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