StructuredType.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / StructuredType.cs / 1305376 / StructuredType.cs

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

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Xml; 
using System.Data;
using System.Data.Metadata.Edm; 
using System.Diagnostics; 
using System.Data.Entity;
using System.Globalization; 



 
namespace System.Data.EntityModel.SchemaObjectModel
{ 
    ///  
    /// Summary description for StructuredType.
    ///  
    internal abstract class StructuredType : SchemaType
    {
        #region Instance Fields
        private bool? _baseTypeResolveResult; 
        private string _unresolvedBaseType = null;
        private StructuredType _baseType = null; 
        private bool _isAbstract = false; 
        private SchemaElementLookUpTable _namedMembers = null;
        private ISchemaElementLookUpTable _properties = null; 
        #endregion

        #region Static Fields
        private static readonly char[] NameSeparators = new char[] { '.' }; 
        #endregion
 
        #region Public Properties 
        /// 
        /// 
        /// 
        public StructuredType BaseType
        {
            get 
            {
                return _baseType; 
            } 
            private set
            { 
                _baseType = value;
            }
        }
 
        /// 
        /// 
        /// 
        /// 
        public ISchemaElementLookUpTable Properties 
        {
            get
            {
                if (_properties == null) 
                {
                    _properties = new FilteredSchemaElementLookUpTable(NamedMembers); 
                } 
                return _properties;
            } 
        }

        /// 
        /// 
        ///
        ///  
        protected SchemaElementLookUpTable NamedMembers 
        {
            get 
            {
                if (_namedMembers == null)
                {
                    _namedMembers = new SchemaElementLookUpTable(); 
                }
                return _namedMembers; 
            } 
        }
 
        /// 
        ///
        /// 
        public virtual bool IsTypeHierarchyRoot 
        {
            get 
            { 
                Debug.Assert((BaseType == null && _unresolvedBaseType == null) ||
                             (BaseType != null && _unresolvedBaseType != null), "you are checking for the hierarchy root before the basetype has been set"); 

                // any type without a base is a base type
                return BaseType == null;
            } 
        }
 
 
        /// 
        /// 
        /// 
        public bool IsAbstract
        {
            get 
            {
                return _isAbstract; 
            } 
        }
 

        #endregion

        #region More Public Methods 
        /// 
        /// Find a property by name in the type hierarchy 
        ///  
        /// simple property name
        /// the StructuredProperty object if name exists, null otherwise 
        public StructuredProperty FindProperty(string name)
        {
            StructuredProperty property = Properties.LookUpEquivalentKey(name);
            if (property != null) 
                return property;
 
            if (IsTypeHierarchyRoot) 
                return null;
 
            return BaseType.FindProperty(name);
        }

 
        /// 
        /// Determines whether this type is of the same type as baseType, 
        /// or is derived from baseType. 
        /// 
        ///  
        /// true if this type is of the baseType, false otherwise
        public bool IsOfType(StructuredType baseType)
        {
            StructuredType type = this; 

            while (type != null && type != baseType) 
            { 
                type = type.BaseType;
            } 

            return (type == baseType);
        }
        #endregion 

        #region Protected Methods 
        ///  
        ///
        ///  
        internal override void ResolveTopLevelNames()
        {
            base.ResolveTopLevelNames();
 
            TryResolveBaseType();
 
            foreach (SchemaElement member in NamedMembers) 
                member.ResolveTopLevelNames();
 
        }

        /// 
        /// 
        /// 
        ///  
        internal override void Validate() 
        {
            base.Validate(); 

            foreach (SchemaElement member in NamedMembers)
            {
                if (BaseType != null) 
                {
                    StructuredType definingType; 
                    SchemaElement definingMember; 
                    string errorMessage = null;
                    if(HowDefined.AsMember == BaseType.DefinesMemberName(member.Name, out definingType, out definingMember)) 
                    {
                        errorMessage = System.Data.Entity.Strings.DuplicateMemberName(member.Name, FQName, definingType.FQName);
                    }
                    if (errorMessage != null) 
                        member.AddError(ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error, errorMessage);
                } 
 
                member.Validate();
            } 
        }

