Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TreeNode.cs
- AppearanceEditorPart.cs
- StylusPointPropertyInfo.cs
- SizeF.cs
- BindingValueChangedEventArgs.cs
- ListViewGroup.cs
- JulianCalendar.cs
- PageRanges.cs
- SQLUtility.cs
- LineSegment.cs
- TypeLoadException.cs
- CodePrimitiveExpression.cs
- TableAdapterManagerGenerator.cs
- DbConnectionStringCommon.cs
- XmlLangPropertyAttribute.cs
- PriorityQueue.cs
- AstTree.cs
- BamlTreeMap.cs
- TaiwanCalendar.cs
- AliasedSlot.cs
- EventDescriptor.cs
- SerializableAttribute.cs
- RangeBase.cs
- SqlWebEventProvider.cs
- ValidatorUtils.cs
- ThemeInfoAttribute.cs
- ReadOnlyCollectionBase.cs
- SerializationAttributes.cs
- SimpleType.cs
- ProgressiveCrcCalculatingStream.cs
- HttpWriter.cs
- MobileCategoryAttribute.cs
- TargetInvocationException.cs
- RealProxy.cs
- Visual.cs
- _AcceptOverlappedAsyncResult.cs
- TypeConverterHelper.cs
- DataGridViewBand.cs
- TextDecorationCollection.cs
- XPathDescendantIterator.cs
- ElapsedEventArgs.cs
- XmlSchemaComplexContent.cs
- InstanceCreationEditor.cs
- PropertyEmitterBase.cs
- PointUtil.cs
- VarInfo.cs
- WizardStepBase.cs
- TypeUsageBuilder.cs
- HttpUnhandledOperationInvoker.cs
- EntityReference.cs
- DataTableMappingCollection.cs
- DataRowCollection.cs
- HitTestDrawingContextWalker.cs
- InfoCardCryptoHelper.cs
- WebPartsPersonalizationAuthorization.cs
- precedingquery.cs
- InstanceCreationEditor.cs
- CodeParameterDeclarationExpressionCollection.cs
- HtmlInputSubmit.cs
- ApplicationFileCodeDomTreeGenerator.cs
- Shape.cs
- Literal.cs
- AppDomainShutdownMonitor.cs
- Control.cs
- ResourcesChangeInfo.cs
- OdbcErrorCollection.cs
- SetterBase.cs
- KoreanCalendar.cs
- _Win32.cs
- XmlSchema.cs
- TagPrefixCollection.cs
- Schema.cs
- GroupAggregateExpr.cs
- ConfigurationFileMap.cs
- ListViewItem.cs
- FixedPage.cs
- SafeHandle.cs
- ObjectSet.cs
- BoolLiteral.cs
- InstanceData.cs
- TextTreePropertyUndoUnit.cs
- AnchoredBlock.cs
- ActivationServices.cs
- backend.cs
- SoapMessage.cs
- TextRenderer.cs
- shaperfactory.cs
- WorkerRequest.cs
- FillBehavior.cs
- EmbeddedMailObjectsCollection.cs
- AssemblyHash.cs
- SemaphoreSecurity.cs
- XmlSchemaDatatype.cs
- EdgeProfileValidation.cs
- DateBoldEvent.cs
- FlowLayoutPanel.cs
- RunInstallerAttribute.cs
- XPathBinder.cs
- ExtensionElement.cs
- DirectoryObjectSecurity.cs