SchemaManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / SchemaManager.cs / 3 / SchemaManager.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Metadata.Edm; 
using System.Data.Common.Utils;
using System.Xml; 
using System.Data.Common; 
using System.Data.Entity;
 
namespace System.Data.EntityModel.SchemaObjectModel
{
    internal delegate void AttributeValueNotification(string token, Action addError);
    internal delegate DbProviderManifest ProviderManifestNeeded(Action addError); 

    ///  
    /// Class responsible for parsing,validating a collection of schema 
    /// 
    [System.Diagnostics.DebuggerDisplay("DataModel={DataModel}")] 
    internal class SchemaManager
    {
        #region Instance Fields
        // This keeps track of all the possible namespaces encountered till now. This helps in displaying the error to the 
        // user - if the particular type is not found, we can report whether the namespace was invalid or the type with the
        // given name was not found in the given namespace. This also helps in validating the namespace in the using elements 
        private readonly HashSet _namespaceLookUpTable = new HashSet(StringComparer.Ordinal); 

        // List of all the schema types across all the schemas. This is to ensure that there is no duplicate type encountered 
        // across schemas
        private readonly SchemaElementLookUpTable _schemaTypes = new SchemaElementLookUpTable();

        // We want to stop parsing/resolving/validation after the first 100 errors 
        private const int MaxErrorCount = 100;
 
        // delay loaded 
        private DbProviderManifest _providerManifest;
        private PrimitiveSchema _primitiveSchema; 

        private readonly SchemaDataModelOption _dataModel;
        private readonly ProviderManifestNeeded _providerManifestNeeded;
        private readonly AttributeValueNotification _providerNotification; 
        private readonly AttributeValueNotification _providerManifestTokenNotification;
        #endregion 
 
        #region Constructor
        private SchemaManager(SchemaDataModelOption dataModel, AttributeValueNotification providerNotification, AttributeValueNotification providerManifestTokenNotification, ProviderManifestNeeded providerManifestNeeded) 
        {
            _dataModel = dataModel;
            _providerNotification = providerNotification;
            _providerManifestTokenNotification = providerManifestTokenNotification; 
            _providerManifestNeeded = providerManifestNeeded;
        } 
        #endregion 

        #region Public Methods 



        public static IList LoadProviderManifest(XmlReader xmlReader, string location, 
            bool checkForSystemNamespace, out Schema schema)
        { 
            IList schemaCollection = new List(1); 

            DbProviderManifest providerManifest = checkForSystemNamespace ? EdmProviderManifest.Instance : null; 
            IList errors = ParseAndValidate(new XmlReader[] { xmlReader },
                new string[] { location }, SchemaDataModelOption.ProviderManifestModel,
                providerManifest, out schemaCollection);
 
            // In case of errors, there are no schema in the schema collection
            if (schemaCollection.Count != 0) 
            { 
                schema = schemaCollection[0];
            } 
            else
            {
                Debug.Assert(errors.Count != 0, "There must be some error encountered");
                schema = null; 
            }
 
            return errors; 
        }
 
        public static void NoOpAttributeValueNotification(string attributeValue, Action addError) { }

        public static IList ParseAndValidate(IEnumerable xmlReaders,
            IEnumerable sourceFilePaths, SchemaDataModelOption dataModel, 
            DbProviderManifest providerManifest,
            out IList schemaCollection) 
        { 
            return ParseAndValidate(xmlReaders,
                sourceFilePaths, 
                dataModel,
                NoOpAttributeValueNotification,
                NoOpAttributeValueNotification,
                delegate(Action addError) { return providerManifest == null ? MetadataItem.EdmProviderManifest : providerManifest; }, 
                out schemaCollection);
        } 
 