        /// 
        /// 
        /// 
        ///  
        protected StructuredType(Schema parentElement) 
            : base(parentElement)
        { 
        }

        /// 
        /// Add a member to the type 
        /// 
        /// the member being added 
        protected void AddMember(SchemaElement newMember) 
        {
            Debug.Assert(newMember != null, "newMember parameter is null"); 

            if (string.IsNullOrEmpty(newMember.Name))
            {
                // this is an error condition that has already been reported. 
                return;
            } 
 
            if (this.Schema.DataModel != SchemaDataModelOption.ProviderDataModel &&
                 Utils.CompareNames(newMember.Name, Name) == 0) 
            {
                newMember.AddError(ErrorCode.BadProperty, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.InvalidMemberNameMatchesTypeName(newMember.Name, FQName));
            } 

            NamedMembers.Add(newMember, true, Strings.PropertyNameAlreadyDefinedDuplicate); 
        } 

 
        /// 
        /// See if a name is a member in a type or any of its base types
        /// 
        /// name to look for 
        /// if defined, the type that defines it
        /// if defined, the member that defines it 
        /// how name was defined 
        private HowDefined DefinesMemberName(string name, out StructuredType definingType, out SchemaElement definingMember)
        { 
            if (NamedMembers.ContainsKey(name))
            {
                definingType = this;
                definingMember = NamedMembers[name]; 
                return HowDefined.AsMember;
            } 
 
            definingMember = NamedMembers.LookUpEquivalentKey(name);
            Debug.Assert(definingMember == null, "we allow the scenario that members can have same name but different cases"); 

            if (IsTypeHierarchyRoot)
            {
                definingType = null; 
                definingMember = null;
                return HowDefined.NotDefined; 
            } 

            return BaseType.DefinesMemberName(name, out definingType, out definingMember); 
        }
        #endregion

        #region Protected Properties 
        /// 
        /// 
        ///  
        protected string UnresolvedBaseType
        { 
            get
            {
                return _unresolvedBaseType;
            } 
            set
            { 
                _unresolvedBaseType = value; 
            }
        } 

        protected override bool HandleElement(XmlReader reader)
        {
            if (base.HandleElement(reader)) 
            {
                return true; 
            } 
            else if (CanHandleElement(reader, XmlConstants.Property))
            { 
                HandlePropertyElement(reader);
                return true;
            }
            return false; 
        }
 
        protected override bool HandleAttribute(XmlReader reader) 
        {
            if (base.HandleAttribute(reader)) 
            {
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.BaseType)) 
            {
                HandleBaseTypeAttribute(reader); 
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.Abstract)) 
            {
                HandleAbstractAttribute(reader);
                return true;
            } 

