SchemaImporter.cs 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.Runtime.Serialization
  5. {
  6. using System;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.Diagnostics;
  11. using System.Globalization;
  12. using System.IO;
  13. using System.Security;
  14. using System.Runtime.Diagnostics;
  15. using System.Xml;
  16. using System.Xml.Schema;
  17. using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
  18. using SchemaObjectDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, SchemaObjectInfo>;
  19. using System.Runtime.Serialization.Diagnostics;
  20. class SchemaImporter
  21. {
  22. DataContractSet dataContractSet;
  23. XmlSchemaSet schemaSet;
  24. ICollection<XmlQualifiedName> typeNames;
  25. ICollection<XmlSchemaElement> elements;
  26. XmlQualifiedName[] elementTypeNames;
  27. bool importXmlDataType;
  28. SchemaObjectDictionary schemaObjects;
  29. List<XmlSchemaRedefine> redefineList;
  30. bool needToImportKnownTypesForObject;
  31. [Fx.Tag.SecurityNote(Critical = "Static field used to store serialization schema elements from future versions."
  32. + " Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
  33. [SecurityCritical]
  34. static Hashtable serializationSchemaElements;
  35. internal SchemaImporter(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames, ICollection<XmlSchemaElement> elements, XmlQualifiedName[] elementTypeNames, DataContractSet dataContractSet, bool importXmlDataType)
  36. {
  37. this.dataContractSet = dataContractSet;
  38. this.schemaSet = schemas;
  39. this.typeNames = typeNames;
  40. this.elements = elements;
  41. this.elementTypeNames = elementTypeNames;
  42. this.importXmlDataType = importXmlDataType;
  43. }
  44. internal void Import()
  45. {
  46. if (!schemaSet.Contains(Globals.SerializationNamespace))
  47. {
  48. StringReader reader = new StringReader(Globals.SerializationSchema);
  49. XmlSchema schema = XmlSchema.Read(reader, null);
  50. if (schema == null)
  51. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace)));
  52. schemaSet.Add(schema);
  53. }
  54. try
  55. {
  56. CompileSchemaSet(schemaSet);
  57. }
  58. #pragma warning suppress 56500 // covered by FxCOP
  59. catch (Exception ex)
  60. {
  61. if (Fx.IsFatal(ex))
  62. {
  63. throw;
  64. }
  65. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportInvalidSchemas), ex));
  66. }
  67. if (typeNames == null)
  68. {
  69. ICollection schemaList = schemaSet.Schemas();
  70. foreach (object schemaObj in schemaList)
  71. {
  72. if (schemaObj == null)
  73. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullSchema)));
  74. XmlSchema schema = (XmlSchema)schemaObj;
  75. if (schema.TargetNamespace != Globals.SerializationNamespace
  76. && schema.TargetNamespace != Globals.SchemaNamespace)
  77. {
  78. foreach (XmlSchemaObject typeObj in schema.SchemaTypes.Values)
  79. {
  80. ImportType((XmlSchemaType)typeObj);
  81. }
  82. foreach (XmlSchemaElement element in schema.Elements.Values)
  83. {
  84. if (element.SchemaType != null)
  85. ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace);
  86. }
  87. }
  88. }
  89. }
  90. else
  91. {
  92. foreach (XmlQualifiedName typeName in typeNames)
  93. {
  94. if (typeName == null)
  95. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullDataContractName)));
  96. ImportType(typeName);
  97. }
  98. if (elements != null)
  99. {
  100. int i = 0;
  101. foreach (XmlSchemaElement element in elements)
  102. {
  103. XmlQualifiedName typeName = element.SchemaTypeName;
  104. if (typeName != null && typeName.Name.Length > 0)
  105. {
  106. elementTypeNames[i++] = ImportType(typeName).StableName;
  107. }
  108. else
  109. {
  110. XmlSchema schema = SchemaHelper.GetSchemaWithGlobalElementDeclaration(element, schemaSet);
  111. if (schema == null)
  112. {
  113. elementTypeNames[i++] = ImportAnonymousElement(element, element.QualifiedName).StableName;
  114. }
  115. else
  116. {
  117. elementTypeNames[i++] = ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace).StableName;
  118. }
  119. }
  120. }
  121. }
  122. }
  123. ImportKnownTypesForObject();
  124. }
  125. internal static void CompileSchemaSet(XmlSchemaSet schemaSet)
  126. {
  127. if (schemaSet.Contains(XmlSchema.Namespace))
  128. schemaSet.Compile();
  129. else
  130. {
  131. // Add base XSD schema with top level element named "schema"
  132. XmlSchema xsdSchema = new XmlSchema();
  133. xsdSchema.TargetNamespace = XmlSchema.Namespace;
  134. XmlSchemaElement element = new XmlSchemaElement();
  135. element.Name = Globals.SchemaLocalName;
  136. element.SchemaType = new XmlSchemaComplexType();
  137. xsdSchema.Items.Add(element);
  138. schemaSet.Add(xsdSchema);
  139. schemaSet.Compile();
  140. }
  141. }
  142. SchemaObjectDictionary SchemaObjects
  143. {
  144. get
  145. {
  146. if (schemaObjects == null)
  147. schemaObjects = CreateSchemaObjects();
  148. return schemaObjects;
  149. }
  150. }
  151. List<XmlSchemaRedefine> RedefineList
  152. {
  153. get
  154. {
  155. if (redefineList == null)
  156. redefineList = CreateRedefineList();
  157. return redefineList;
  158. }
  159. }
  160. void ImportKnownTypes(XmlQualifiedName typeName)
  161. {
  162. SchemaObjectInfo schemaObjectInfo;
  163. if (SchemaObjects.TryGetValue(typeName, out schemaObjectInfo))
  164. {
  165. List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
  166. if (knownTypes != null)
  167. {
  168. foreach (XmlSchemaType knownType in knownTypes)
  169. ImportType(knownType);
  170. }
  171. }
  172. }
  173. internal static bool IsObjectContract(DataContract dataContract)
  174. {
  175. Dictionary<Type, object> previousCollectionTypes = new Dictionary<Type, object>();
  176. while (dataContract is CollectionDataContract)
  177. {
  178. if (dataContract.OriginalUnderlyingType == null)
  179. {
  180. dataContract = ((CollectionDataContract)dataContract).ItemContract;
  181. continue;
  182. }
  183. if (!previousCollectionTypes.ContainsKey(dataContract.OriginalUnderlyingType))
  184. {
  185. previousCollectionTypes.Add(dataContract.OriginalUnderlyingType, dataContract.OriginalUnderlyingType);
  186. dataContract = ((CollectionDataContract)dataContract).ItemContract;
  187. }
  188. else
  189. {
  190. break;
  191. }
  192. }
  193. return dataContract is PrimitiveDataContract && ((PrimitiveDataContract)dataContract).UnderlyingType == Globals.TypeOfObject;
  194. }
  195. void ImportKnownTypesForObject()
  196. {
  197. if (!needToImportKnownTypesForObject)
  198. return;
  199. needToImportKnownTypesForObject = false;
  200. if (dataContractSet.KnownTypesForObject == null)
  201. {
  202. SchemaObjectInfo schemaObjectInfo;
  203. if (SchemaObjects.TryGetValue(SchemaExporter.AnytypeQualifiedName, out schemaObjectInfo))
  204. {
  205. List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
  206. if (knownTypes != null)
  207. {
  208. DataContractDictionary knownDataContracts = new DataContractDictionary();
  209. foreach (XmlSchemaType knownType in knownTypes)
  210. {
  211. // Expected: will throw exception if schema set contains types that are not supported
  212. DataContract dataContract = ImportType(knownType);
  213. DataContract existingContract;
  214. if (!knownDataContracts.TryGetValue(dataContract.StableName, out existingContract))
  215. {
  216. knownDataContracts.Add(dataContract.StableName, dataContract);
  217. }
  218. }
  219. dataContractSet.KnownTypesForObject = knownDataContracts;
  220. }
  221. }
  222. }
  223. }
  224. internal SchemaObjectDictionary CreateSchemaObjects()
  225. {
  226. SchemaObjectDictionary schemaObjects = new SchemaObjectDictionary();
  227. ICollection schemaList = schemaSet.Schemas();
  228. List<XmlSchemaType> knownTypesForObject = new List<XmlSchemaType>();
  229. schemaObjects.Add(SchemaExporter.AnytypeQualifiedName, new SchemaObjectInfo(null, null, null, knownTypesForObject));
  230. foreach (XmlSchema schema in schemaList)
  231. {
  232. if (schema.TargetNamespace != Globals.SerializationNamespace)
  233. {
  234. foreach (XmlSchemaObject schemaObj in schema.SchemaTypes.Values)
  235. {
  236. XmlSchemaType schemaType = schemaObj as XmlSchemaType;
  237. if (schemaType != null)
  238. {
  239. knownTypesForObject.Add(schemaType);
  240. XmlQualifiedName currentTypeName = new XmlQualifiedName(schemaType.Name, schema.TargetNamespace);
  241. SchemaObjectInfo schemaObjectInfo;
  242. if (schemaObjects.TryGetValue(currentTypeName, out schemaObjectInfo))
  243. {
  244. schemaObjectInfo.type = schemaType;
  245. schemaObjectInfo.schema = schema;
  246. }
  247. else
  248. {
  249. schemaObjects.Add(currentTypeName, new SchemaObjectInfo(schemaType, null, schema, null));
  250. }
  251. XmlQualifiedName baseTypeName = GetBaseTypeName(schemaType);
  252. if (baseTypeName != null)
  253. {
  254. SchemaObjectInfo baseTypeInfo;
  255. if (schemaObjects.TryGetValue(baseTypeName, out baseTypeInfo))
  256. {
  257. if (baseTypeInfo.knownTypes == null)
  258. {
  259. baseTypeInfo.knownTypes = new List<XmlSchemaType>();
  260. }
  261. }
  262. else
  263. {
  264. baseTypeInfo = new SchemaObjectInfo(null, null, null, new List<XmlSchemaType>());
  265. schemaObjects.Add(baseTypeName, baseTypeInfo);
  266. }
  267. baseTypeInfo.knownTypes.Add(schemaType);
  268. }
  269. }
  270. }
  271. foreach (XmlSchemaObject schemaObj in schema.Elements.Values)
  272. {
  273. XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
  274. if (schemaElement != null)
  275. {
  276. XmlQualifiedName currentElementName = new XmlQualifiedName(schemaElement.Name, schema.TargetNamespace);
  277. SchemaObjectInfo schemaObjectInfo;
  278. if (schemaObjects.TryGetValue(currentElementName, out schemaObjectInfo))
  279. {
  280. schemaObjectInfo.element = schemaElement;
  281. schemaObjectInfo.schema = schema;
  282. }
  283. else
  284. {
  285. schemaObjects.Add(currentElementName, new SchemaObjectInfo(null, schemaElement, schema, null));
  286. }
  287. }
  288. }
  289. }
  290. }
  291. return schemaObjects;
  292. }
  293. XmlQualifiedName GetBaseTypeName(XmlSchemaType type)
  294. {
  295. XmlQualifiedName baseTypeName = null;
  296. XmlSchemaComplexType complexType = type as XmlSchemaComplexType;
  297. if (complexType != null)
  298. {
  299. if (complexType.ContentModel != null)
  300. {
  301. XmlSchemaComplexContent complexContent = complexType.ContentModel as XmlSchemaComplexContent;
  302. if (complexContent != null)
  303. {
  304. XmlSchemaComplexContentExtension extension = complexContent.Content as XmlSchemaComplexContentExtension;
  305. if (extension != null)
  306. baseTypeName = extension.BaseTypeName;
  307. }
  308. }
  309. }
  310. return baseTypeName;
  311. }
  312. List<XmlSchemaRedefine> CreateRedefineList()
  313. {
  314. List<XmlSchemaRedefine> list = new List<XmlSchemaRedefine>();
  315. ICollection schemaList = schemaSet.Schemas();
  316. foreach (object schemaObj in schemaList)
  317. {
  318. XmlSchema schema = schemaObj as XmlSchema;
  319. if (schema == null)
  320. continue;
  321. foreach (XmlSchemaExternal ext in schema.Includes)
  322. {
  323. XmlSchemaRedefine redefine = ext as XmlSchemaRedefine;
  324. if (redefine != null)
  325. list.Add(redefine);
  326. }
  327. }
  328. return list;
  329. }
  330. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
  331. Safe = "Called during schema import/code generation.")]
  332. [SecuritySafeCritical]
  333. DataContract ImportAnonymousGlobalElement(XmlSchemaElement element, XmlQualifiedName typeQName, string ns)
  334. {
  335. DataContract contract = ImportAnonymousElement(element, typeQName);
  336. XmlDataContract xmlDataContract = contract as XmlDataContract;
  337. if (xmlDataContract != null)
  338. {
  339. xmlDataContract.SetTopLevelElementName(new XmlQualifiedName(element.Name, ns));
  340. xmlDataContract.IsTopLevelElementNullable = element.IsNillable;
  341. }
  342. return contract;
  343. }
  344. DataContract ImportAnonymousElement(XmlSchemaElement element, XmlQualifiedName typeQName)
  345. {
  346. if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) != null)
  347. {
  348. for (int i = 1;; i++)
  349. {
  350. typeQName = new XmlQualifiedName(typeQName.Name + i.ToString(NumberFormatInfo.InvariantInfo), typeQName.Namespace);
  351. if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) == null)
  352. break;
  353. if (i == Int32.MaxValue)
  354. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, element.Name)));
  355. }
  356. }
  357. if (element.SchemaType == null)
  358. return ImportType(SchemaExporter.AnytypeQualifiedName);
  359. else
  360. return ImportType(element.SchemaType, typeQName, true/*isAnonymous*/);
  361. }
  362. DataContract ImportType(XmlQualifiedName typeName)
  363. {
  364. DataContract dataContract = DataContract.GetBuiltInDataContract(typeName.Name, typeName.Namespace);
  365. if (dataContract == null)
  366. {
  367. XmlSchemaType type = SchemaHelper.GetSchemaType(SchemaObjects, typeName);
  368. if (type == null)
  369. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SpecifiedTypeNotFoundInSchema, typeName.Name, typeName.Namespace)));
  370. dataContract = ImportType(type);
  371. }
  372. if (IsObjectContract(dataContract))
  373. needToImportKnownTypesForObject = true;
  374. return dataContract;
  375. }
  376. DataContract ImportType(XmlSchemaType type)
  377. {
  378. return ImportType(type, type.QualifiedName, false/*isAnonymous*/);
  379. }
  380. DataContract ImportType(XmlSchemaType type, XmlQualifiedName typeName, bool isAnonymous)
  381. {
  382. DataContract dataContract = dataContractSet[typeName];
  383. if (dataContract != null)
  384. return dataContract;
  385. InvalidDataContractException invalidContractException;
  386. try
  387. {
  388. foreach (XmlSchemaRedefine redefine in RedefineList)
  389. {
  390. if (redefine.SchemaTypes[typeName] != null)
  391. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RedefineNotSupported));
  392. }
  393. if (type is XmlSchemaSimpleType)
  394. {
  395. XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)type;
  396. XmlSchemaSimpleTypeContent content = simpleType.Content;
  397. if (content is XmlSchemaSimpleTypeUnion)
  398. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeUnionNotSupported));
  399. else if (content is XmlSchemaSimpleTypeList)
  400. dataContract = ImportFlagsEnum(typeName, (XmlSchemaSimpleTypeList)content, simpleType.Annotation);
  401. else if (content is XmlSchemaSimpleTypeRestriction)
  402. {
  403. XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
  404. if (CheckIfEnum(restriction))
  405. {
  406. dataContract = ImportEnum(typeName, restriction, false /*isFlags*/, simpleType.Annotation);
  407. }
  408. else
  409. {
  410. dataContract = ImportSimpleTypeRestriction(typeName, restriction);
  411. if (dataContract.IsBuiltInDataContract && !isAnonymous)
  412. {
  413. dataContractSet.InternalAdd(typeName, dataContract);
  414. }
  415. }
  416. }
  417. }
  418. else if (type is XmlSchemaComplexType)
  419. {
  420. XmlSchemaComplexType complexType = (XmlSchemaComplexType)type;
  421. if (complexType.ContentModel == null)
  422. {
  423. CheckComplexType(typeName, complexType);
  424. dataContract = ImportType(typeName, complexType.Particle, complexType.Attributes, complexType.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
  425. }
  426. else
  427. {
  428. XmlSchemaContentModel contentModel = complexType.ContentModel;
  429. if (contentModel is XmlSchemaSimpleContent)
  430. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleContentNotSupported));
  431. else if (contentModel is XmlSchemaComplexContent)
  432. {
  433. XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)contentModel;
  434. if (complexContent.IsMixed)
  435. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
  436. if (complexContent.Content is XmlSchemaComplexContentExtension)
  437. {
  438. XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)complexContent.Content;
  439. dataContract = ImportType(typeName, extension.Particle, extension.Attributes, extension.AnyAttribute, extension.BaseTypeName, complexType.Annotation);
  440. }
  441. else if (complexContent.Content is XmlSchemaComplexContentRestriction)
  442. {
  443. XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)complexContent.Content;
  444. XmlQualifiedName baseTypeName = restriction.BaseTypeName;
  445. if (baseTypeName == SchemaExporter.AnytypeQualifiedName)
  446. dataContract = ImportType(typeName, restriction.Particle, restriction.Attributes, restriction.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
  447. else
  448. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ComplexTypeRestrictionNotSupported));
  449. }
  450. }
  451. }
  452. }
  453. if (dataContract == null)
  454. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, String.Empty);
  455. if (type.QualifiedName != XmlQualifiedName.Empty)
  456. ImportTopLevelElement(typeName);
  457. ImportDataContractExtension(type, dataContract);
  458. ImportGenericInfo(type, dataContract);
  459. ImportKnownTypes(typeName);
  460. return dataContract;
  461. }
  462. catch (InvalidDataContractException e)
  463. {
  464. invalidContractException = e;
  465. }
  466. // Execution gets to this point if InvalidDataContractException was thrown
  467. if (importXmlDataType)
  468. {
  469. RemoveFailedContract(typeName);
  470. return ImportXmlDataType(typeName, type, isAnonymous);
  471. }
  472. Type referencedType;
  473. if (dataContractSet.TryGetReferencedType(typeName, dataContract, out referencedType)
  474. || (string.IsNullOrEmpty(type.Name) && dataContractSet.TryGetReferencedType(ImportActualType(type.Annotation, typeName, typeName), dataContract, out referencedType)))
  475. {
  476. if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
  477. {
  478. RemoveFailedContract(typeName);
  479. return ImportXmlDataType(typeName, type, isAnonymous);
  480. }
  481. }
  482. XmlDataContract specialContract = ImportSpecialXmlDataType(type, isAnonymous);
  483. if (specialContract != null)
  484. {
  485. this.dataContractSet.Remove(typeName);
  486. return specialContract;
  487. }
  488. throw invalidContractException;
  489. }
  490. private void RemoveFailedContract(XmlQualifiedName typeName)
  491. {
  492. ClassDataContract oldContract = this.dataContractSet[typeName] as ClassDataContract;
  493. this.dataContractSet.Remove(typeName);
  494. if (oldContract != null)
  495. {
  496. ClassDataContract ancestorDataContract = oldContract.BaseContract;
  497. while (ancestorDataContract != null)
  498. {
  499. ancestorDataContract.KnownDataContracts.Remove(typeName);
  500. ancestorDataContract = ancestorDataContract.BaseContract;
  501. }
  502. if (dataContractSet.KnownTypesForObject != null)
  503. dataContractSet.KnownTypesForObject.Remove(typeName);
  504. }
  505. }
  506. bool CheckIfEnum(XmlSchemaSimpleTypeRestriction restriction)
  507. {
  508. foreach (XmlSchemaFacet facet in restriction.Facets)
  509. {
  510. if (!(facet is XmlSchemaEnumerationFacet))
  511. return false;
  512. }
  513. XmlQualifiedName expectedBase = SchemaExporter.StringQualifiedName;
  514. if (restriction.BaseTypeName != XmlQualifiedName.Empty)
  515. {
  516. return ((restriction.BaseTypeName == expectedBase && restriction.Facets.Count > 0) || ImportType(restriction.BaseTypeName) is EnumDataContract);
  517. }
  518. else if (restriction.BaseType != null)
  519. {
  520. DataContract baseContract = ImportType(restriction.BaseType);
  521. return (baseContract.StableName == expectedBase || baseContract is EnumDataContract);
  522. }
  523. return false;
  524. }
  525. bool CheckIfCollection(XmlSchemaSequence rootSequence)
  526. {
  527. if (rootSequence.Items == null || rootSequence.Items.Count == 0)
  528. return false;
  529. RemoveOptionalUnknownSerializationElements(rootSequence.Items);
  530. if (rootSequence.Items.Count != 1)
  531. return false;
  532. XmlSchemaObject o = rootSequence.Items[0];
  533. if (!(o is XmlSchemaElement))
  534. return false;
  535. XmlSchemaElement localElement = (XmlSchemaElement)o;
  536. return (localElement.MaxOccursString == Globals.OccursUnbounded || localElement.MaxOccurs > 1);
  537. }
  538. bool CheckIfISerializable(XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
  539. {
  540. if (rootSequence.Items == null || rootSequence.Items.Count == 0)
  541. return false;
  542. RemoveOptionalUnknownSerializationElements(rootSequence.Items);
  543. if (attributes == null || attributes.Count == 0)
  544. return false;
  545. return (rootSequence.Items.Count == 1 && rootSequence.Items[0] is XmlSchemaAny);
  546. }
  547. [Fx.Tag.SecurityNote(Critical = "Initializes critical static fields.",
  548. Safe = "Doesn't leak anything.")]
  549. [SecuritySafeCritical]
  550. void RemoveOptionalUnknownSerializationElements(XmlSchemaObjectCollection items)
  551. {
  552. for (int i = 0; i < items.Count; i++)
  553. {
  554. XmlSchemaElement element = items[i] as XmlSchemaElement;
  555. if (element != null && element.RefName != null &&
  556. element.RefName.Namespace == Globals.SerializationNamespace &&
  557. element.MinOccurs == 0)
  558. {
  559. if (serializationSchemaElements == null)
  560. {
  561. XmlSchema serializationSchema = XmlSchema.Read(XmlReader.Create(new StringReader(Globals.SerializationSchema)), null);
  562. serializationSchemaElements = new Hashtable();
  563. foreach (XmlSchemaObject schemaObject in serializationSchema.Items)
  564. {
  565. XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement;
  566. if (schemaElement != null)
  567. serializationSchemaElements.Add(schemaElement.Name, schemaElement);
  568. }
  569. }
  570. if (!serializationSchemaElements.ContainsKey(element.RefName.Name))
  571. {
  572. items.RemoveAt(i);
  573. i--;
  574. }
  575. }
  576. }
  577. }
  578. DataContract ImportType(XmlQualifiedName typeName, XmlSchemaParticle rootParticle, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation)
  579. {
  580. DataContract dataContract = null;
  581. bool isDerived = (baseTypeName != null);
  582. bool isReference;
  583. ImportAttributes(typeName, attributes, anyAttribute, out isReference);
  584. if (rootParticle == null)
  585. dataContract = ImportClass(typeName, new XmlSchemaSequence(), baseTypeName, annotation, isReference);
  586. else if (!(rootParticle is XmlSchemaSequence))
  587. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootParticleMustBeSequence));
  588. else
  589. {
  590. XmlSchemaSequence rootSequence = (XmlSchemaSequence)rootParticle;
  591. if (rootSequence.MinOccurs != 1)
  592. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMustBeRequired));
  593. if (rootSequence.MaxOccurs != 1)
  594. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMaxOccursMustBe));
  595. if (!isDerived && CheckIfCollection(rootSequence))
  596. dataContract = ImportCollection(typeName, rootSequence, attributes, annotation, isReference);
  597. else if (CheckIfISerializable(rootSequence, attributes))
  598. dataContract = ImportISerializable(typeName, rootSequence, baseTypeName, attributes, annotation);
  599. else
  600. dataContract = ImportClass(typeName, rootSequence, baseTypeName, annotation, isReference);
  601. }
  602. return dataContract;
  603. }
  604. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
  605. Safe = "Called during schema import/code generation.")]
  606. [SecuritySafeCritical]
  607. ClassDataContract ImportClass(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation, bool isReference)
  608. {
  609. ClassDataContract dataContract = new ClassDataContract();
  610. dataContract.StableName = typeName;
  611. AddDataContract(dataContract);
  612. dataContract.IsValueType = IsValueType(typeName, annotation);
  613. dataContract.IsReference = isReference;
  614. if (baseTypeName != null)
  615. {
  616. ImportBaseContract(baseTypeName, dataContract);
  617. if (dataContract.BaseContract.IsISerializable)
  618. {
  619. if (IsISerializableDerived(typeName, rootSequence))
  620. dataContract.IsISerializable = true;
  621. else
  622. ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.DerivedTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
  623. }
  624. if (dataContract.BaseContract.IsReference)
  625. {
  626. dataContract.IsReference = true;
  627. }
  628. }
  629. if (!dataContract.IsISerializable)
  630. {
  631. dataContract.Members = new List<DataMember>();
  632. RemoveOptionalUnknownSerializationElements(rootSequence.Items);
  633. for (int memberIndex = 0; memberIndex < rootSequence.Items.Count; memberIndex++)
  634. {
  635. XmlSchemaElement element = rootSequence.Items[memberIndex] as XmlSchemaElement;
  636. if (element == null)
  637. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MustContainOnlyLocalElements));
  638. ImportClassMember(element, dataContract);
  639. }
  640. }
  641. return dataContract;
  642. }
  643. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
  644. Safe = "Called during schema import/code generation.")]
  645. [SecuritySafeCritical]
  646. DataContract ImportXmlDataType(XmlQualifiedName typeName, XmlSchemaType xsdType, bool isAnonymous)
  647. {
  648. DataContract dataContract = dataContractSet[typeName];
  649. if (dataContract != null)
  650. return dataContract;
  651. XmlDataContract xmlDataContract = ImportSpecialXmlDataType(xsdType, isAnonymous);
  652. if (xmlDataContract != null)
  653. return xmlDataContract;
  654. xmlDataContract = new XmlDataContract();
  655. xmlDataContract.StableName = typeName;
  656. xmlDataContract.IsValueType = false;
  657. AddDataContract(xmlDataContract);
  658. if (xsdType != null)
  659. {
  660. ImportDataContractExtension(xsdType, xmlDataContract);
  661. xmlDataContract.IsValueType = IsValueType(typeName, xsdType.Annotation);
  662. xmlDataContract.IsTypeDefinedOnImport = true;
  663. xmlDataContract.XsdType = isAnonymous ? xsdType : null;
  664. xmlDataContract.HasRoot = !IsXmlAnyElementType(xsdType as XmlSchemaComplexType);
  665. }
  666. else
  667. {
  668. //Value type can be used by both nillable and non-nillable elements but reference type cannot be used by non nillable elements
  669. xmlDataContract.IsValueType = true;
  670. xmlDataContract.IsTypeDefinedOnImport = false;
  671. xmlDataContract.HasRoot = true;
  672. if (DiagnosticUtility.ShouldTraceVerbose)
  673. {
  674. TraceUtility.Trace(TraceEventType.Verbose, TraceCode.XsdImportAnnotationFailed,
  675. SR.GetString(SR.TraceCodeXsdImportAnnotationFailed), new StringTraceRecord("Type", typeName.Namespace + ":" + typeName.Name));
  676. }
  677. }
  678. if (!isAnonymous)
  679. {
  680. bool isNullable;
  681. xmlDataContract.SetTopLevelElementName(SchemaHelper.GetGlobalElementDeclaration(schemaSet, typeName, out isNullable));
  682. xmlDataContract.IsTopLevelElementNullable = isNullable;
  683. }
  684. return xmlDataContract;
  685. }
  686. private XmlDataContract ImportSpecialXmlDataType(XmlSchemaType xsdType, bool isAnonymous)
  687. {
  688. if (!isAnonymous)
  689. return null;
  690. XmlSchemaComplexType complexType = xsdType as XmlSchemaComplexType;
  691. if (complexType == null)
  692. return null;
  693. if (IsXmlAnyElementType(complexType))
  694. {
  695. //check if the type is XElement
  696. XmlQualifiedName xlinqTypeName = new XmlQualifiedName("XElement", "http://schemas.datacontract.org/2004/07/System.Xml.Linq");
  697. Type referencedType;
  698. if (dataContractSet.TryGetReferencedType(xlinqTypeName, null, out referencedType)
  699. && Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
  700. {
  701. XmlDataContract xmlDataContract = new XmlDataContract(referencedType);
  702. AddDataContract(xmlDataContract);
  703. return xmlDataContract;
  704. }
  705. //otherwise, assume XmlElement
  706. return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlElement);
  707. }
  708. if (IsXmlAnyType(complexType))
  709. return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlNodeArray);
  710. return null;
  711. }
  712. bool IsXmlAnyElementType(XmlSchemaComplexType xsdType)
  713. {
  714. if (xsdType == null)
  715. return false;
  716. XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
  717. if (sequence == null)
  718. return false;
  719. if (sequence.Items == null || sequence.Items.Count != 1)
  720. return false;
  721. XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
  722. if (any == null || any.Namespace != null)
  723. return false;
  724. if (xsdType.AnyAttribute != null || (xsdType.Attributes != null && xsdType.Attributes.Count > 0))
  725. return false;
  726. return true;
  727. }
  728. bool IsXmlAnyType(XmlSchemaComplexType xsdType)
  729. {
  730. if (xsdType == null)
  731. return false;
  732. XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
  733. if (sequence == null)
  734. return false;
  735. if (sequence.Items == null || sequence.Items.Count != 1)
  736. return false;
  737. XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
  738. if (any == null || any.Namespace != null)
  739. return false;
  740. if (any.MaxOccurs != Decimal.MaxValue)
  741. return false;
  742. if (xsdType.AnyAttribute == null || xsdType.Attributes.Count > 0)
  743. return false;
  744. return true;
  745. }
  746. bool IsValueType(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
  747. {
  748. string isValueTypeInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsValueTypeName));
  749. if (isValueTypeInnerText != null)
  750. {
  751. try
  752. {
  753. return XmlConvert.ToBoolean(isValueTypeInnerText);
  754. }
  755. catch (FormatException fe)
  756. {
  757. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsValueTypeFormattedIncorrectly, isValueTypeInnerText, fe.Message));
  758. }
  759. }
  760. return false;
  761. }
  762. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
  763. Safe = "Called during schema import/code generation.")]
  764. [SecuritySafeCritical]
  765. ClassDataContract ImportISerializable(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation)
  766. {
  767. ClassDataContract dataContract = new ClassDataContract();
  768. dataContract.StableName = typeName;
  769. dataContract.IsISerializable = true;
  770. AddDataContract(dataContract);
  771. dataContract.IsValueType = IsValueType(typeName, annotation);
  772. if (baseTypeName == null)
  773. CheckISerializableBase(typeName, rootSequence, attributes);
  774. else
  775. {
  776. ImportBaseContract(baseTypeName, dataContract);
  777. if (!dataContract.BaseContract.IsISerializable)
  778. ThrowISerializableTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.BaseTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
  779. if (!IsISerializableDerived(typeName, rootSequence))
  780. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDerivedContainsOneOrMoreItems));
  781. }
  782. return dataContract;
  783. }
  784. void CheckISerializableBase(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
  785. {
  786. if (rootSequence == null)
  787. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
  788. if (rootSequence.Items == null || rootSequence.Items.Count < 1)
  789. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
  790. else if (rootSequence.Items.Count > 1)
  791. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableContainsMoreThanOneItems));
  792. XmlSchemaObject o = rootSequence.Items[0];
  793. if (!(o is XmlSchemaAny))
  794. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
  795. XmlSchemaAny wildcard = (XmlSchemaAny)o;
  796. XmlSchemaAny iSerializableWildcardElement = SchemaExporter.ISerializableWildcardElement;
  797. if (wildcard.MinOccurs != iSerializableWildcardElement.MinOccurs)
  798. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMinOccursMustBe, iSerializableWildcardElement.MinOccurs));
  799. if (wildcard.MaxOccursString != iSerializableWildcardElement.MaxOccursString)
  800. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMaxOccursMustBe, iSerializableWildcardElement.MaxOccursString));
  801. if (wildcard.Namespace != iSerializableWildcardElement.Namespace)
  802. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardNamespaceInvalid, iSerializableWildcardElement.Namespace));
  803. if (wildcard.ProcessContents != iSerializableWildcardElement.ProcessContents)
  804. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardProcessContentsInvalid, iSerializableWildcardElement.ProcessContents));
  805. XmlQualifiedName factoryTypeAttributeRefName = SchemaExporter.ISerializableFactoryTypeAttribute.RefName;
  806. bool containsFactoryTypeAttribute = false;
  807. if (attributes != null)
  808. {
  809. for (int i = 0; i < attributes.Count; i++)
  810. {
  811. o = attributes[i];
  812. if (o is XmlSchemaAttribute)
  813. {
  814. if (((XmlSchemaAttribute)o).RefName == factoryTypeAttributeRefName)
  815. {
  816. containsFactoryTypeAttribute = true;
  817. break;
  818. }
  819. }
  820. }
  821. }
  822. if (!containsFactoryTypeAttribute)
  823. ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableMustRefFactoryTypeAttribute, factoryTypeAttributeRefName.Name, factoryTypeAttributeRefName.Namespace));
  824. }
  825. bool IsISerializableDerived(XmlQualifiedName typeName, XmlSchemaSequence rootSequence)
  826. {
  827. return (rootSequence == null || rootSequence.Items == null || rootSequence.Items.Count == 0);
  828. }
  829. [Fx.Tag.SecurityNote(Critical = "Sets critical BaseContract property on ClassDataContract.",
  830. Safe = "Called during schema import/code generation.")]
  831. [SecuritySafeCritical]
  832. void ImportBaseContract(XmlQualifiedName baseTypeName, ClassDataContract dataContract)
  833. {
  834. ClassDataContract baseContract = ImportType(baseTypeName) as ClassDataContract;
  835. if (baseContract == null)
  836. ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(dataContract.IsISerializable ? SR.InvalidISerializableDerivation : SR.InvalidClassDerivation, baseTypeName.Name, baseTypeName.Namespace));
  837. // Note: code ignores IsValueType annotation if derived type exists
  838. if (baseContract.IsValueType)
  839. baseContract.IsValueType = false;
  840. ClassDataContract ancestorDataContract = baseContract;
  841. while (ancestorDataContract != null)
  842. {
  843. DataContractDictionary knownDataContracts = ancestorDataContract.KnownDataContracts;
  844. if (knownDataContracts == null)
  845. {
  846. knownDataContracts = new DataContractDictionary();
  847. ancestorDataContract.KnownDataContracts = knownDataContracts;
  848. }
  849. knownDataContracts.Add(dataContract.StableName, dataContract);
  850. ancestorDataContract = ancestorDataContract.BaseContract;
  851. }
  852. dataContract.BaseContract = baseContract;
  853. }
  854. void ImportTopLevelElement(XmlQualifiedName typeName)
  855. {
  856. XmlSchemaElement topLevelElement = SchemaHelper.GetSchemaElement(SchemaObjects, typeName);
  857. // Top level element of same name is not required, but is validated if it is present
  858. if (topLevelElement == null)
  859. return;
  860. else
  861. {
  862. XmlQualifiedName elementTypeName = topLevelElement.SchemaTypeName;
  863. if (elementTypeName.IsEmpty)
  864. {
  865. if (topLevelElement.SchemaType != null)
  866. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnonymousTypeNotSupported, typeName.Name, typeName.Namespace));
  867. else
  868. elementTypeName = SchemaExporter.AnytypeQualifiedName;
  869. }
  870. if (elementTypeName != typeName)
  871. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TopLevelElementRepresentsDifferentType, topLevelElement.SchemaTypeName.Name, topLevelElement.SchemaTypeName.Namespace));
  872. CheckIfElementUsesUnsupportedConstructs(typeName, topLevelElement);
  873. }
  874. }
  875. void ImportClassMember(XmlSchemaElement element, ClassDataContract dataContract)
  876. {
  877. XmlQualifiedName typeName = dataContract.StableName;
  878. if (element.MinOccurs > 1)
  879. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMinOccursMustBe, element.Name));
  880. if (element.MaxOccurs != 1)
  881. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMaxOccursMustBe, element.Name));
  882. DataContract memberTypeContract = null;
  883. string memberName = element.Name;
  884. bool memberIsRequired = (element.MinOccurs > 0);
  885. bool memberIsNullable = element.IsNillable;
  886. bool memberEmitDefaultValue;
  887. int memberOrder = 0;
  888. XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
  889. if (elementForm != XmlSchemaForm.Qualified)
  890. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FormMustBeQualified, element.Name));
  891. CheckIfElementUsesUnsupportedConstructs(typeName, element);
  892. if (element.SchemaTypeName.IsEmpty)
  893. {
  894. if (element.SchemaType != null)
  895. memberTypeContract = ImportAnonymousElement(element, new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace));
  896. else if (!element.RefName.IsEmpty)
  897. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
  898. else
  899. memberTypeContract = ImportType(SchemaExporter.AnytypeQualifiedName);
  900. }
  901. else
  902. {
  903. XmlQualifiedName memberTypeName = ImportActualType(element.Annotation, element.SchemaTypeName, typeName);
  904. memberTypeContract = ImportType(memberTypeName);
  905. if (IsObjectContract(memberTypeContract))
  906. needToImportKnownTypesForObject = true;
  907. }
  908. bool? emitDefaultValueFromAnnotation = ImportEmitDefaultValue(element.Annotation, typeName);
  909. if (!memberTypeContract.IsValueType && !memberIsNullable)
  910. {
  911. if (emitDefaultValueFromAnnotation != null && emitDefaultValueFromAnnotation.Value)
  912. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidEmitDefaultAnnotation, memberName, typeName.Name, typeName.Namespace)));
  913. memberEmitDefaultValue = false;
  914. }
  915. else
  916. memberEmitDefaultValue = emitDefaultValueFromAnnotation != null ? emitDefaultValueFromAnnotation.Value : Globals.DefaultEmitDefaultValue;
  917. int prevMemberIndex = dataContract.Members.Count - 1;
  918. if (prevMemberIndex >= 0)
  919. {
  920. DataMember prevMember = dataContract.Members[prevMemberIndex];
  921. if (prevMember.Order > Globals.DefaultOrder)
  922. memberOrder = dataContract.Members.Count;
  923. DataMember currentMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
  924. int compare = ClassDataContract.DataMemberComparer.Singleton.Compare(prevMember, currentMember);
  925. if (compare == 0)
  926. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateElementNames, memberName));
  927. else if (compare > 0)
  928. memberOrder = dataContract.Members.Count;
  929. }
  930. DataMember dataMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
  931. XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
  932. dataContractSet.SetSurrogateData(dataMember, ImportSurrogateData(ImportAnnotation(element.Annotation, surrogateDataAnnotationName), surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace));
  933. dataContract.Members.Add(dataMember);
  934. }
  935. private bool? ImportEmitDefaultValue(XmlSchemaAnnotation annotation, XmlQualifiedName typeName)
  936. {
  937. XmlElement defaultValueElement = ImportAnnotation(annotation, SchemaExporter.DefaultValueAnnotation);
  938. if (defaultValueElement == null)
  939. return null;
  940. XmlNode emitDefaultValueAttribute = defaultValueElement.Attributes.GetNamedItem(Globals.EmitDefaultValueAttribute);
  941. string emitDefaultValueString = (emitDefaultValueAttribute == null) ? null : emitDefaultValueAttribute.Value;
  942. if (emitDefaultValueString == null)
  943. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.DefaultValueAnnotation.Name, typeName.Name, typeName.Namespace, Globals.EmitDefaultValueAttribute)));
  944. return XmlConvert.ToBoolean(emitDefaultValueString);
  945. }
  946. internal static XmlQualifiedName ImportActualType(XmlSchemaAnnotation annotation, XmlQualifiedName defaultTypeName, XmlQualifiedName typeName)
  947. {
  948. XmlElement actualTypeElement = ImportAnnotation(annotation, SchemaExporter.ActualTypeAnnotationName);
  949. if (actualTypeElement == null)
  950. return defaultTypeName;
  951. XmlNode nameAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNameAttribute);
  952. string name = (nameAttribute == null) ? null : nameAttribute.Value;
  953. if (name == null)
  954. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNameAttribute)));
  955. XmlNode nsAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNamespaceAttribute);
  956. string ns = (nsAttribute == null) ? null : nsAttribute.Value;
  957. if (ns == null)
  958. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNamespaceAttribute)));
  959. return new XmlQualifiedName(name, ns);
  960. }
  961. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on CollectionDataContract.",
  962. Safe = "Called during schema import/code generation.")]
  963. [SecuritySafeCritical]
  964. CollectionDataContract ImportCollection(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation, bool isReference)
  965. {
  966. CollectionDataContract dataContract = new CollectionDataContract(CollectionKind.Array);
  967. dataContract.StableName = typeName;
  968. AddDataContract(dataContract);
  969. dataContract.IsReference = isReference;
  970. // CheckIfCollection has already checked if sequence contains exactly one item with maxOccurs="unbounded" or maxOccurs > 1
  971. XmlSchemaElement element = (XmlSchemaElement)rootSequence.Items[0];
  972. dataContract.IsItemTypeNullable = element.IsNillable;
  973. dataContract.ItemName = element.Name;
  974. XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
  975. if (elementForm != XmlSchemaForm.Qualified)
  976. ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ArrayItemFormMustBe, element.Name));
  977. CheckIfElementUsesUnsupportedConstructs(typeName, element);
  978. if (element.SchemaTypeName.IsEmpty)
  979. {
  980. if (element.SchemaType != null)
  981. {
  982. XmlQualifiedName shortName = new XmlQualifiedName(element.Name, typeName.Namespace);
  983. DataContract contract = dataContractSet[shortName];
  984. if (contract == null)
  985. {
  986. dataContract.ItemContract = ImportAnonymousElement(element, shortName);
  987. }
  988. else
  989. {
  990. XmlQualifiedName fullName = new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace);
  991. dataContract.ItemContract = ImportAnonymousElement(element, fullName);
  992. }
  993. }
  994. else if (!element.RefName.IsEmpty)
  995. ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
  996. else
  997. dataContract.ItemContract = ImportType(SchemaExporter.AnytypeQualifiedName);
  998. }
  999. else
  1000. {
  1001. dataContract.ItemContract = ImportType(element.SchemaTypeName);
  1002. }
  1003. if (IsDictionary(typeName, annotation))
  1004. {
  1005. ClassDataContract keyValueContract = dataContract.ItemContract as ClassDataContract;
  1006. DataMember key = null, value = null;
  1007. if (keyValueContract == null || keyValueContract.Members == null || keyValueContract.Members.Count != 2
  1008. || !(key = keyValueContract.Members[0]).IsRequired || !(value = keyValueContract.Members[1]).IsRequired)
  1009. {
  1010. ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueType, element.Name));
  1011. }
  1012. if (keyValueContract.Namespace != dataContract.Namespace)
  1013. {
  1014. ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueTypeNamespace, element.Name, keyValueContract.Namespace));
  1015. }
  1016. keyValueContract.IsValueType = true;
  1017. dataContract.KeyName = key.Name;
  1018. dataContract.ValueName = value.Name;
  1019. if (element.SchemaType != null)
  1020. {
  1021. dataContractSet.Remove(keyValueContract.StableName);
  1022. GenericInfo genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfKeyValue), Globals.TypeOfKeyValue.FullName);
  1023. genericInfo.Add(GetGenericInfoForDataMember(key));
  1024. genericInfo.Add(GetGenericInfoForDataMember(value));
  1025. genericInfo.AddToLevel(0, 2);
  1026. dataContract.ItemContract.StableName = new XmlQualifiedName(genericInfo.GetExpandedStableName().Name, typeName.Namespace);
  1027. }
  1028. }
  1029. return dataContract;
  1030. }
  1031. GenericInfo GetGenericInfoForDataMember(DataMember dataMember)
  1032. {
  1033. GenericInfo genericInfo = null;
  1034. if (dataMember.MemberTypeContract.IsValueType && dataMember.IsNullable)
  1035. {
  1036. genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfNullable), Globals.TypeOfNullable.FullName);
  1037. genericInfo.Add(new GenericInfo(dataMember.MemberTypeContract.StableName, null));
  1038. }
  1039. else
  1040. {
  1041. genericInfo = new GenericInfo(dataMember.MemberTypeContract.StableName, null);
  1042. }
  1043. return genericInfo;
  1044. }
  1045. bool IsDictionary(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
  1046. {
  1047. string isDictionaryInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsDictionaryAnnotationName));
  1048. if (isDictionaryInnerText != null)
  1049. {
  1050. try
  1051. {
  1052. return XmlConvert.ToBoolean(isDictionaryInnerText);
  1053. }
  1054. catch (FormatException fe)
  1055. {
  1056. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsDictionaryFormattedIncorrectly, isDictionaryInnerText, fe.Message));
  1057. }
  1058. }
  1059. return false;
  1060. }
  1061. EnumDataContract ImportFlagsEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeList list, XmlSchemaAnnotation annotation)
  1062. {
  1063. XmlSchemaSimpleType anonymousType = list.ItemType;
  1064. if (anonymousType == null)
  1065. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListMustContainAnonymousType));
  1066. XmlSchemaSimpleTypeContent content = anonymousType.Content;
  1067. if (content is XmlSchemaSimpleTypeUnion)
  1068. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumUnionInAnonymousTypeNotSupported));
  1069. else if (content is XmlSchemaSimpleTypeList)
  1070. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListInAnonymousTypeNotSupported));
  1071. else if (content is XmlSchemaSimpleTypeRestriction)
  1072. {
  1073. XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
  1074. if (CheckIfEnum(restriction))
  1075. return ImportEnum(typeName, restriction, true /*isFlags*/, annotation);
  1076. else
  1077. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumRestrictionInvalid));
  1078. }
  1079. return null;
  1080. }
  1081. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on EnumDataContract.",
  1082. Safe = "Called during schema import/code generation.")]
  1083. [SecuritySafeCritical]
  1084. EnumDataContract ImportEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction, bool isFlags, XmlSchemaAnnotation annotation)
  1085. {
  1086. EnumDataContract dataContract = new EnumDataContract();
  1087. dataContract.StableName = typeName;
  1088. dataContract.BaseContractName = ImportActualType(annotation, SchemaExporter.DefaultEnumBaseTypeName, typeName);
  1089. dataContract.IsFlags = isFlags;
  1090. AddDataContract(dataContract);
  1091. // CheckIfEnum has already checked if baseType of restriction is string
  1092. dataContract.Values = new List<long>();
  1093. dataContract.Members = new List<DataMember>();
  1094. foreach (XmlSchemaFacet facet in restriction.Facets)
  1095. {
  1096. XmlSchemaEnumerationFacet enumFacet = facet as XmlSchemaEnumerationFacet;
  1097. if (enumFacet == null)
  1098. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumOnlyEnumerationFacetsSupported));
  1099. if (enumFacet.Value == null)
  1100. ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumEnumerationFacetsMustHaveValue));
  1101. string valueInnerText = GetInnerText(typeName, ImportAnnotation(enumFacet.Annotation, SchemaExporter.EnumerationValueAnnotationName));
  1102. if (valueInnerText == null)
  1103. dataContract.Values.Add(SchemaExporter.GetDefaultEnumValue(isFlags, dataContract.Members.Count));
  1104. else
  1105. dataContract.Values.Add(dataContract.GetEnumValueFromString(valueInnerText));
  1106. DataMember dataMember = new DataMember(enumFacet.Value);
  1107. dataContract.Members.Add(dataMember);
  1108. }
  1109. return dataContract;
  1110. }
  1111. DataContract ImportSimpleTypeRestriction(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction)
  1112. {
  1113. DataContract dataContract = null;
  1114. if (!restriction.BaseTypeName.IsEmpty)
  1115. dataContract = ImportType(restriction.BaseTypeName);
  1116. else if (restriction.BaseType != null)
  1117. dataContract = ImportType(restriction.BaseType);
  1118. else
  1119. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeRestrictionDoesNotSpecifyBase));
  1120. return dataContract;
  1121. }
  1122. void ImportDataContractExtension(XmlSchemaType type, DataContract dataContract)
  1123. {
  1124. if (type.Annotation == null || type.Annotation.Items == null)
  1125. return;
  1126. foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
  1127. {
  1128. XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
  1129. if (appInfo == null)
  1130. continue;
  1131. if (appInfo.Markup != null)
  1132. {
  1133. foreach (XmlNode xmlNode in appInfo.Markup)
  1134. {
  1135. XmlElement typeElement = xmlNode as XmlElement;
  1136. XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
  1137. if (typeElement != null && typeElement.NamespaceURI == surrogateDataAnnotationName.Namespace && typeElement.LocalName == surrogateDataAnnotationName.Name)
  1138. {
  1139. object surrogateData = ImportSurrogateData(typeElement, surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace);
  1140. dataContractSet.SetSurrogateData(dataContract, surrogateData);
  1141. }
  1142. }
  1143. }
  1144. }
  1145. }
  1146. [Fx.Tag.SecurityNote(Critical = "Sets critical properties on DataContract.",
  1147. Safe = "Called during schema import/code generation.")]
  1148. [SecuritySafeCritical]
  1149. void ImportGenericInfo(XmlSchemaType type, DataContract dataContract)
  1150. {
  1151. if (type.Annotation == null || type.Annotation.Items == null)
  1152. return;
  1153. foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
  1154. {
  1155. XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
  1156. if (appInfo == null)
  1157. continue;
  1158. if (appInfo.Markup != null)
  1159. {
  1160. foreach (XmlNode xmlNode in appInfo.Markup)
  1161. {
  1162. XmlElement typeElement = xmlNode as XmlElement;
  1163. if (typeElement != null && typeElement.NamespaceURI == Globals.SerializationNamespace)
  1164. {
  1165. if (typeElement.LocalName == Globals.GenericTypeLocalName)
  1166. dataContract.GenericInfo = ImportGenericInfo(typeElement, type);
  1167. }
  1168. }
  1169. }
  1170. }
  1171. }
  1172. GenericInfo ImportGenericInfo(XmlElement typeElement, XmlSchemaType type)
  1173. {
  1174. XmlNode nameAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNameAttribute);
  1175. string name = (nameAttribute == null) ? null : nameAttribute.Value;
  1176. if (name == null)
  1177. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNameAttribute)));
  1178. XmlNode nsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNamespaceAttribute);
  1179. string ns = (nsAttribute == null) ? null : nsAttribute.Value;
  1180. if (ns == null)
  1181. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNamespaceAttribute)));
  1182. if (typeElement.ChildNodes.Count > 0) //Generic Type
  1183. name = DataContract.EncodeLocalName(name);
  1184. int currentLevel = 0;
  1185. GenericInfo genInfo = new GenericInfo(new XmlQualifiedName(name, ns), type.Name);
  1186. foreach (XmlNode childNode in typeElement.ChildNodes)
  1187. {
  1188. XmlElement argumentElement = childNode as XmlElement;
  1189. if (argumentElement == null)
  1190. continue;
  1191. if (argumentElement.LocalName != Globals.GenericParameterLocalName ||
  1192. argumentElement.NamespaceURI != Globals.SerializationNamespace)
  1193. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidElement, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
  1194. XmlNode nestedLevelAttribute = argumentElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
  1195. int argumentLevel = 0;
  1196. if (nestedLevelAttribute != null)
  1197. {
  1198. if (!Int32.TryParse(nestedLevelAttribute.Value, out argumentLevel))
  1199. 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)));
  1200. }
  1201. if (argumentLevel < currentLevel)
  1202. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationForNestedLevelMustBeIncreasing, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
  1203. genInfo.Add(ImportGenericInfo(argumentElement, type));
  1204. genInfo.AddToLevel(argumentLevel, 1);
  1205. currentLevel = argumentLevel;
  1206. }
  1207. XmlNode typeNestedLevelsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
  1208. if (typeNestedLevelsAttribute != null)
  1209. {
  1210. int nestedLevels = 0;
  1211. if (!Int32.TryParse(typeNestedLevelsAttribute.Value, out nestedLevels))
  1212. 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)));
  1213. if ((nestedLevels - 1) > currentLevel)
  1214. genInfo.AddToLevel(nestedLevels - 1, 0);
  1215. }
  1216. return genInfo;
  1217. }
  1218. object ImportSurrogateData(XmlElement typeElement, string name, string ns)
  1219. {
  1220. if (dataContractSet.DataContractSurrogate != null && typeElement != null)
  1221. {
  1222. Collection<Type> knownTypes = new Collection<Type>();
  1223. DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes);
  1224. DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject, name, ns, knownTypes,
  1225. Int32.MaxValue, false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
  1226. return serializer.ReadObject(new XmlNodeReader(typeElement));
  1227. }
  1228. return null;
  1229. }
  1230. void CheckComplexType(XmlQualifiedName typeName, XmlSchemaComplexType type)
  1231. {
  1232. if (type.IsAbstract)
  1233. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractTypeNotSupported));
  1234. if (type.IsMixed)
  1235. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
  1236. }
  1237. void CheckIfElementUsesUnsupportedConstructs(XmlQualifiedName typeName, XmlSchemaElement element)
  1238. {
  1239. if (element.IsAbstract)
  1240. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractElementNotSupported, element.Name));
  1241. if (element.DefaultValue != null)
  1242. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.DefaultOnElementNotSupported, element.Name));
  1243. if (element.FixedValue != null)
  1244. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FixedOnElementNotSupported, element.Name));
  1245. if (!element.SubstitutionGroup.IsEmpty)
  1246. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SubstitutionGroupOnElementNotSupported, element.Name));
  1247. }
  1248. void ImportAttributes(XmlQualifiedName typeName, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, out bool isReference)
  1249. {
  1250. if (anyAttribute != null)
  1251. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnyAttributeNotSupported));
  1252. isReference = false;
  1253. if (attributes != null)
  1254. {
  1255. bool foundId = false, foundRef = false;
  1256. for (int i = 0; i < attributes.Count; i++)
  1257. {
  1258. XmlSchemaObject o = attributes[i];
  1259. if (o is XmlSchemaAttribute)
  1260. {
  1261. XmlSchemaAttribute attribute = (XmlSchemaAttribute)o;
  1262. if (attribute.Use == XmlSchemaUse.Prohibited)
  1263. continue;
  1264. if (TryCheckIfAttribute(typeName, attribute, Globals.IdQualifiedName, ref foundId))
  1265. continue;
  1266. if (TryCheckIfAttribute(typeName, attribute, Globals.RefQualifiedName, ref foundRef))
  1267. continue;
  1268. if (attribute.RefName.IsEmpty || attribute.RefName.Namespace != Globals.SerializationNamespace || attribute.Use == XmlSchemaUse.Required)
  1269. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TypeShouldNotContainAttributes, Globals.SerializationNamespace));
  1270. }
  1271. }
  1272. isReference = (foundId && foundRef);
  1273. }
  1274. }
  1275. bool TryCheckIfAttribute(XmlQualifiedName typeName, XmlSchemaAttribute attribute, XmlQualifiedName refName, ref bool foundAttribute)
  1276. {
  1277. if (attribute.RefName != refName)
  1278. return false;
  1279. if (foundAttribute)
  1280. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateAttributeNames, refName.Name));
  1281. foundAttribute = true;
  1282. return true;
  1283. }
  1284. void AddDataContract(DataContract dataContract)
  1285. {
  1286. dataContractSet.Add(dataContract.StableName, dataContract);
  1287. }
  1288. string GetInnerText(XmlQualifiedName typeName, XmlElement xmlElement)
  1289. {
  1290. if (xmlElement != null)
  1291. {
  1292. XmlNode child = xmlElement.FirstChild;
  1293. while (child != null)
  1294. {
  1295. if (child.NodeType == XmlNodeType.Element)
  1296. ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidAnnotationExpectingText, xmlElement.LocalName, xmlElement.NamespaceURI, child.LocalName, child.NamespaceURI));
  1297. child = child.NextSibling;
  1298. }
  1299. return xmlElement.InnerText;
  1300. }
  1301. return null;
  1302. }
  1303. static XmlElement ImportAnnotation(XmlSchemaAnnotation annotation, XmlQualifiedName annotationQualifiedName)
  1304. {
  1305. if (annotation != null && annotation.Items != null && annotation.Items.Count > 0 && annotation.Items[0] is XmlSchemaAppInfo)
  1306. {
  1307. XmlSchemaAppInfo appInfo = (XmlSchemaAppInfo)annotation.Items[0];
  1308. XmlNode[] markup = appInfo.Markup;
  1309. if (markup != null)
  1310. {
  1311. for (int i = 0; i < markup.Length; i++)
  1312. {
  1313. XmlElement annotationElement = markup[i] as XmlElement;
  1314. if (annotationElement != null && annotationElement.LocalName == annotationQualifiedName.Name && annotationElement.NamespaceURI == annotationQualifiedName.Namespace)
  1315. return annotationElement;
  1316. }
  1317. }
  1318. }
  1319. return null;
  1320. }
  1321. static void ThrowTypeCannotBeImportedException(string name, string ns, string message)
  1322. {
  1323. ThrowTypeCannotBeImportedException(SR.GetString(SR.TypeCannotBeImported, name, ns, message));
  1324. }
  1325. static void ThrowArrayTypeCannotBeImportedException(string name, string ns, string message)
  1326. {
  1327. ThrowTypeCannotBeImportedException(SR.GetString(SR.ArrayTypeCannotBeImported, name, ns, message));
  1328. }
  1329. static void ThrowEnumTypeCannotBeImportedException(string name, string ns, string message)
  1330. {
  1331. ThrowTypeCannotBeImportedException(SR.GetString(SR.EnumTypeCannotBeImported, name, ns, message));
  1332. }
  1333. static void ThrowISerializableTypeCannotBeImportedException(string name, string ns, string message)
  1334. {
  1335. ThrowTypeCannotBeImportedException(SR.GetString(SR.ISerializableTypeCannotBeImported, name, ns, message));
  1336. }
  1337. static void ThrowTypeCannotBeImportedException(string message)
  1338. {
  1339. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeCannotBeImportedHowToFix, message)));
  1340. }
  1341. }
  1342. }