        public static IList ParseAndValidate(IEnumerable xmlReaders,
            IEnumerable sourceFilePaths, SchemaDataModelOption dataModel, 
            AttributeValueNotification providerNotification,
            AttributeValueNotification providerManifestTokenNotification,
            ProviderManifestNeeded providerManifestNeeded,
            out IList schemaCollection) 
        {
            SchemaManager schemaManager = new SchemaManager(dataModel, providerNotification, providerManifestTokenNotification, providerManifestNeeded); 
            var errorCollection = new List(); 
            schemaCollection = new List();
            bool errorEncountered = false; 

            List filePathList;
            if (sourceFilePaths != null)
            { 
                filePathList = new List(sourceFilePaths);
            } 
            else 
            {
                filePathList = new List(); 
            }

            int index = 0;
            foreach (XmlReader xmlReader in xmlReaders) 
            {
                string location = null; 
                if (filePathList.Count <= index) 
                {
                    TryGetBaseUri(xmlReader, out location); 
                }
                else
                {
                    location = filePathList[index]; 
                }
 
                Schema schema; 
                schema = new Schema(schemaManager);
 
                // If the number of errors exceeded the max error count, then return
                if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.Parse(xmlReader, location), ref errorEncountered))
                {
                    return errorCollection; 
                }
 
                // Add the schema to the collection if there are no errors. There are errors in which schema do not have any namespace. 
                // Also if there is an error encountered in one of the schema, we do not need to add the remaining schemas since
                // we will never go to the resolve phase. 
                if (!errorEncountered)
                {
                    schemaCollection.Add(schema);
                    schemaManager.AddSchema(schema); 
                }
                index++; 
            } 

            // If there are no errors encountered in the parsing stage, we can proceed to the 
            // parsing and validating phase
            if (!errorEncountered)
            {
                foreach (Schema schema in schemaCollection) 
                {
                    if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.Resolve(), ref errorEncountered)) 
                    { 
                        return errorCollection;
                    } 
                }

                // If there are no errors encountered in the parsing stage, we can proceed to the
                // parsing and validating phase 
                if (!errorEncountered)
                { 
                    foreach (Schema schema in schemaCollection) 
                    {
                        if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.ValidateSchema(), ref errorEncountered)) 
                        {
                            return errorCollection;
                        }
                    } 
                }
            } 
 
            return errorCollection;
        } 

        /// 
        /// Add the namespace of the given schema to the namespace lookup table
        ///  
        public void AddSchema(Schema schema)
        { 
            Debug.Assert(schema.DataModel == _dataModel, "DataModel must match"); 

            if (_namespaceLookUpTable.Count == 0 && schema.DataModel != SchemaDataModelOption.ProviderManifestModel) 
            {
                // Add the primitive type namespace to the namespace look up table
                if (this.PrimitiveSchema.Namespace != null)
                { 
                    _namespaceLookUpTable.Add(this.PrimitiveSchema.Namespace);
                } 
            } 

            // Add the namespace to the namespaceLookUpTable. 
            // Its okay to have multiple schemas with the same namespace
            _namespaceLookUpTable.Add(schema.Namespace);
        }
 
        /// 
        /// Resolve the type - if the type is not found, return appropriate error 
        ///  
        /// 
        public bool TryResolveType(string namespaceName, string typeName, out SchemaType schemaType) 
        {
            // For resolving entity container names, namespace can be null
            string fullyQualifiedName = String.IsNullOrEmpty(namespaceName) ? typeName : namespaceName + "." + typeName;
 
            schemaType = SchemaTypes.LookUpEquivalentKey(fullyQualifiedName);
            if (schemaType != null) 
            { 
                return true;
            } 

            return false;
        }
 
        /// 
        /// Returns true if this is a valid namespace name or else returns false 
        ///  
        public bool IsValidNamespaceName(string namespaceName)
        { 
            return _namespaceLookUpTable.Contains(namespaceName);
        }
        #endregion // Public Methods
 
        #region Private Methods
 
        ///  
        /// Checks if the xml reader has base uri. If it doesn't have, it adds error, other
        /// returns the location from the base uri 
        /// 
        /// 
        internal static bool TryGetBaseUri(XmlReader xmlReader, out string location)
        { 
            string baseUri = xmlReader.BaseURI;
            Uri uri = null; 
 
            if (!string.IsNullOrEmpty(baseUri) &&
                 Uri.TryCreate(baseUri, UriKind.Absolute, out uri) && 
                 uri.Scheme == "file")
            {
                location = Helper.GetFileNameFromUri(uri);
                return true; 
            }
            else 
            { 
                location = null;
                return false; 
            }
        }

        ///  
        /// Add the given list of newErrors to the error collection. If there is a error in the new errors,
        /// it sets the errorEncountered to true. Returns true if the number of errors encountered is more 
        /// than max errors 
        /// 
        ///  
        private static bool UpdateErrorCollectionAndCheckForMaxErrors(List errorCollection,
            IList newErrors, ref bool errorEncountered)
        {
            // If we have encountered error already in one of the schemas, then we don't need to check for errors in the remaining schemas. 
            // Just keep aggregating the errors and throw them at the end.
            if (!errorEncountered) 
            { 
                if (!MetadataHelper.CheckIfAllErrorsAreWarnings(newErrors))
                { 
                    errorEncountered = true;
                }
            }
 
            // assert that the number of errors is less than the max errors
            Debug.Assert(errorCollection.Count < MaxErrorCount, "Errors should be less than max errors"); 
 
            // Add the new errors to the error collection
            errorCollection.AddRange(newErrors); 

            if (errorCollection.Count >= MaxErrorCount)
            {
                return true; 
            }
            return false; 
        } 
        #endregion
 
        #region Internal Properties

        internal SchemaElementLookUpTable SchemaTypes
        { 
            get
            { 
                return _schemaTypes; 
            }
        } 

        internal DbProviderManifest GetProviderManifest(Action addError)
        {
            if (_providerManifest == null) 
            {
                _providerManifest = _providerManifestNeeded(addError); 
            } 
            return _providerManifest;
        } 

        internal SchemaDataModelOption DataModel { get { return _dataModel; } }

        internal void EnsurePrimitiveSchemaIsLoaded() 
        {
            if (_primitiveSchema == null) 
            { 
                _primitiveSchema = new PrimitiveSchema(this);
            } 
        }

        internal PrimitiveSchema PrimitiveSchema
        { 
            get
            { 
                return _primitiveSchema; 
            }
        } 

        internal AttributeValueNotification ProviderNotification
        {
            get 
            {
                return _providerNotification; 
            } 
        }
 
        internal AttributeValueNotification ProviderManifestTokenNotification
        {
            get
            { 
                return _providerManifestTokenNotification;
            } 
        } 

        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Metadata.Edm; 