            return false; 
        } 
        #endregion
 
        #region Private Methods
        /// 
        ///
        ///  
        private bool TryResolveBaseType()
        { 
            if (_baseTypeResolveResult.HasValue) 
            {
                return _baseTypeResolveResult.Value; 
            }

            if (BaseType != null)
            { 
                _baseTypeResolveResult = true;
                return _baseTypeResolveResult.Value; 
            } 

            if (UnresolvedBaseType == null) 
            {
                _baseTypeResolveResult = true;
                return _baseTypeResolveResult.Value;
            } 

            SchemaType element; 
            if (!Schema.ResolveTypeName(this, UnresolvedBaseType, out element)) 
            {
                _baseTypeResolveResult = false; 
                return _baseTypeResolveResult.Value;
            }

            BaseType = element as StructuredType; 
            if (BaseType == null)
            { 
                AddError(ErrorCode.InvalidBaseType, EdmSchemaErrorSeverity.Error, 
                    System.Data.Entity.Strings.InvalidBaseTypeForStructuredType(UnresolvedBaseType, FQName));
                _baseTypeResolveResult = false; 
                return _baseTypeResolveResult.Value;
            }

            // verify that creating this link to the base type will not introduce a cycle; 
            // if so, break the link and add an error
            if (CheckForInheritanceCycle()) 
            { 
                BaseType = null;
 
                AddError(ErrorCode.CycleInTypeHierarchy, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.CycleInTypeHierarchy(FQName));
                _baseTypeResolveResult = false;
                return _baseTypeResolveResult.Value; 
            }
 
            _baseTypeResolveResult = true; 
            return true;
        } 

        /// 
        ///
        ///  
        /// 
        private void HandleBaseTypeAttribute(XmlReader reader) 
        { 
            Debug.Assert(UnresolvedBaseType == null, string.Format(CultureInfo.CurrentCulture, "{0} is already defined", reader.Name));
 
            string baseType;
            if (!Utils.GetDottedName(this.Schema, reader, out baseType))
                return;
 
            UnresolvedBaseType = baseType;
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void HandleAbstractAttribute(XmlReader reader)
        { 
            HandleBoolAttribute(reader, ref _isAbstract);
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void HandlePropertyElement(XmlReader reader)
        { 
            StructuredProperty property = new StructuredProperty(this);
 
            property.Parse(reader); 

            AddMember(property); 
        }

        /// 
        /// Determine if a cycle exists in the type hierarchy: use two pointers to 
        /// walk the chain, if one catches up with the other, we have a cycle.
        ///  
        /// true if a cycle exists in the type hierarchy, false otherwise 
        private bool CheckForInheritanceCycle()
        { 
            StructuredType baseType = BaseType;
            Debug.Assert(baseType != null);

            StructuredType ref1 = baseType; 
            StructuredType ref2 = baseType;
 
            do 
            {
                ref2 = ref2.BaseType; 

                if (Object.ReferenceEquals(ref1, ref2))
                    return true;
 
                if (ref1 == null)
                    return false; 
 
                ref1 = ref1.BaseType;
 
                if (ref2 != null)
                    ref2 = ref2.BaseType;
            }
            while (ref2 != null); 

            return false; 
        } 

        #endregion 

        #region Private Properties
        #endregion
 
        private enum HowDefined
        { 
            NotDefined, 
            AsMember,
        } 
    }
}

// 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.Collections.Specialized;
using System.Xml; 
using System.Data;
using System.Data.Metadata.Edm; 
using System.Diagnostics; 
using System.Data.Entity;
using System.Globalization; 



 
namespace System.Data.EntityModel.SchemaObjectModel
{ 
    ///  
    /// Summary description for StructuredType.
    ///  
    internal abstract class StructuredType : SchemaType
    {
        #region Instance Fields
        private bool? _baseTypeResolveResult; 
        private string _unresolvedBaseType = null;
        private StructuredType _baseType = null; 
        private bool _isAbstract = false; 
        private SchemaElementLookUpTable _namedMembers = null;
        private ISchemaElementLookUpTable _properties = null; 
        #endregion

        #region Static Fields
        private static readonly char[] NameSeparators = new char[] { '.' }; 
        #endregion
 
        #region Public Properties 
        /// 
        /// 
        /// 
        public StructuredType BaseType
        {
            get 
            {
                return _baseType; 
            } 
            private set
            { 
                _baseType = value;
            }
        }
 
        /// 
        /// 
        /// 
        /// 
        public ISchemaElementLookUpTable Properties 
        {
            get
            {
                if (_properties == null) 
                {
                    _properties = new FilteredSchemaElementLookUpTable(NamedMembers); 
                } 
                return _properties;
            } 
        }

        /// 
        /// 
        ///
        ///  
        protected SchemaElementLookUpTable NamedMembers 
        {
            get 
            {
                if (_namedMembers == null)
                {
                    _namedMembers = new SchemaElementLookUpTable(); 
                }
                return _namedMembers; 
            } 
        }
 
        /// 
        ///
        /// 
        public virtual bool IsTypeHierarchyRoot 
        {
            get 
            { 
                Debug.Assert((BaseType == null && _unresolvedBaseType == null) ||
                             (BaseType != null && _unresolvedBaseType != null), "you are checking for the hierarchy root before the basetype has been set"); 

                // any type without a base is a base type
                return BaseType == null;
            } 
        }
 
 
        /// 
        /// 
        /// 
        public bool IsAbstract
        {
            get 
            {
                return _isAbstract; 
            } 
        }
 

