| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Security;
- using System.Runtime.Diagnostics;
- using System.Xml;
- using System.Xml.Schema;
- using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
- using SchemaObjectDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, SchemaObjectInfo>;
- using System.Runtime.Serialization.Diagnostics;
- class SchemaImporter
- {
- DataContractSet dataContractSet;
- XmlSchemaSet schemaSet;
- ICollection<XmlQualifiedName> typeNames;
- ICollection<XmlSchemaElement> elements;
- XmlQualifiedName[] elementTypeNames;
- bool importXmlDataType;
- SchemaObjectDictionary schemaObjects;
- List<XmlSchemaRedefine> redefineList;
- bool needToImportKnownTypesForObject;
- [Fx.Tag.SecurityNote(Critical = "Static field used to store serialization schema elements from future versions."
- + " Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static Hashtable serializationSchemaElements;
- internal SchemaImporter(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames, ICollection<XmlSchemaElement> elements, XmlQualifiedName[] elementTypeNames, DataContractSet dataContractSet, bool importXmlDataType)
- {
- this.dataContractSet = dataContractSet;
- this.schemaSet = schemas;
- this.typeNames = typeNames;
- this.elements = elements;
- this.elementTypeNames = elementTypeNames;
- this.importXmlDataType = importXmlDataType;
- }
- internal void Import()
- {
- if (!schemaSet.Contains(Globals.SerializationNamespace))
- {
- StringReader reader = new StringReader(Globals.SerializationSchema);
- XmlSchema schema = XmlSchema.Read(reader, null);
- if (schema == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace)));
- schemaSet.Add(schema);
- }
- try
- {
- CompileSchemaSet(schemaSet);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception ex)
- {
- if (Fx.IsFatal(ex))
- {
- throw;
- }
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportInvalidSchemas), ex));
- }
- if (typeNames == null)
- {
- ICollection schemaList = schemaSet.Schemas();
- foreach (object schemaObj in schemaList)
- {
- if (schemaObj == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullSchema)));
- XmlSchema schema = (XmlSchema)schemaObj;
- if (schema.TargetNamespace != Globals.SerializationNamespace
- && schema.TargetNamespace != Globals.SchemaNamespace)
- {
- foreach (XmlSchemaObject typeObj in schema.SchemaTypes.Values)
- {
- ImportType((XmlSchemaType)typeObj);
- }
- foreach (XmlSchemaElement element in schema.Elements.Values)
- {
- if (element.SchemaType != null)
- ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace);
- }
- }
- }
- }
- else
- {
- foreach (XmlQualifiedName typeName in typeNames)
- {
- if (typeName == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullDataContractName)));
- ImportType(typeName);
- }
- if (elements != null)
- {
- int i = 0;
- foreach (XmlSchemaElement element in elements)
- {
- XmlQualifiedName typeName = element.SchemaTypeName;
- if (typeName != null && typeName.Name.Length > 0)
- {
- elementTypeNames[i++] = ImportType(typeName).StableName;
- }
- else
- {
- XmlSchema schema = SchemaHelper.GetSchemaWithGlobalElementDeclaration(element, schemaSet);
- if (schema == null)
- {
- elementTypeNames[i++] = ImportAnonymousElement(element, element.QualifiedName).StableName;
- }
- else
- {
- elementTypeNames[i++] = ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace).StableName;
- }
- }
- }
- }
- }
- ImportKnownTypesForObject();
- }
- internal static void CompileSchemaSet(XmlSchemaSet schemaSet)
- {
- if (schemaSet.Contains(XmlSchema.Namespace))
- schemaSet.Compile();
- else
- {
- // Add base XSD schema with top level element named "schema"
- XmlSchema xsdSchema = new XmlSchema();
- xsdSchema.TargetNamespace = XmlSchema.Namespace;
- XmlSchemaElement element = new XmlSchemaElement();
- element.Name = Globals.SchemaLocalName;
- element.SchemaType = new XmlSchemaComplexType();
- xsdSchema.Items.Add(element);
- schemaSet.Add(xsdSchema);
- schemaSet.Compile();
- }
- }
- SchemaObjectDictionary SchemaObjects
- {
- get
- {
- if (schemaObjects == null)
- schemaObjects = CreateSchemaObjects();
- return schemaObjects;
- }
- }
- List<XmlSchemaRedefine> RedefineList
- {
- get
- {
- if (redefineList == null)
- redefineList = CreateRedefineList();
- return redefineList;
- }
- }
- void ImportKnownTypes(XmlQualifiedName typeName)
- {
- SchemaObjectInfo schemaObjectInfo;
- if (SchemaObjects.TryGetValue(typeName, out schemaObjectInfo))
- {
- List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
- if (knownTypes != null)
- {
- foreach (XmlSchemaType knownType in knownTypes)
- ImportType(knownType);
- }
- }
- }
- internal static bool IsObjectContract(DataContract dataContract)
- {
- Dictionary<Type, object> previousCollectionTypes = new Dictionary<Type, object>();
- while (dataContract is CollectionDataContract)
- {
- if (dataContract.OriginalUnderlyingType == null)
- {
- dataContract = ((CollectionDataContract)dataContract).ItemContract;
- continue;
- }
- if (!previousCollectionTypes.ContainsKey(dataContract.OriginalUnderlyingType))
- {
- previousCollectionTypes.Add(dataContract.OriginalUnderlyingType, dataContract.OriginalUnderlyingType);
- dataContract = ((CollectionDataContract)dataContract).ItemContract;
- }
- else
- {
- break;
- }
- }
- return dataContract is PrimitiveDataContract && ((PrimitiveDataContract)dataContract).UnderlyingType == Globals.TypeOfObject;
- }
- void ImportKnownTypesForObject()
- {
- if (!needToImportKnownTypesForObject)
- return;
- needToImportKnownTypesForObject = false;
- if (dataContractSet.KnownTypesForObject == null)
- {
- SchemaObjectInfo schemaObjectInfo;
- if (SchemaObjects.TryGetValue(SchemaExporter.AnytypeQualifiedName, out schemaObjectInfo))
- {
- List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
- if (knownTypes != null)
- {
- DataContractDictionary knownDataContracts = new DataContractDictionary();
- foreach (XmlSchemaType knownType in knownTypes)
- {
- // Expected: will throw exception if schema set contains types that are not supported
- DataContract dataContract = ImportType(knownType);
- DataContract existingContract;
- if (!knownDataContracts.TryGetValue(dataContract.StableName, out existingContract))
- {
- knownDataContracts.Add(dataContract.StableName, dataContract);
- }
- }
- dataContractSet.KnownTypesForObject = knownDataContracts;
- }
- }
- }
- }
- internal SchemaObjectDictionary CreateSchemaObjects()
- {
- SchemaObjectDictionary schemaObjects = new SchemaObjectDictionary();
- ICollection schemaList = schemaSet.Schemas();
- List<XmlSchemaType> knownTypesForObject = new List<XmlSchemaType>();
- schemaObjects.Add(SchemaExporter.AnytypeQualifiedName, new SchemaObjectInfo(null, null, null, knownTypesForObject));
- foreach (XmlSchema schema in schemaList)
- {
- if (schema.TargetNamespace != Globals.SerializationNamespace)
- {
- foreach (XmlSchemaObject schemaObj in schema.SchemaTypes.Values)
- {
- XmlSchemaType schemaType = schemaObj as XmlSchemaType;
- if (schemaType != null)
- {
- knownTypesForObject.Add(schemaType);
- XmlQualifiedName currentTypeName = new XmlQualifiedName(schemaType.Name, schema.TargetNamespace);
- SchemaObjectInfo schemaObjectInfo;
- if (schemaObjects.TryGetValue(currentTypeName, out schemaObjectInfo))
- {
- schemaObjectInfo.type = schemaType;
- schemaObjectInfo.schema = schema;
- }
- else
- {
- schemaObjects.Add(currentTypeName, new SchemaObjectInfo(schemaType, null, schema, null));
- }
- XmlQualifiedName baseTypeName = GetBaseTypeName(schemaType);
- if (baseTypeName != null)
- {
- SchemaObjectInfo baseTypeInfo;
- if (schemaObjects.TryGetValue(baseTypeName, out baseTypeInfo))
- {
- if (baseTypeInfo.knownTypes == null)
- {
- baseTypeInfo.knownTypes = new List<XmlSchemaType>();
- }
- }
- else
- {
- baseTypeInfo = new SchemaObjectInfo(null, null, null, new List<XmlSchemaType>());
- schemaObjects.Add(baseTypeName, baseTypeInfo);
- }
- baseTypeInfo.knownTypes.Add(schemaType);
- }
- }
- }
- foreach (XmlSchemaObject schemaObj in schema.Elements.Values)
- {
- XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
- if (schemaElement != null)
- {
- XmlQualifiedName currentElementName = new XmlQualifiedName(schemaElement.Name, schema.TargetNamespace);
- SchemaObjectInfo schemaObjectInfo;
- if (schemaObjects.TryGetValue(currentElementName, out schemaObjectInfo))
- {
- schemaObjectInfo.element = schemaElement;
- schemaObjectInfo.schema = schema;
- }
- else
- {
- schemaObjects.Add(currentElementName, new SchemaObjectInfo(null, schemaElement, schema, null));
- }
- }
- }
- }
- }
- return schemaObjects;
- }
- XmlQualifiedName GetBaseTypeName(XmlSchemaType type)
- {
- XmlQualifiedName baseTypeName = null;
- XmlSchemaComplexType complexType = type as XmlSchemaComplexType;
- if (complexType != null)
- {
- if (complexType.ContentModel != null)
- {
- XmlSchemaComplexContent complexContent = complexType.ContentModel as XmlSchemaComplexContent;
- if (complexContent != null)
- {
- XmlSchemaComplexContentExtension extension = complexContent.Content as XmlSchemaComplexContentExtension;
- if (extension != null)
- baseTypeName = extension.BaseTypeName;
- }
- }
- }
- return baseTypeName;
- }
- List<XmlSchemaRedefine> CreateRedefineList()
- {
- List<XmlSchemaRedefine> list = new List<XmlSchemaRedefine>();
- ICollection schemaList = schemaSet.Schemas();
- foreach (object schemaObj in schemaList)
- {
- XmlSchema schema = schemaObj as XmlSchema;
- if (schema == null)
- continue;
- foreach (XmlSchemaExternal ext in schema.Includes)
- {
- XmlSchemaRedefine redefine = ext as XmlSchemaRedefine;
- if (redefine != null)
- list.Add(redefine);
- }
- }
- return list;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- DataContract ImportAnonymousGlobalElement(XmlSchemaElement element, XmlQualifiedName typeQName, string ns)
- {
- DataContract contract = ImportAnonymousElement(element, typeQName);
- XmlDataContract xmlDataContract = contract as XmlDataContract;
- if (xmlDataContract != null)
- {
- xmlDataContract.SetTopLevelElementName(new XmlQualifiedName(element.Name, ns));
- xmlDataContract.IsTopLevelElementNullable = element.IsNillable;
- }
- return contract;
- }
- DataContract ImportAnonymousElement(XmlSchemaElement element, XmlQualifiedName typeQName)
- {
- if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) != null)
- {
- for (int i = 1;; i++)
- {
- typeQName = new XmlQualifiedName(typeQName.Name + i.ToString(NumberFormatInfo.InvariantInfo), typeQName.Namespace);
- if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) == null)
- break;
- if (i == Int32.MaxValue)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, element.Name)));
- }
- }
- if (element.SchemaType == null)
- return ImportType(SchemaExporter.AnytypeQualifiedName);
- else
- return ImportType(element.SchemaType, typeQName, true/*isAnonymous*/);
- }
- DataContract ImportType(XmlQualifiedName typeName)
- {
- DataContract dataContract = DataContract.GetBuiltInDataContract(typeName.Name, typeName.Namespace);
- if (dataContract == null)
- {
- XmlSchemaType type = SchemaHelper.GetSchemaType(SchemaObjects, typeName);
- if (type == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SpecifiedTypeNotFoundInSchema, typeName.Name, typeName.Namespace)));
- dataContract = ImportType(type);
- }
- if (IsObjectContract(dataContract))
- needToImportKnownTypesForObject = true;
- return dataContract;
- }
- DataContract ImportType(XmlSchemaType type)
- {
- return ImportType(type, type.QualifiedName, false/*isAnonymous*/);
- }
- DataContract ImportType(XmlSchemaType type, XmlQualifiedName typeName, bool isAnonymous)
- {
- DataContract dataContract = dataContractSet[typeName];
- if (dataContract != null)
- return dataContract;
- InvalidDataContractException invalidContractException;
- try
- {
- foreach (XmlSchemaRedefine redefine in RedefineList)
- {
- if (redefine.SchemaTypes[typeName] != null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RedefineNotSupported));
- }
- if (type is XmlSchemaSimpleType)
- {
- XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)type;
- XmlSchemaSimpleTypeContent content = simpleType.Content;
- if (content is XmlSchemaSimpleTypeUnion)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeUnionNotSupported));
- else if (content is XmlSchemaSimpleTypeList)
- dataContract = ImportFlagsEnum(typeName, (XmlSchemaSimpleTypeList)content, simpleType.Annotation);
- else if (content is XmlSchemaSimpleTypeRestriction)
- {
- XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
- if (CheckIfEnum(restriction))
- {
- dataContract = ImportEnum(typeName, restriction, false /*isFlags*/, simpleType.Annotation);
- }
- else
- {
- dataContract = ImportSimpleTypeRestriction(typeName, restriction);
- if (dataContract.IsBuiltInDataContract && !isAnonymous)
- {
- dataContractSet.InternalAdd(typeName, dataContract);
- }
- }
- }
- }
- else if (type is XmlSchemaComplexType)
- {
- XmlSchemaComplexType complexType = (XmlSchemaComplexType)type;
- if (complexType.ContentModel == null)
- {
- CheckComplexType(typeName, complexType);
- dataContract = ImportType(typeName, complexType.Particle, complexType.Attributes, complexType.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
- }
- else
- {
- XmlSchemaContentModel contentModel = complexType.ContentModel;
- if (contentModel is XmlSchemaSimpleContent)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleContentNotSupported));
- else if (contentModel is XmlSchemaComplexContent)
- {
- XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)contentModel;
- if (complexContent.IsMixed)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
- if (complexContent.Content is XmlSchemaComplexContentExtension)
- {
- XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)complexContent.Content;
- dataContract = ImportType(typeName, extension.Particle, extension.Attributes, extension.AnyAttribute, extension.BaseTypeName, complexType.Annotation);
- }
- else if (complexContent.Content is XmlSchemaComplexContentRestriction)
- {
- XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)complexContent.Content;
- XmlQualifiedName baseTypeName = restriction.BaseTypeName;
- if (baseTypeName == SchemaExporter.AnytypeQualifiedName)
- dataContract = ImportType(typeName, restriction.Particle, restriction.Attributes, restriction.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
- else
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ComplexTypeRestrictionNotSupported));
- }
- }
- }
- }
- if (dataContract == null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, String.Empty);
- if (type.QualifiedName != XmlQualifiedName.Empty)
- ImportTopLevelElement(typeName);
- ImportDataContractExtension(type, dataContract);
- ImportGenericInfo(type, dataContract);
- ImportKnownTypes(typeName);
- return dataContract;
- }
- catch (InvalidDataContractException e)
- {
- invalidContractException = e;
- }
- // Execution gets to this point if InvalidDataContractException was thrown
- if (importXmlDataType)
- {
- RemoveFailedContract(typeName);
- return ImportXmlDataType(typeName, type, isAnonymous);
- }
- Type referencedType;
- if (dataContractSet.TryGetReferencedType(typeName, dataContract, out referencedType)
- || (string.IsNullOrEmpty(type.Name) && dataContractSet.TryGetReferencedType(ImportActualType(type.Annotation, typeName, typeName), dataContract, out referencedType)))
- {
- if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
- {
- RemoveFailedContract(typeName);
- return ImportXmlDataType(typeName, type, isAnonymous);
- }
- }
- XmlDataContract specialContract = ImportSpecialXmlDataType(type, isAnonymous);
- if (specialContract != null)
- {
- this.dataContractSet.Remove(typeName);
- return specialContract;
- }
- throw invalidContractException;
- }
- private void RemoveFailedContract(XmlQualifiedName typeName)
- {
- ClassDataContract oldContract = this.dataContractSet[typeName] as ClassDataContract;
- this.dataContractSet.Remove(typeName);
- if (oldContract != null)
- {
- ClassDataContract ancestorDataContract = oldContract.BaseContract;
- while (ancestorDataContract != null)
- {
- ancestorDataContract.KnownDataContracts.Remove(typeName);
- ancestorDataContract = ancestorDataContract.BaseContract;
- }
- if (dataContractSet.KnownTypesForObject != null)
- dataContractSet.KnownTypesForObject.Remove(typeName);
- }
- }
- bool CheckIfEnum(XmlSchemaSimpleTypeRestriction restriction)
- {
- foreach (XmlSchemaFacet facet in restriction.Facets)
- {
- if (!(facet is XmlSchemaEnumerationFacet))
- return false;
- }
- XmlQualifiedName expectedBase = SchemaExporter.StringQualifiedName;
- if (restriction.BaseTypeName != XmlQualifiedName.Empty)
- {
- return ((restriction.BaseTypeName == expectedBase && restriction.Facets.Count > 0) || ImportType(restriction.BaseTypeName) is EnumDataContract);
- }
- else if (restriction.BaseType != null)
- {
- DataContract baseContract = ImportType(restriction.BaseType);
- return (baseContract.StableName == expectedBase || baseContract is EnumDataContract);
- }
- return false;
- }
- bool CheckIfCollection(XmlSchemaSequence rootSequence)
- {
- if (rootSequence.Items == null || rootSequence.Items.Count == 0)
- return false;
- RemoveOptionalUnknownSerializationElements(rootSequence.Items);
- if (rootSequence.Items.Count != 1)
- return false;
- XmlSchemaObject o = rootSequence.Items[0];
- if (!(o is XmlSchemaElement))
- return false;
- XmlSchemaElement localElement = (XmlSchemaElement)o;
- return (localElement.MaxOccursString == Globals.OccursUnbounded || localElement.MaxOccurs > 1);
- }
- bool CheckIfISerializable(XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
- {
- if (rootSequence.Items == null || rootSequence.Items.Count == 0)
- return false;
- RemoveOptionalUnknownSerializationElements(rootSequence.Items);
- if (attributes == null || attributes.Count == 0)
- return false;
- return (rootSequence.Items.Count == 1 && rootSequence.Items[0] is XmlSchemaAny);
- }
- [Fx.Tag.SecurityNote(Critical = "Initializes critical static fields.",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- void RemoveOptionalUnknownSerializationElements(XmlSchemaObjectCollection items)
- {
- for (int i = 0; i < items.Count; i++)
- {
- XmlSchemaElement element = items[i] as XmlSchemaElement;
- if (element != null && element.RefName != null &&
- element.RefName.Namespace == Globals.SerializationNamespace &&
- element.MinOccurs == 0)
- {
- if (serializationSchemaElements == null)
- {
- XmlSchema serializationSchema = XmlSchema.Read(XmlReader.Create(new StringReader(Globals.SerializationSchema)), null);
- serializationSchemaElements = new Hashtable();
- foreach (XmlSchemaObject schemaObject in serializationSchema.Items)
- {
- XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement;
- if (schemaElement != null)
- serializationSchemaElements.Add(schemaElement.Name, schemaElement);
- }
- }
- if (!serializationSchemaElements.ContainsKey(element.RefName.Name))
- {
- items.RemoveAt(i);
- i--;
- }
- }
- }
- }
- DataContract ImportType(XmlQualifiedName typeName, XmlSchemaParticle rootParticle, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation)
- {
- DataContract dataContract = null;
- bool isDerived = (baseTypeName != null);
- bool isReference;
- ImportAttributes(typeName, attributes, anyAttribute, out isReference);
- if (rootParticle == null)
- dataContract = ImportClass(typeName, new XmlSchemaSequence(), baseTypeName, annotation, isReference);
- else if (!(rootParticle is XmlSchemaSequence))
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootParticleMustBeSequence));
- else
- {
- XmlSchemaSequence rootSequence = (XmlSchemaSequence)rootParticle;
- if (rootSequence.MinOccurs != 1)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMustBeRequired));
- if (rootSequence.MaxOccurs != 1)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMaxOccursMustBe));
- if (!isDerived && CheckIfCollection(rootSequence))
- dataContract = ImportCollection(typeName, rootSequence, attributes, annotation, isReference);
- else if (CheckIfISerializable(rootSequence, attributes))
- dataContract = ImportISerializable(typeName, rootSequence, baseTypeName, attributes, annotation);
- else
- dataContract = ImportClass(typeName, rootSequence, baseTypeName, annotation, isReference);
- }
- return dataContract;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- ClassDataContract ImportClass(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation, bool isReference)
- {
- ClassDataContract dataContract = new ClassDataContract();
- dataContract.StableName = typeName;
- AddDataContract(dataContract);
- dataContract.IsValueType = IsValueType(typeName, annotation);
- dataContract.IsReference = isReference;
- if (baseTypeName != null)
- {
- ImportBaseContract(baseTypeName, dataContract);
- if (dataContract.BaseContract.IsISerializable)
- {
- if (IsISerializableDerived(typeName, rootSequence))
- dataContract.IsISerializable = true;
- else
- ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.DerivedTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
- }
- if (dataContract.BaseContract.IsReference)
- {
- dataContract.IsReference = true;
- }
- }
- if (!dataContract.IsISerializable)
- {
- dataContract.Members = new List<DataMember>();
- RemoveOptionalUnknownSerializationElements(rootSequence.Items);
- for (int memberIndex = 0; memberIndex < rootSequence.Items.Count; memberIndex++)
- {
- XmlSchemaElement element = rootSequence.Items[memberIndex] as XmlSchemaElement;
- if (element == null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MustContainOnlyLocalElements));
- ImportClassMember(element, dataContract);
- }
- }
- return dataContract;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- DataContract ImportXmlDataType(XmlQualifiedName typeName, XmlSchemaType xsdType, bool isAnonymous)
- {
- DataContract dataContract = dataContractSet[typeName];
- if (dataContract != null)
- return dataContract;
- XmlDataContract xmlDataContract = ImportSpecialXmlDataType(xsdType, isAnonymous);
- if (xmlDataContract != null)
- return xmlDataContract;
- xmlDataContract = new XmlDataContract();
- xmlDataContract.StableName = typeName;
- xmlDataContract.IsValueType = false;
- AddDataContract(xmlDataContract);
- if (xsdType != null)
- {
- ImportDataContractExtension(xsdType, xmlDataContract);
- xmlDataContract.IsValueType = IsValueType(typeName, xsdType.Annotation);
- xmlDataContract.IsTypeDefinedOnImport = true;
- xmlDataContract.XsdType = isAnonymous ? xsdType : null;
- xmlDataContract.HasRoot = !IsXmlAnyElementType(xsdType as XmlSchemaComplexType);
- }
- else
- {
- //Value type can be used by both nillable and non-nillable elements but reference type cannot be used by non nillable elements
- xmlDataContract.IsValueType = true;
- xmlDataContract.IsTypeDefinedOnImport = false;
- xmlDataContract.HasRoot = true;
- if (DiagnosticUtility.ShouldTraceVerbose)
- {
- TraceUtility.Trace(TraceEventType.Verbose, TraceCode.XsdImportAnnotationFailed,
- SR.GetString(SR.TraceCodeXsdImportAnnotationFailed), new StringTraceRecord("Type", typeName.Namespace + ":" + typeName.Name));
- }
- }
- if (!isAnonymous)
- {
- bool isNullable;
- xmlDataContract.SetTopLevelElementName(SchemaHelper.GetGlobalElementDeclaration(schemaSet, typeName, out isNullable));
- xmlDataContract.IsTopLevelElementNullable = isNullable;
- }
- return xmlDataContract;
- }
- private XmlDataContract ImportSpecialXmlDataType(XmlSchemaType xsdType, bool isAnonymous)
- {
- if (!isAnonymous)
- return null;
- XmlSchemaComplexType complexType = xsdType as XmlSchemaComplexType;
- if (complexType == null)
- return null;
- if (IsXmlAnyElementType(complexType))
- {
- //check if the type is XElement
- XmlQualifiedName xlinqTypeName = new XmlQualifiedName("XElement", "http://schemas.datacontract.org/2004/07/System.Xml.Linq");
- Type referencedType;
- if (dataContractSet.TryGetReferencedType(xlinqTypeName, null, out referencedType)
- && Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
- {
- XmlDataContract xmlDataContract = new XmlDataContract(referencedType);
- AddDataContract(xmlDataContract);
- return xmlDataContract;
- }
- //otherwise, assume XmlElement
- return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlElement);
- }
- if (IsXmlAnyType(complexType))
- return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlNodeArray);
- return null;
- }
- bool IsXmlAnyElementType(XmlSchemaComplexType xsdType)
- {
- if (xsdType == null)
- return false;
- XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
- if (sequence == null)
- return false;
- if (sequence.Items == null || sequence.Items.Count != 1)
- return false;
- XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
- if (any == null || any.Namespace != null)
- return false;
- if (xsdType.AnyAttribute != null || (xsdType.Attributes != null && xsdType.Attributes.Count > 0))
- return false;
- return true;
- }
- bool IsXmlAnyType(XmlSchemaComplexType xsdType)
- {
- if (xsdType == null)
- return false;
- XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
- if (sequence == null)
- return false;
- if (sequence.Items == null || sequence.Items.Count != 1)
- return false;
- XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
- if (any == null || any.Namespace != null)
- return false;
- if (any.MaxOccurs != Decimal.MaxValue)
- return false;
- if (xsdType.AnyAttribute == null || xsdType.Attributes.Count > 0)
- return false;
- return true;
- }
- bool IsValueType(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
- {
- string isValueTypeInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsValueTypeName));
- if (isValueTypeInnerText != null)
- {
- try
- {
- return XmlConvert.ToBoolean(isValueTypeInnerText);
- }
- catch (FormatException fe)
- {
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsValueTypeFormattedIncorrectly, isValueTypeInnerText, fe.Message));
- }
- }
- return false;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- ClassDataContract ImportISerializable(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation)
- {
- ClassDataContract dataContract = new ClassDataContract();
- dataContract.StableName = typeName;
- dataContract.IsISerializable = true;
- AddDataContract(dataContract);
- dataContract.IsValueType = IsValueType(typeName, annotation);
- if (baseTypeName == null)
- CheckISerializableBase(typeName, rootSequence, attributes);
- else
- {
- ImportBaseContract(baseTypeName, dataContract);
- if (!dataContract.BaseContract.IsISerializable)
- ThrowISerializableTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.BaseTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
- if (!IsISerializableDerived(typeName, rootSequence))
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDerivedContainsOneOrMoreItems));
- }
- return dataContract;
- }
- void CheckISerializableBase(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
- {
- if (rootSequence == null)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
- if (rootSequence.Items == null || rootSequence.Items.Count < 1)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
- else if (rootSequence.Items.Count > 1)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableContainsMoreThanOneItems));
- XmlSchemaObject o = rootSequence.Items[0];
- if (!(o is XmlSchemaAny))
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
- XmlSchemaAny wildcard = (XmlSchemaAny)o;
- XmlSchemaAny iSerializableWildcardElement = SchemaExporter.ISerializableWildcardElement;
- if (wildcard.MinOccurs != iSerializableWildcardElement.MinOccurs)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMinOccursMustBe, iSerializableWildcardElement.MinOccurs));
- if (wildcard.MaxOccursString != iSerializableWildcardElement.MaxOccursString)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMaxOccursMustBe, iSerializableWildcardElement.MaxOccursString));
- if (wildcard.Namespace != iSerializableWildcardElement.Namespace)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardNamespaceInvalid, iSerializableWildcardElement.Namespace));
- if (wildcard.ProcessContents != iSerializableWildcardElement.ProcessContents)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardProcessContentsInvalid, iSerializableWildcardElement.ProcessContents));
- XmlQualifiedName factoryTypeAttributeRefName = SchemaExporter.ISerializableFactoryTypeAttribute.RefName;
- bool containsFactoryTypeAttribute = false;
- if (attributes != null)
- {
- for (int i = 0; i < attributes.Count; i++)
- {
- o = attributes[i];
- if (o is XmlSchemaAttribute)
- {
- if (((XmlSchemaAttribute)o).RefName == factoryTypeAttributeRefName)
- {
- containsFactoryTypeAttribute = true;
- break;
- }
- }
- }
- }
- if (!containsFactoryTypeAttribute)
- ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableMustRefFactoryTypeAttribute, factoryTypeAttributeRefName.Name, factoryTypeAttributeRefName.Namespace));
- }
- bool IsISerializableDerived(XmlQualifiedName typeName, XmlSchemaSequence rootSequence)
- {
- return (rootSequence == null || rootSequence.Items == null || rootSequence.Items.Count == 0);
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical BaseContract property on ClassDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- void ImportBaseContract(XmlQualifiedName baseTypeName, ClassDataContract dataContract)
- {
- ClassDataContract baseContract = ImportType(baseTypeName) as ClassDataContract;
- if (baseContract == null)
- ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(dataContract.IsISerializable ? SR.InvalidISerializableDerivation : SR.InvalidClassDerivation, baseTypeName.Name, baseTypeName.Namespace));
- // Note: code ignores IsValueType annotation if derived type exists
- if (baseContract.IsValueType)
- baseContract.IsValueType = false;
- ClassDataContract ancestorDataContract = baseContract;
- while (ancestorDataContract != null)
- {
- DataContractDictionary knownDataContracts = ancestorDataContract.KnownDataContracts;
- if (knownDataContracts == null)
- {
- knownDataContracts = new DataContractDictionary();
- ancestorDataContract.KnownDataContracts = knownDataContracts;
- }
- knownDataContracts.Add(dataContract.StableName, dataContract);
- ancestorDataContract = ancestorDataContract.BaseContract;
- }
- dataContract.BaseContract = baseContract;
- }
- void ImportTopLevelElement(XmlQualifiedName typeName)
- {
- XmlSchemaElement topLevelElement = SchemaHelper.GetSchemaElement(SchemaObjects, typeName);
- // Top level element of same name is not required, but is validated if it is present
- if (topLevelElement == null)
- return;
- else
- {
- XmlQualifiedName elementTypeName = topLevelElement.SchemaTypeName;
- if (elementTypeName.IsEmpty)
- {
- if (topLevelElement.SchemaType != null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnonymousTypeNotSupported, typeName.Name, typeName.Namespace));
- else
- elementTypeName = SchemaExporter.AnytypeQualifiedName;
- }
- if (elementTypeName != typeName)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TopLevelElementRepresentsDifferentType, topLevelElement.SchemaTypeName.Name, topLevelElement.SchemaTypeName.Namespace));
- CheckIfElementUsesUnsupportedConstructs(typeName, topLevelElement);
- }
- }
- void ImportClassMember(XmlSchemaElement element, ClassDataContract dataContract)
- {
- XmlQualifiedName typeName = dataContract.StableName;
- if (element.MinOccurs > 1)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMinOccursMustBe, element.Name));
- if (element.MaxOccurs != 1)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMaxOccursMustBe, element.Name));
- DataContract memberTypeContract = null;
- string memberName = element.Name;
- bool memberIsRequired = (element.MinOccurs > 0);
- bool memberIsNullable = element.IsNillable;
- bool memberEmitDefaultValue;
- int memberOrder = 0;
- XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
- if (elementForm != XmlSchemaForm.Qualified)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FormMustBeQualified, element.Name));
- CheckIfElementUsesUnsupportedConstructs(typeName, element);
- if (element.SchemaTypeName.IsEmpty)
- {
- if (element.SchemaType != null)
- memberTypeContract = ImportAnonymousElement(element, new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace));
- else if (!element.RefName.IsEmpty)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
- else
- memberTypeContract = ImportType(SchemaExporter.AnytypeQualifiedName);
- }
- else
- {
- XmlQualifiedName memberTypeName = ImportActualType(element.Annotation, element.SchemaTypeName, typeName);
- memberTypeContract = ImportType(memberTypeName);
- if (IsObjectContract(memberTypeContract))
- needToImportKnownTypesForObject = true;
- }
- bool? emitDefaultValueFromAnnotation = ImportEmitDefaultValue(element.Annotation, typeName);
- if (!memberTypeContract.IsValueType && !memberIsNullable)
- {
- if (emitDefaultValueFromAnnotation != null && emitDefaultValueFromAnnotation.Value)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidEmitDefaultAnnotation, memberName, typeName.Name, typeName.Namespace)));
- memberEmitDefaultValue = false;
- }
- else
- memberEmitDefaultValue = emitDefaultValueFromAnnotation != null ? emitDefaultValueFromAnnotation.Value : Globals.DefaultEmitDefaultValue;
- int prevMemberIndex = dataContract.Members.Count - 1;
- if (prevMemberIndex >= 0)
- {
- DataMember prevMember = dataContract.Members[prevMemberIndex];
- if (prevMember.Order > Globals.DefaultOrder)
- memberOrder = dataContract.Members.Count;
- DataMember currentMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
- int compare = ClassDataContract.DataMemberComparer.Singleton.Compare(prevMember, currentMember);
- if (compare == 0)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateElementNames, memberName));
- else if (compare > 0)
- memberOrder = dataContract.Members.Count;
- }
- DataMember dataMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
- XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
- dataContractSet.SetSurrogateData(dataMember, ImportSurrogateData(ImportAnnotation(element.Annotation, surrogateDataAnnotationName), surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace));
- dataContract.Members.Add(dataMember);
- }
- private bool? ImportEmitDefaultValue(XmlSchemaAnnotation annotation, XmlQualifiedName typeName)
- {
- XmlElement defaultValueElement = ImportAnnotation(annotation, SchemaExporter.DefaultValueAnnotation);
- if (defaultValueElement == null)
- return null;
- XmlNode emitDefaultValueAttribute = defaultValueElement.Attributes.GetNamedItem(Globals.EmitDefaultValueAttribute);
- string emitDefaultValueString = (emitDefaultValueAttribute == null) ? null : emitDefaultValueAttribute.Value;
- if (emitDefaultValueString == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.DefaultValueAnnotation.Name, typeName.Name, typeName.Namespace, Globals.EmitDefaultValueAttribute)));
- return XmlConvert.ToBoolean(emitDefaultValueString);
- }
- internal static XmlQualifiedName ImportActualType(XmlSchemaAnnotation annotation, XmlQualifiedName defaultTypeName, XmlQualifiedName typeName)
- {
- XmlElement actualTypeElement = ImportAnnotation(annotation, SchemaExporter.ActualTypeAnnotationName);
- if (actualTypeElement == null)
- return defaultTypeName;
- XmlNode nameAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNameAttribute);
- string name = (nameAttribute == null) ? null : nameAttribute.Value;
- if (name == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNameAttribute)));
- XmlNode nsAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNamespaceAttribute);
- string ns = (nsAttribute == null) ? null : nsAttribute.Value;
- if (ns == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNamespaceAttribute)));
- return new XmlQualifiedName(name, ns);
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on CollectionDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- CollectionDataContract ImportCollection(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation, bool isReference)
- {
- CollectionDataContract dataContract = new CollectionDataContract(CollectionKind.Array);
- dataContract.StableName = typeName;
- AddDataContract(dataContract);
- dataContract.IsReference = isReference;
- // CheckIfCollection has already checked if sequence contains exactly one item with maxOccurs="unbounded" or maxOccurs > 1
- XmlSchemaElement element = (XmlSchemaElement)rootSequence.Items[0];
- dataContract.IsItemTypeNullable = element.IsNillable;
- dataContract.ItemName = element.Name;
- XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
- if (elementForm != XmlSchemaForm.Qualified)
- ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ArrayItemFormMustBe, element.Name));
- CheckIfElementUsesUnsupportedConstructs(typeName, element);
- if (element.SchemaTypeName.IsEmpty)
- {
- if (element.SchemaType != null)
- {
- XmlQualifiedName shortName = new XmlQualifiedName(element.Name, typeName.Namespace);
- DataContract contract = dataContractSet[shortName];
- if (contract == null)
- {
- dataContract.ItemContract = ImportAnonymousElement(element, shortName);
- }
- else
- {
- XmlQualifiedName fullName = new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace);
- dataContract.ItemContract = ImportAnonymousElement(element, fullName);
- }
- }
- else if (!element.RefName.IsEmpty)
- ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
- else
- dataContract.ItemContract = ImportType(SchemaExporter.AnytypeQualifiedName);
- }
- else
- {
- dataContract.ItemContract = ImportType(element.SchemaTypeName);
- }
- if (IsDictionary(typeName, annotation))
- {
- ClassDataContract keyValueContract = dataContract.ItemContract as ClassDataContract;
- DataMember key = null, value = null;
- if (keyValueContract == null || keyValueContract.Members == null || keyValueContract.Members.Count != 2
- || !(key = keyValueContract.Members[0]).IsRequired || !(value = keyValueContract.Members[1]).IsRequired)
- {
- ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueType, element.Name));
- }
- if (keyValueContract.Namespace != dataContract.Namespace)
- {
- ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueTypeNamespace, element.Name, keyValueContract.Namespace));
- }
- keyValueContract.IsValueType = true;
- dataContract.KeyName = key.Name;
- dataContract.ValueName = value.Name;
- if (element.SchemaType != null)
- {
- dataContractSet.Remove(keyValueContract.StableName);
- GenericInfo genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfKeyValue), Globals.TypeOfKeyValue.FullName);
- genericInfo.Add(GetGenericInfoForDataMember(key));
- genericInfo.Add(GetGenericInfoForDataMember(value));
- genericInfo.AddToLevel(0, 2);
- dataContract.ItemContract.StableName = new XmlQualifiedName(genericInfo.GetExpandedStableName().Name, typeName.Namespace);
- }
- }
- return dataContract;
- }
- GenericInfo GetGenericInfoForDataMember(DataMember dataMember)
- {
- GenericInfo genericInfo = null;
- if (dataMember.MemberTypeContract.IsValueType && dataMember.IsNullable)
- {
- genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfNullable), Globals.TypeOfNullable.FullName);
- genericInfo.Add(new GenericInfo(dataMember.MemberTypeContract.StableName, null));
- }
- else
- {
- genericInfo = new GenericInfo(dataMember.MemberTypeContract.StableName, null);
- }
- return genericInfo;
- }
- bool IsDictionary(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
- {
- string isDictionaryInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsDictionaryAnnotationName));
- if (isDictionaryInnerText != null)
- {
- try
- {
- return XmlConvert.ToBoolean(isDictionaryInnerText);
- }
- catch (FormatException fe)
- {
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsDictionaryFormattedIncorrectly, isDictionaryInnerText, fe.Message));
- }
- }
- return false;
- }
- EnumDataContract ImportFlagsEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeList list, XmlSchemaAnnotation annotation)
- {
- XmlSchemaSimpleType anonymousType = list.ItemType;
- if (anonymousType == null)
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListMustContainAnonymousType));
- XmlSchemaSimpleTypeContent content = anonymousType.Content;
- if (content is XmlSchemaSimpleTypeUnion)
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumUnionInAnonymousTypeNotSupported));
- else if (content is XmlSchemaSimpleTypeList)
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListInAnonymousTypeNotSupported));
- else if (content is XmlSchemaSimpleTypeRestriction)
- {
- XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
- if (CheckIfEnum(restriction))
- return ImportEnum(typeName, restriction, true /*isFlags*/, annotation);
- else
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumRestrictionInvalid));
- }
- return null;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on EnumDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- EnumDataContract ImportEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction, bool isFlags, XmlSchemaAnnotation annotation)
- {
- EnumDataContract dataContract = new EnumDataContract();
- dataContract.StableName = typeName;
- dataContract.BaseContractName = ImportActualType(annotation, SchemaExporter.DefaultEnumBaseTypeName, typeName);
- dataContract.IsFlags = isFlags;
- AddDataContract(dataContract);
- // CheckIfEnum has already checked if baseType of restriction is string
- dataContract.Values = new List<long>();
- dataContract.Members = new List<DataMember>();
- foreach (XmlSchemaFacet facet in restriction.Facets)
- {
- XmlSchemaEnumerationFacet enumFacet = facet as XmlSchemaEnumerationFacet;
- if (enumFacet == null)
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumOnlyEnumerationFacetsSupported));
- if (enumFacet.Value == null)
- ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumEnumerationFacetsMustHaveValue));
- string valueInnerText = GetInnerText(typeName, ImportAnnotation(enumFacet.Annotation, SchemaExporter.EnumerationValueAnnotationName));
- if (valueInnerText == null)
- dataContract.Values.Add(SchemaExporter.GetDefaultEnumValue(isFlags, dataContract.Members.Count));
- else
- dataContract.Values.Add(dataContract.GetEnumValueFromString(valueInnerText));
- DataMember dataMember = new DataMember(enumFacet.Value);
- dataContract.Members.Add(dataMember);
- }
- return dataContract;
- }
- DataContract ImportSimpleTypeRestriction(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction)
- {
- DataContract dataContract = null;
- if (!restriction.BaseTypeName.IsEmpty)
- dataContract = ImportType(restriction.BaseTypeName);
- else if (restriction.BaseType != null)
- dataContract = ImportType(restriction.BaseType);
- else
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeRestrictionDoesNotSpecifyBase));
- return dataContract;
- }
- void ImportDataContractExtension(XmlSchemaType type, DataContract dataContract)
- {
- if (type.Annotation == null || type.Annotation.Items == null)
- return;
- foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
- {
- XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
- if (appInfo == null)
- continue;
- if (appInfo.Markup != null)
- {
- foreach (XmlNode xmlNode in appInfo.Markup)
- {
- XmlElement typeElement = xmlNode as XmlElement;
- XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
- if (typeElement != null && typeElement.NamespaceURI == surrogateDataAnnotationName.Namespace && typeElement.LocalName == surrogateDataAnnotationName.Name)
- {
- object surrogateData = ImportSurrogateData(typeElement, surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace);
- dataContractSet.SetSurrogateData(dataContract, surrogateData);
- }
- }
- }
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on DataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- void ImportGenericInfo(XmlSchemaType type, DataContract dataContract)
- {
- if (type.Annotation == null || type.Annotation.Items == null)
- return;
- foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
- {
- XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
- if (appInfo == null)
- continue;
- if (appInfo.Markup != null)
- {
- foreach (XmlNode xmlNode in appInfo.Markup)
- {
- XmlElement typeElement = xmlNode as XmlElement;
- if (typeElement != null && typeElement.NamespaceURI == Globals.SerializationNamespace)
- {
- if (typeElement.LocalName == Globals.GenericTypeLocalName)
- dataContract.GenericInfo = ImportGenericInfo(typeElement, type);
- }
- }
- }
- }
- }
- GenericInfo ImportGenericInfo(XmlElement typeElement, XmlSchemaType type)
- {
- XmlNode nameAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNameAttribute);
- string name = (nameAttribute == null) ? null : nameAttribute.Value;
- if (name == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNameAttribute)));
- XmlNode nsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNamespaceAttribute);
- string ns = (nsAttribute == null) ? null : nsAttribute.Value;
- if (ns == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNamespaceAttribute)));
- if (typeElement.ChildNodes.Count > 0) //Generic Type
- name = DataContract.EncodeLocalName(name);
- int currentLevel = 0;
- GenericInfo genInfo = new GenericInfo(new XmlQualifiedName(name, ns), type.Name);
- foreach (XmlNode childNode in typeElement.ChildNodes)
- {
- XmlElement argumentElement = childNode as XmlElement;
- if (argumentElement == null)
- continue;
- if (argumentElement.LocalName != Globals.GenericParameterLocalName ||
- argumentElement.NamespaceURI != Globals.SerializationNamespace)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidElement, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
- XmlNode nestedLevelAttribute = argumentElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
- int argumentLevel = 0;
- if (nestedLevelAttribute != null)
- {
- if (!Int32.TryParse(nestedLevelAttribute.Value, out argumentLevel))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidAttributeValue, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name, nestedLevelAttribute.Value, nestedLevelAttribute.LocalName, Globals.TypeOfInt.Name)));
- }
- if (argumentLevel < currentLevel)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationForNestedLevelMustBeIncreasing, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
- genInfo.Add(ImportGenericInfo(argumentElement, type));
- genInfo.AddToLevel(argumentLevel, 1);
- currentLevel = argumentLevel;
- }
- XmlNode typeNestedLevelsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
- if (typeNestedLevelsAttribute != null)
- {
- int nestedLevels = 0;
- if (!Int32.TryParse(typeNestedLevelsAttribute.Value, out nestedLevels))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidAttributeValue, typeElement.LocalName, typeElement.NamespaceURI, type.Name, typeNestedLevelsAttribute.Value, typeNestedLevelsAttribute.LocalName, Globals.TypeOfInt.Name)));
- if ((nestedLevels - 1) > currentLevel)
- genInfo.AddToLevel(nestedLevels - 1, 0);
- }
- return genInfo;
- }
- object ImportSurrogateData(XmlElement typeElement, string name, string ns)
- {
- if (dataContractSet.DataContractSurrogate != null && typeElement != null)
- {
- Collection<Type> knownTypes = new Collection<Type>();
- DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes);
- DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject, name, ns, knownTypes,
- Int32.MaxValue, false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
- return serializer.ReadObject(new XmlNodeReader(typeElement));
- }
- return null;
- }
- void CheckComplexType(XmlQualifiedName typeName, XmlSchemaComplexType type)
- {
- if (type.IsAbstract)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractTypeNotSupported));
- if (type.IsMixed)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
- }
- void CheckIfElementUsesUnsupportedConstructs(XmlQualifiedName typeName, XmlSchemaElement element)
- {
- if (element.IsAbstract)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractElementNotSupported, element.Name));
- if (element.DefaultValue != null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.DefaultOnElementNotSupported, element.Name));
- if (element.FixedValue != null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FixedOnElementNotSupported, element.Name));
- if (!element.SubstitutionGroup.IsEmpty)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SubstitutionGroupOnElementNotSupported, element.Name));
- }
- void ImportAttributes(XmlQualifiedName typeName, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, out bool isReference)
- {
- if (anyAttribute != null)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnyAttributeNotSupported));
- isReference = false;
- if (attributes != null)
- {
- bool foundId = false, foundRef = false;
- for (int i = 0; i < attributes.Count; i++)
- {
- XmlSchemaObject o = attributes[i];
- if (o is XmlSchemaAttribute)
- {
- XmlSchemaAttribute attribute = (XmlSchemaAttribute)o;
- if (attribute.Use == XmlSchemaUse.Prohibited)
- continue;
- if (TryCheckIfAttribute(typeName, attribute, Globals.IdQualifiedName, ref foundId))
- continue;
- if (TryCheckIfAttribute(typeName, attribute, Globals.RefQualifiedName, ref foundRef))
- continue;
- if (attribute.RefName.IsEmpty || attribute.RefName.Namespace != Globals.SerializationNamespace || attribute.Use == XmlSchemaUse.Required)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TypeShouldNotContainAttributes, Globals.SerializationNamespace));
- }
- }
- isReference = (foundId && foundRef);
- }
- }
- bool TryCheckIfAttribute(XmlQualifiedName typeName, XmlSchemaAttribute attribute, XmlQualifiedName refName, ref bool foundAttribute)
- {
- if (attribute.RefName != refName)
- return false;
- if (foundAttribute)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateAttributeNames, refName.Name));
- foundAttribute = true;
- return true;
- }
- void AddDataContract(DataContract dataContract)
- {
- dataContractSet.Add(dataContract.StableName, dataContract);
- }
- string GetInnerText(XmlQualifiedName typeName, XmlElement xmlElement)
- {
- if (xmlElement != null)
- {
- XmlNode child = xmlElement.FirstChild;
- while (child != null)
- {
- if (child.NodeType == XmlNodeType.Element)
- ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidAnnotationExpectingText, xmlElement.LocalName, xmlElement.NamespaceURI, child.LocalName, child.NamespaceURI));
- child = child.NextSibling;
- }
- return xmlElement.InnerText;
- }
- return null;
- }
- static XmlElement ImportAnnotation(XmlSchemaAnnotation annotation, XmlQualifiedName annotationQualifiedName)
- {
- if (annotation != null && annotation.Items != null && annotation.Items.Count > 0 && annotation.Items[0] is XmlSchemaAppInfo)
- {
- XmlSchemaAppInfo appInfo = (XmlSchemaAppInfo)annotation.Items[0];
- XmlNode[] markup = appInfo.Markup;
- if (markup != null)
- {
- for (int i = 0; i < markup.Length; i++)
- {
- XmlElement annotationElement = markup[i] as XmlElement;
- if (annotationElement != null && annotationElement.LocalName == annotationQualifiedName.Name && annotationElement.NamespaceURI == annotationQualifiedName.Namespace)
- return annotationElement;
- }
- }
- }
- return null;
- }
- static void ThrowTypeCannotBeImportedException(string name, string ns, string message)
- {
- ThrowTypeCannotBeImportedException(SR.GetString(SR.TypeCannotBeImported, name, ns, message));
- }
- static void ThrowArrayTypeCannotBeImportedException(string name, string ns, string message)
- {
- ThrowTypeCannotBeImportedException(SR.GetString(SR.ArrayTypeCannotBeImported, name, ns, message));
- }
- static void ThrowEnumTypeCannotBeImportedException(string name, string ns, string message)
- {
- ThrowTypeCannotBeImportedException(SR.GetString(SR.EnumTypeCannotBeImported, name, ns, message));
- }
- static void ThrowISerializableTypeCannotBeImportedException(string name, string ns, string message)
- {
- ThrowTypeCannotBeImportedException(SR.GetString(SR.ISerializableTypeCannotBeImported, name, ns, message));
- }
- static void ThrowTypeCannotBeImportedException(string message)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeCannotBeImportedHowToFix, message)));
- }
- }
- }
|