using System.Data.Common.Utils;
using System.Xml; 
using System.Data.Common; 
using System.Data.Entity;
 
namespace System.Data.EntityModel.SchemaObjectModel
{
    internal delegate void AttributeValueNotification(string token, Action addError);
    internal delegate DbProviderManifest ProviderManifestNeeded(Action addError); 

    ///  
    /// Class responsible for parsing,validating a collection of schema 
    /// 
    [System.Diagnostics.DebuggerDisplay("DataModel={DataModel}")] 
    internal class SchemaManager
    {
        #region Instance Fields
        // This keeps track of all the possible namespaces encountered till now. This helps in displaying the error to the 
        // user - if the particular type is not found, we can report whether the namespace was invalid or the type with the
        // given name was not found in the given namespace. This also helps in validating the namespace in the using elements 
        private readonly HashSet _namespaceLookUpTable = new HashSet(StringComparer.Ordinal); 

        // List of all the schema types across all the schemas. This is to ensure that there is no duplicate type encountered 
        // across schemas
        private readonly SchemaElementLookUpTable _schemaTypes = new SchemaElementLookUpTable();

        // We want to stop parsing/resolving/validation after the first 100 errors 
        private const int MaxErrorCount = 100;
 
        // delay loaded 
        private DbProviderManifest _providerManifest;
        private PrimitiveSchema _primitiveSchema; 

        private readonly SchemaDataModelOption _dataModel;
        private readonly ProviderManifestNeeded _providerManifestNeeded;
        private readonly AttributeValueNotification _providerNotification; 
        private readonly AttributeValueNotification _providerManifestTokenNotification;
        #endregion 
 
        #region Constructor
        private SchemaManager(SchemaDataModelOption dataModel, AttributeValueNotification providerNotification, AttributeValueNotification providerManifestTokenNotification, ProviderManifestNeeded providerManifestNeeded) 
        {
            _dataModel = dataModel;
            _providerNotification = providerNotification;
            _providerManifestTokenNotification = providerManifestTokenNotification; 
            _providerManifestNeeded = providerManifestNeeded;
        } 
        #endregion 