        #endregion

        #region More Public Methods 
        /// 
        /// Find a property by name in the type hierarchy 
        ///  
        /// simple property name
        /// the StructuredProperty object if name exists, null otherwise 
        public StructuredProperty FindProperty(string name)
        {
            StructuredProperty property = Properties.LookUpEquivalentKey(name);
            if (property != null) 
                return property;
 
            if (IsTypeHierarchyRoot) 
                return null;
 
            return BaseType.FindProperty(name);
        }

 
        /// 
        /// Determines whether this type is of the same type as baseType, 
        /// or is derived from baseType. 
        /// 
        ///  
        /// true if this type is of the baseType, false otherwise
        public bool IsOfType(StructuredType baseType)
        {
            StructuredType type = this; 

            while (type != null && type != baseType) 
            { 
                type = type.BaseType;
            } 

            return (type == baseType);
        }
        #endregion 

        #region Protected Methods 
        ///  
        ///
        ///  
        internal override void ResolveTopLevelNames()
        {
            base.ResolveTopLevelNames();
 
            TryResolveBaseType();
 
            foreach (SchemaElement member in NamedMembers) 
                member.ResolveTopLevelNames();
 
        }

        /// 
        /// 
        /// 
        ///  
        internal override void Validate() 
        {
            base.Validate(); 

            foreach (SchemaElement member in NamedMembers)
            {
                if (BaseType != null) 
                {
                    StructuredType definingType; 
                    SchemaElement definingMember; 
                    string errorMessage = null;
                    if(HowDefined.AsMember == BaseType.DefinesMemberName(member.Name, out definingType, out definingMember)) 
                    {
                        errorMessage = System.Data.Entity.Strings.DuplicateMemberName(member.Name, FQName, definingType.FQName);
                    }
                    if (errorMessage != null) 
                        member.AddError(ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error, errorMessage);
                } 
 
                member.Validate();
            } 
        }

        /// 
        /// 
        /// 
        ///  
        protected StructuredType(Schema parentElement) 
            : base(parentElement)
        { 
        }

        /// 
        /// Add a member to the type 
        /// 
        /// the member being added 
        protected void AddMember(SchemaElement newMember) 
        {
            Debug.Assert(newMember != null, "newMember parameter is null"); 

            if (string.IsNullOrEmpty(newMember.Name))
            {
                // this is an error condition that has already been reported. 
                return;
            } 
 
            if (this.Schema.DataModel != SchemaDataModelOption.ProviderDataModel &&
                 Utils.CompareNames(newMember.Name, Name) == 0) 
            {
                newMember.AddError(ErrorCode.BadProperty, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.InvalidMemberNameMatchesTypeName(newMember.Name, FQName));
            } 

            NamedMembers.Add(newMember, true, Strings.PropertyNameAlreadyDefinedDuplicate); 
        } 

 
        /// 
        /// See if a name is a member in a type or any of its base types
        /// 
        /// name to look for 
        /// if defined, the type that defines it
        /// if defined, the member that defines it 
        /// how name was defined 
        private HowDefined DefinesMemberName(string name, out StructuredType definingType, out SchemaElement definingMember)
        { 
            if (NamedMembers.ContainsKey(name))
            {
                definingType = this;
                definingMember = NamedMembers[name]; 
                return HowDefined.AsMember;
            } 
 
            definingMember = NamedMembers.LookUpEquivalentKey(name);
            Debug.Assert(definingMember == null, "we allow the scenario that members can have same name but different cases"); 

            if (IsTypeHierarchyRoot)
            {
                definingType = null; 
                definingMember = null;
                return HowDefined.NotDefined; 
            } 

            return BaseType.DefinesMemberName(name, out definingType, out definingMember); 
        }
        #endregion

        #region Protected Properties 
        /// 
        /// 
        ///  
        protected string UnresolvedBaseType
        { 
            get
            {
                return _unresolvedBaseType;
            } 
            set
            { 
                _unresolvedBaseType = value; 
            }
        } 

        protected override bool HandleElement(XmlReader reader)
        {
            if (base.HandleElement(reader)) 
            {
                return true; 
            } 
            else if (CanHandleElement(reader, XmlConstants.Property))
            { 
                HandlePropertyElement(reader);
                return true;
            }
            return false; 
        }
 
        protected override bool HandleAttribute(XmlReader reader) 
        {
            if (base.HandleAttribute(reader)) 
            {
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.BaseType)) 
            {
                HandleBaseTypeAttribute(reader); 
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.Abstract)) 
            {
                HandleAbstractAttribute(reader);
                return true;
            } 

            return false; 
        } 
        #endregion
 
        #region Private Methods
        /// 
        ///
        ///  
        private bool TryResolveBaseType()
        { 
            if (_baseTypeResolveResult.HasValue) 
            {
                return _baseTypeResolveResult.Value; 
            }

            if (BaseType != null)
            { 
                _baseTypeResolveResult = true;
                return _baseTypeResolveResult.Value; 
            } 

            if (UnresolvedBaseType == null) 
            {
                _baseTypeResolveResult = true;
                return _baseTypeResolveResult.Value;
            } 

            SchemaType element; 
            if (!Schema.ResolveTypeName(this, UnresolvedBaseType, out element)) 
            {
                _baseTypeResolveResult = false; 
                return _baseTypeResolveResult.Value;
            }

            BaseType = element as StructuredType; 
            if (BaseType == null)
            { 
                AddError(ErrorCode.InvalidBaseType, EdmSchemaErrorSeverity.Error, 
                    System.Data.Entity.Strings.InvalidBaseTypeForStructuredType(UnresolvedBaseType, FQName));
                _baseTypeResolveResult = false; 
                return _baseTypeResolveResult.Value;
            }

            // verify that creating this link to the base type will not introduce a cycle; 
            // if so, break the link and add an error
            if (CheckForInheritanceCycle()) 
            { 
                BaseType = null;
 
                AddError(ErrorCode.CycleInTypeHierarchy, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.CycleInTypeHierarchy(FQName));
                _baseTypeResolveResult = false;
                return _baseTypeResolveResult.Value; 
            }
 
            _baseTypeResolveResult = true; 
            return true;
        } 

        /// 
        ///
        ///  
        /// 
        private void HandleBaseTypeAttribute(XmlReader reader) 
        { 
            Debug.Assert(UnresolvedBaseType == null, string.Format(CultureInfo.CurrentCulture, "{0} is already defined", reader.Name));
 
            string baseType;
            if (!Utils.GetDottedName(this.Schema, reader, out baseType))
                return;
 
            UnresolvedBaseType = baseType;
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void HandleAbstractAttribute(XmlReader reader)
        { 
            HandleBoolAttribute(reader, ref _isAbstract);
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void HandlePropertyElement(XmlReader reader)
        { 
            StructuredProperty property = new StructuredProperty(this);
 
            property.Parse(reader); 

            AddMember(property); 
        }

        /// 
        /// Determine if a cycle exists in the type hierarchy: use two pointers to 
        /// walk the chain, if one catches up with the other, we have a cycle.
        ///  
        /// true if a cycle exists in the type hierarchy, false otherwise 
        private bool CheckForInheritanceCycle()
        { 
            StructuredType baseType = BaseType;
            Debug.Assert(baseType != null);

            StructuredType ref1 = baseType; 
            StructuredType ref2 = baseType;
 
            do 
            {
                ref2 = ref2.BaseType; 

                if (Object.ReferenceEquals(ref1, ref2))
                    return true;
 
                if (ref1 == null)
                    return false; 
 
                ref1 = ref1.BaseType;
 
                if (ref2 != null)
                    ref2 = ref2.BaseType;
            }
            while (ref2 != null); 

            return false; 
        } 

        #endregion 

        #region Private Properties
        #endregion
 
        private enum HowDefined
        { 
            NotDefined, 
            AsMember,
        } 
    }
}

// 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