        #region Public Methods 



        public static IList LoadProviderManifest(XmlReader xmlReader, string location, 
            bool checkForSystemNamespace, out Schema schema)
        { 
            IList schemaCollection = new List(1); 

            DbProviderManifest providerManifest = checkForSystemNamespace ? EdmProviderManifest.Instance : null; 
            IList errors = ParseAndValidate(new XmlReader[] { xmlReader },
                new string[] { location }, SchemaDataModelOption.ProviderManifestModel,
                providerManifest, out schemaCollection);
 
            // In case of errors, there are no schema in the schema collection
            if (schemaCollection.Count != 0) 
            { 
                schema = schemaCollection[0];
            } 
            else
            {
                Debug.Assert(errors.Count != 0, "There must be some error encountered");
                schema = null; 
            }
 
            return errors; 
        }
 
        public static void NoOpAttributeValueNotification(string attributeValue, Action addError) { }

        public static IList ParseAndValidate(IEnumerable xmlReaders,
            IEnumerable sourceFilePaths, SchemaDataModelOption dataModel, 
            DbProviderManifest providerManifest,
            out IList schemaCollection) 
        { 
            return ParseAndValidate(xmlReaders,
                sourceFilePaths, 
                dataModel,
                NoOpAttributeValueNotification,
                NoOpAttributeValueNotification,
                delegate(Action addError) { return providerManifest == null ? MetadataItem.EdmProviderManifest : providerManifest; }, 
                out schemaCollection);
        } 
 
        public static IList ParseAndValidate(IEnumerable xmlReaders,
            IEnumerable sourceFilePaths, SchemaDataModelOption dataModel, 
            AttributeValueNotification providerNotification,
            AttributeValueNotification providerManifestTokenNotification,
            ProviderManifestNeeded providerManifestNeeded,
            out IList schemaCollection) 
        {
            SchemaManager schemaManager = new SchemaManager(dataModel, providerNotification, providerManifestTokenNotification, providerManifestNeeded); 
            var errorCollection = new List(); 
            schemaCollection = new List();
            bool errorEncountered = false; 

            List filePathList;
            if (sourceFilePaths != null)
            { 
                filePathList = new List(sourceFilePaths);
            } 
            else 
            {
                filePathList = new List(); 
            }

            int index = 0;
            foreach (XmlReader xmlReader in xmlReaders) 
            {
                string location = null; 
                if (filePathList.Count <= index) 
                {
                    TryGetBaseUri(xmlReader, out location); 
                }
                else
                {
                    location = filePathList[index]; 
                }
 
                Schema schema; 
                schema = new Schema(schemaManager);
 
                // If the number of errors exceeded the max error count, then return
                if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.Parse(xmlReader, location), ref errorEncountered))
                {
                    return errorCollection; 
                }
 
                // Add the schema to the collection if there are no errors. There are errors in which schema do not have any namespace. 
                // Also if there is an error encountered in one of the schema, we do not need to add the remaining schemas since
                // we will never go to the resolve phase. 
                if (!errorEncountered)
                {
                    schemaCollection.Add(schema);
                    schemaManager.AddSchema(schema); 
                }
                index++; 
            } 

            // If there are no errors encountered in the parsing stage, we can proceed to the 
            // parsing and validating phase
            if (!errorEncountered)
            {
                foreach (Schema schema in schemaCollection) 
                {
                    if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.Resolve(), ref errorEncountered)) 
                    { 
                        return errorCollection;
                    } 
                }

                // If there are no errors encountered in the parsing stage, we can proceed to the
                // parsing and validating phase 
                if (!errorEncountered)
                { 
                    foreach (Schema schema in schemaCollection) 
                    {
                        if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.ValidateSchema(), ref errorEncountered)) 
                        {
                            return errorCollection;
                        }
                    } 
                }
            } 
 
            return errorCollection;
        } 

        /// 
        /// Add the namespace of the given schema to the namespace lookup table
        ///  
        public void AddSchema(Schema schema)
        { 
            Debug.Assert(schema.DataModel == _dataModel, "DataModel must match"); 

            if (_namespaceLookUpTable.Count == 0 && schema.DataModel != SchemaDataModelOption.ProviderManifestModel) 
            {
                // Add the primitive type namespace to the namespace look up table
                if (this.PrimitiveSchema.Namespace != null)
                { 
                    _namespaceLookUpTable.Add(this.PrimitiveSchema.Namespace);
                } 
            } 

            // Add the namespace to the namespaceLookUpTable. 
            // Its okay to have multiple schemas with the same namespace
            _namespaceLookUpTable.Add(schema.Namespace);
        }
 
        /// 
        /// Resolve the type - if the type is not found, return appropriate error 
        ///  
        /// 
        public bool TryResolveType(string namespaceName, string typeName, out SchemaType schemaType) 
        {
            // For resolving entity container names, namespace can be null
            string fullyQualifiedName = String.IsNullOrEmpty(namespaceName) ? typeName : namespaceName + "." + typeName;
 
            schemaType = SchemaTypes.LookUpEquivalentKey(fullyQualifiedName);
            if (schemaType != null) 
            { 
                return true;
            } 

            return false;
        }
 
        /// 
        /// Returns true if this is a valid namespace name or else returns false 
        ///  
        public bool IsValidNamespaceName(string namespaceName)
        { 
            return _namespaceLookUpTable.Contains(namespaceName);
        }
        #endregion // Public Methods
 
        #region Private Methods
 
        ///  
        /// Checks if the xml reader has base uri. If it doesn't have, it adds error, other
        /// returns the location from the base uri 
        /// 
        /// 
        internal static bool TryGetBaseUri(XmlReader xmlReader, out string location)
        { 
            string baseUri = xmlReader.BaseURI;
            Uri uri = null; 
 
            if (!string.IsNullOrEmpty(baseUri) &&
                 Uri.TryCreate(baseUri, UriKind.Absolute, out uri) && 
                 uri.Scheme == "file")
            {
                location = Helper.GetFileNameFromUri(uri);
                return true; 
            }
            else 
            { 
                location = null;
                return false; 
            }
        }

        ///  
        /// Add the given list of newErrors to the error collection. If there is a error in the new errors,
        /// it sets the errorEncountered to true. Returns true if the number of errors encountered is more 
        /// than max errors 
        /// 
        ///  
        private static bool UpdateErrorCollectionAndCheckForMaxErrors(List errorCollection,
            IList newErrors, ref bool errorEncountered)
        {
            // If we have encountered error already in one of the schemas, then we don't need to check for errors in the remaining schemas. 
            // Just keep aggregating the errors and throw them at the end.
            if (!errorEncountered) 
            { 
                if (!MetadataHelper.CheckIfAllErrorsAreWarnings(newErrors))
                { 
                    errorEncountered = true;
                }
            }
 
            // assert that the number of errors is less than the max errors
            Debug.Assert(errorCollection.Count < MaxErrorCount, "Errors should be less than max errors"); 
 
            // Add the new errors to the error collection
            errorCollection.AddRange(newErrors); 

            if (errorCollection.Count >= MaxErrorCount)
            {
                return true; 
            }
            return false; 
        } 
        #endregion
 
        #region Internal Properties

        internal SchemaElementLookUpTable SchemaTypes
        { 
            get
            { 
                return _schemaTypes; 
            }
        } 

        internal DbProviderManifest GetProviderManifest(Action addError)
        {
            if (_providerManifest == null) 
            {
                _providerManifest = _providerManifestNeeded(addError); 
            } 
            return _providerManifest;
        } 

        internal SchemaDataModelOption DataModel { get { return _dataModel; } }

        internal void EnsurePrimitiveSchemaIsLoaded() 
        {
            if (_primitiveSchema == null) 
            { 
                _primitiveSchema = new PrimitiveSchema(this);
            } 
        }

        internal PrimitiveSchema PrimitiveSchema
        { 
            get
            { 
                return _primitiveSchema; 
            }
        } 

        internal AttributeValueNotification ProviderNotification
        {
            get 
            {
                return _providerNotification; 
            } 
        }
 
        internal AttributeValueNotification ProviderManifestTokenNotification
        {
            get
            { 
                return _providerManifestTokenNotification;
            } 
        } 

        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK