536cd135cc
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
666 lines
34 KiB
C#
666 lines
34 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="SoapSchemaImporter.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
// <owner current="true" primary="true">Microsoft</owner>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Xml.Serialization {
|
|
|
|
using System;
|
|
using System.Xml.Schema;
|
|
using System.Xml;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using System.Diagnostics;
|
|
using System.CodeDom.Compiler;
|
|
using System.Security.Permissions;
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter"]/*' />
|
|
///<internalonly/>
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public class SoapSchemaImporter : SchemaImporter {
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.SoapSchemaImporter"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapSchemaImporter(XmlSchemas schemas) : base(schemas, CodeGenerationOptions.GenerateProperties, null, new ImportContext()) {}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.SoapSchemaImporter1"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapSchemaImporter(XmlSchemas schemas, CodeIdentifiers typeIdentifiers) : base(schemas, CodeGenerationOptions.GenerateProperties, null, new ImportContext(typeIdentifiers, false)) {}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.SoapSchemaImporter2"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapSchemaImporter(XmlSchemas schemas, CodeIdentifiers typeIdentifiers, CodeGenerationOptions options) : base(schemas, options, null, new ImportContext(typeIdentifiers, false)) {}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.SoapSchemaImporter3"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapSchemaImporter(XmlSchemas schemas, CodeGenerationOptions options, ImportContext context) : base(schemas, options, null, context){}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.SoapSchemaImporter4"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapSchemaImporter(XmlSchemas schemas, CodeGenerationOptions options, CodeDomProvider codeProvider, ImportContext context) : base(schemas, options, codeProvider, context){}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportDerivedTypeMapping"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlTypeMapping ImportDerivedTypeMapping(XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
|
|
{
|
|
TypeMapping mapping = ImportType(name, false);
|
|
if (mapping is StructMapping) {
|
|
MakeDerived((StructMapping)mapping, baseType, baseTypeCanBeIndirect);
|
|
}
|
|
else if (baseType != null)
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlPrimitiveBaseType, name.Name, name.Namespace, baseType.FullName));
|
|
ElementAccessor accessor = new ElementAccessor();
|
|
accessor.IsSoap = true;
|
|
accessor.Name = name.Name;
|
|
accessor.Namespace = name.Namespace;
|
|
accessor.Mapping = mapping;
|
|
accessor.IsNullable = true;
|
|
accessor.Form = XmlSchemaForm.Qualified;
|
|
|
|
return new XmlTypeMapping(Scope, accessor);
|
|
}
|
|
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportMembersMapping"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember member) {
|
|
TypeMapping typeMapping = ImportType(member.MemberType, true);
|
|
if (!(typeMapping is StructMapping)) return ImportMembersMapping(name, ns, new SoapSchemaMember[] { member });
|
|
|
|
MembersMapping mapping = new MembersMapping();
|
|
mapping.TypeDesc = Scope.GetTypeDesc(typeof(object[]));
|
|
mapping.Members = ((StructMapping)typeMapping).Members;
|
|
mapping.HasWrapperElement = true;
|
|
|
|
ElementAccessor accessor = new ElementAccessor();
|
|
accessor.IsSoap = true;
|
|
accessor.Name = name;
|
|
accessor.Namespace = typeMapping.Namespace != null ? typeMapping.Namespace : ns;
|
|
accessor.Mapping = mapping;
|
|
accessor.IsNullable = false;
|
|
accessor.Form = XmlSchemaForm.Qualified;
|
|
|
|
return new XmlMembersMapping(Scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write);
|
|
}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportMembersMapping1"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember[] members) {
|
|
return ImportMembersMapping(name, ns, members, true);
|
|
}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportMembersMapping2"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement) {
|
|
return ImportMembersMapping(name, ns, members, hasWrapperElement, null, false);
|
|
}
|
|
|
|
/// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportMembersMapping3"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement, Type baseType, bool baseTypeCanBeIndirect) {
|
|
XmlSchemaComplexType type = new XmlSchemaComplexType();
|
|
XmlSchemaSequence seq = new XmlSchemaSequence();
|
|
type.Particle = seq;
|
|
foreach (SoapSchemaMember member in members) {
|
|
XmlSchemaElement element = new XmlSchemaElement();
|
|
element.Name = member.MemberName;
|
|
element.SchemaTypeName = member.MemberType;
|
|
seq.Items.Add(element);
|
|
}
|
|
|
|
CodeIdentifiers identifiers = new CodeIdentifiers();
|
|
identifiers.UseCamelCasing = true;
|
|
MembersMapping mapping = new MembersMapping();
|
|
mapping.TypeDesc = Scope.GetTypeDesc(typeof(object[]));
|
|
mapping.Members = ImportTypeMembers(type, ns, identifiers);
|
|
mapping.HasWrapperElement = hasWrapperElement;
|
|
|
|
if (baseType != null) {
|
|
for (int i = 0; i < mapping.Members.Length; i++) {
|
|
MemberMapping member = mapping.Members[i];
|
|
if (member.Accessor.Mapping is StructMapping)
|
|
MakeDerived((StructMapping)member.Accessor.Mapping, baseType, baseTypeCanBeIndirect);
|
|
}
|
|
}
|
|
ElementAccessor accessor = new ElementAccessor();
|
|
accessor.IsSoap = true;
|
|
accessor.Name = name;
|
|
accessor.Namespace = ns;
|
|
accessor.Mapping = mapping;
|
|
accessor.IsNullable = false;
|
|
accessor.Form = XmlSchemaForm.Qualified;
|
|
|
|
return new XmlMembersMapping(Scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write);
|
|
}
|
|
|
|
ElementAccessor ImportElement(XmlSchemaElement element, string ns) {
|
|
if (!element.RefName.IsEmpty) {
|
|
throw new InvalidOperationException(Res.GetString(Res.RefSyntaxNotSupportedForElements0, element.RefName.Name, element.RefName.Namespace));
|
|
}
|
|
|
|
if (element.Name.Length == 0) {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlElementHasNoName, parentType.Name, parentType.Namespace));
|
|
}
|
|
TypeMapping mapping = ImportElementType(element, ns);
|
|
ElementAccessor accessor = new ElementAccessor();
|
|
accessor.IsSoap = true;
|
|
accessor.Name = element.Name;
|
|
accessor.Namespace = ns;
|
|
accessor.Mapping = mapping;
|
|
accessor.IsNullable = element.IsNillable;
|
|
accessor.Form = XmlSchemaForm.None;
|
|
|
|
return accessor;
|
|
}
|
|
|
|
TypeMapping ImportElementType(XmlSchemaElement element, string ns) {
|
|
TypeMapping mapping;
|
|
if (!element.SchemaTypeName.IsEmpty)
|
|
mapping = ImportType(element.SchemaTypeName, false);
|
|
else if (element.SchemaType != null) {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
|
|
if (element.SchemaType is XmlSchemaComplexType) {
|
|
mapping = ImportType((XmlSchemaComplexType)element.SchemaType, ns, false);
|
|
if (!(mapping is ArrayMapping)) {
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSchemaElementType, parentType.Name, parentType.Namespace, element.Name));
|
|
}
|
|
}
|
|
else {
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSchemaElementType, parentType.Name, parentType.Namespace, element.Name));
|
|
}
|
|
}
|
|
else if (!element.SubstitutionGroup.IsEmpty) {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSubstitutionGroupUse, parentType.Name, parentType.Namespace));
|
|
}
|
|
else {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlElementMissingType, parentType.Name, parentType.Namespace, element.Name));
|
|
}
|
|
|
|
mapping.ReferencedByElement = true;
|
|
|
|
return mapping;
|
|
}
|
|
|
|
[PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
|
|
internal override void ImportDerivedTypes(XmlQualifiedName baseName) {
|
|
foreach (XmlSchema schema in Schemas) {
|
|
if (Schemas.IsReference(schema)) continue;
|
|
if (XmlSchemas.IsDataSet(schema)) continue;
|
|
XmlSchemas.Preprocess(schema);
|
|
foreach (object item in schema.SchemaTypes.Values) {
|
|
if (item is XmlSchemaType) {
|
|
XmlSchemaType type = (XmlSchemaType)item;
|
|
if (type.DerivedFrom == baseName) {
|
|
ImportType(type.QualifiedName, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TypeMapping ImportType(XmlQualifiedName name, bool excludeFromImport) {
|
|
if (name.Name == Soap.UrType && name.Namespace == XmlSchema.Namespace)
|
|
return ImportRootMapping();
|
|
object type = FindType(name);
|
|
TypeMapping mapping = (TypeMapping)ImportedMappings[type];
|
|
if (mapping == null) {
|
|
if (type is XmlSchemaComplexType)
|
|
mapping = ImportType((XmlSchemaComplexType)type, name.Namespace, excludeFromImport);
|
|
else if (type is XmlSchemaSimpleType)
|
|
mapping = ImportDataType((XmlSchemaSimpleType)type, name.Namespace, name.Name, false);
|
|
else
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
|
|
}
|
|
if (excludeFromImport)
|
|
mapping.IncludeInSchema = false;
|
|
return mapping;
|
|
}
|
|
|
|
TypeMapping ImportType(XmlSchemaComplexType type, string typeNs, bool excludeFromImport) {
|
|
if (type.Redefined != null) {
|
|
// we do not support redefine in the current version
|
|
throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedRedefine, type.Name, typeNs));
|
|
}
|
|
TypeMapping mapping = ImportAnyType(type, typeNs);
|
|
if (mapping == null)
|
|
mapping = ImportArrayMapping(type, typeNs);
|
|
if (mapping == null)
|
|
mapping = ImportStructType(type, typeNs, excludeFromImport);
|
|
return mapping;
|
|
}
|
|
TypeMapping ImportAnyType(XmlSchemaComplexType type, string typeNs){
|
|
if (type.Particle == null)
|
|
return null;
|
|
if(!(type.Particle is XmlSchemaAll ||type.Particle is XmlSchemaSequence))
|
|
return null;
|
|
XmlSchemaGroupBase group = (XmlSchemaGroupBase) type.Particle;
|
|
|
|
if (group.Items.Count != 1 || !(group.Items[0] is XmlSchemaAny))
|
|
return null;
|
|
return ImportRootMapping();
|
|
}
|
|
|
|
StructMapping ImportStructType(XmlSchemaComplexType type, string typeNs, bool excludeFromImport) {
|
|
if (type.Name == null) {
|
|
XmlSchemaElement element = (XmlSchemaElement)type.Parent;
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidSchemaElementType, parentType.Name, parentType.Namespace, element.Name));
|
|
}
|
|
|
|
TypeDesc baseTypeDesc = null;
|
|
|
|
Mapping baseMapping = null;
|
|
if (!type.DerivedFrom.IsEmpty) {
|
|
baseMapping = ImportType(type.DerivedFrom, excludeFromImport);
|
|
|
|
if (baseMapping is StructMapping)
|
|
baseTypeDesc = ((StructMapping)baseMapping).TypeDesc;
|
|
else
|
|
baseMapping = null;
|
|
}
|
|
if (baseMapping == null) baseMapping = GetRootMapping();
|
|
Mapping previousMapping = (Mapping)ImportedMappings[type];
|
|
if (previousMapping != null) {
|
|
return (StructMapping)previousMapping;
|
|
}
|
|
string typeName = GenerateUniqueTypeName(Accessor.UnescapeName(type.Name));
|
|
StructMapping structMapping = new StructMapping();
|
|
structMapping.IsReference = Schemas.IsReference(type);
|
|
TypeFlags flags = TypeFlags.Reference;
|
|
if (type.IsAbstract) flags |= TypeFlags.Abstract;
|
|
structMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Struct, baseTypeDesc, flags);
|
|
structMapping.Namespace = typeNs;
|
|
structMapping.TypeName = type.Name;
|
|
structMapping.BaseMapping = (StructMapping)baseMapping;
|
|
ImportedMappings.Add(type, structMapping);
|
|
if (excludeFromImport)
|
|
structMapping.IncludeInSchema = false;
|
|
CodeIdentifiers members = new CodeIdentifiers();
|
|
members.AddReserved(typeName);
|
|
AddReservedIdentifiersForDataBinding(members);
|
|
structMapping.Members = ImportTypeMembers(type, typeNs, members);
|
|
Scope.AddTypeMapping(structMapping);
|
|
ImportDerivedTypes(new XmlQualifiedName(type.Name, typeNs));
|
|
return structMapping;
|
|
}
|
|
|
|
MemberMapping[] ImportTypeMembers(XmlSchemaComplexType type, string typeNs, CodeIdentifiers members) {
|
|
if (type.AnyAttribute != null) {
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidAnyAttributeUse, type.Name, type.QualifiedName.Namespace));
|
|
}
|
|
|
|
XmlSchemaObjectCollection items = type.Attributes;
|
|
for (int i = 0; i < items.Count; i++) {
|
|
object item = items[i];
|
|
if (item is XmlSchemaAttributeGroup) {
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapInvalidAttributeUse, type.Name, type.QualifiedName.Namespace));
|
|
}
|
|
if (item is XmlSchemaAttribute) {
|
|
XmlSchemaAttribute attr = (XmlSchemaAttribute)item;
|
|
if (attr.Use != XmlSchemaUse.Prohibited) throw new InvalidOperationException(Res.GetString(Res.XmlSoapInvalidAttributeUse, type.Name, type.QualifiedName.Namespace));
|
|
}
|
|
}
|
|
if (type.Particle != null) {
|
|
ImportGroup(type.Particle, members, typeNs);
|
|
}
|
|
else if (type.ContentModel != null && type.ContentModel is XmlSchemaComplexContent) {
|
|
XmlSchemaComplexContent model = (XmlSchemaComplexContent)type.ContentModel;
|
|
|
|
if (model.Content is XmlSchemaComplexContentExtension) {
|
|
if (((XmlSchemaComplexContentExtension)model.Content).Particle != null) {
|
|
ImportGroup(((XmlSchemaComplexContentExtension)model.Content).Particle, members, typeNs);
|
|
}
|
|
}
|
|
else if (model.Content is XmlSchemaComplexContentRestriction) {
|
|
if (((XmlSchemaComplexContentRestriction)model.Content).Particle != null) {
|
|
ImportGroup(((XmlSchemaComplexContentRestriction)model.Content).Particle, members, typeNs);
|
|
}
|
|
}
|
|
}
|
|
return (MemberMapping[])members.ToArray(typeof(MemberMapping));
|
|
}
|
|
|
|
void ImportGroup(XmlSchemaParticle group, CodeIdentifiers members, string ns) {
|
|
if (group is XmlSchemaChoice) {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(group);
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapInvalidChoice, parentType.Name, parentType.Namespace));
|
|
}
|
|
else
|
|
ImportGroupMembers(group, members, ns);
|
|
}
|
|
|
|
void ImportGroupMembers(XmlSchemaParticle particle, CodeIdentifiers members, string ns) {
|
|
XmlQualifiedName parentType = XmlSchemas.GetParentName(particle);
|
|
if (particle is XmlSchemaGroupRef) {
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapUnsupportedGroupRef, parentType.Name, parentType.Namespace));
|
|
}
|
|
else if (particle is XmlSchemaGroupBase) {
|
|
XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle;
|
|
if (group.IsMultipleOccurrence)
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapUnsupportedGroupRepeat, parentType.Name, parentType.Namespace));
|
|
for (int i = 0; i < group.Items.Count; i++) {
|
|
object item = group.Items[i];
|
|
if (item is XmlSchemaGroupBase || item is XmlSchemaGroupRef)
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapUnsupportedGroupNested, parentType.Name, parentType.Namespace));
|
|
else if (item is XmlSchemaElement)
|
|
ImportElementMember((XmlSchemaElement)item, members, ns);
|
|
else if (item is XmlSchemaAny)
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlSoapUnsupportedGroupAny, parentType.Name, parentType.Namespace));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ElementAccessor ImportArray(XmlSchemaElement element, string ns) {
|
|
if (element.SchemaType == null) return null;
|
|
if (!element.IsMultipleOccurrence) return null;
|
|
XmlSchemaType type = element.SchemaType;
|
|
ArrayMapping arrayMapping = ImportArrayMapping(type, ns);
|
|
if (arrayMapping == null) return null;
|
|
ElementAccessor arrayAccessor = new ElementAccessor();
|
|
arrayAccessor.IsSoap = true;
|
|
arrayAccessor.Name = element.Name;
|
|
arrayAccessor.Namespace = ns;
|
|
arrayAccessor.Mapping = arrayMapping;
|
|
arrayAccessor.IsNullable = false;
|
|
arrayAccessor.Form = XmlSchemaForm.None;
|
|
|
|
return arrayAccessor;
|
|
}
|
|
|
|
ArrayMapping ImportArrayMapping(XmlSchemaType type, string ns) {
|
|
ArrayMapping arrayMapping;
|
|
if (type.Name == Soap.Array && ns == Soap.Encoding) {
|
|
arrayMapping = new ArrayMapping();
|
|
TypeMapping mapping = GetRootMapping();
|
|
ElementAccessor itemAccessor = new ElementAccessor();
|
|
itemAccessor.IsSoap = true;
|
|
itemAccessor.Name = Soap.UrType;
|
|
itemAccessor.Namespace = ns;
|
|
itemAccessor.Mapping = mapping;
|
|
itemAccessor.IsNullable = true;
|
|
itemAccessor.Form = XmlSchemaForm.None;
|
|
|
|
arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
|
|
arrayMapping.TypeDesc = itemAccessor.Mapping.TypeDesc.CreateArrayTypeDesc();
|
|
arrayMapping.TypeName = "ArrayOf" + CodeIdentifier.MakePascal(itemAccessor.Mapping.TypeName);
|
|
return arrayMapping;
|
|
}
|
|
if (!(type.DerivedFrom.Name == Soap.Array && type.DerivedFrom.Namespace == Soap.Encoding)) return null;
|
|
|
|
// the type should be a XmlSchemaComplexType
|
|
XmlSchemaContentModel model = ((XmlSchemaComplexType)type).ContentModel;
|
|
|
|
// the Content should be an restriction
|
|
if (!(model.Content is XmlSchemaComplexContentRestriction)) return null;
|
|
|
|
arrayMapping = new ArrayMapping();
|
|
|
|
XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)model.Content;
|
|
|
|
for (int i = 0; i < restriction.Attributes.Count; i++) {
|
|
XmlSchemaAttribute attribute = restriction.Attributes[i] as XmlSchemaAttribute;
|
|
if (attribute != null && attribute.RefName.Name == Soap.ArrayType && attribute.RefName.Namespace == Soap.Encoding) {
|
|
// read the value of the wsdl:arrayType attribute
|
|
string arrayType = null;
|
|
|
|
if (attribute.UnhandledAttributes != null) {
|
|
foreach (XmlAttribute a in attribute.UnhandledAttributes) {
|
|
if (a.LocalName == Wsdl.ArrayType && a.NamespaceURI == Wsdl.Namespace) {
|
|
arrayType = a.Value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (arrayType != null) {
|
|
string dims;
|
|
XmlQualifiedName typeName = TypeScope.ParseWsdlArrayType(arrayType, out dims, attribute);
|
|
|
|
TypeMapping mapping;
|
|
TypeDesc td = Scope.GetTypeDesc(typeName.Name, typeName.Namespace);
|
|
if (td != null && td.IsPrimitive) {
|
|
mapping = new PrimitiveMapping();
|
|
mapping.TypeDesc = td;
|
|
mapping.TypeName = td.DataType.Name;
|
|
}
|
|
else {
|
|
mapping = ImportType(typeName, false);
|
|
}
|
|
ElementAccessor itemAccessor = new ElementAccessor();
|
|
itemAccessor.IsSoap = true;
|
|
itemAccessor.Name = typeName.Name;
|
|
itemAccessor.Namespace = ns;
|
|
itemAccessor.Mapping = mapping;
|
|
itemAccessor.IsNullable = true;
|
|
itemAccessor.Form = XmlSchemaForm.None;
|
|
|
|
arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
|
|
arrayMapping.TypeDesc = itemAccessor.Mapping.TypeDesc.CreateArrayTypeDesc();
|
|
arrayMapping.TypeName = "ArrayOf" + CodeIdentifier.MakePascal(itemAccessor.Mapping.TypeName);
|
|
|
|
return arrayMapping;
|
|
}
|
|
}
|
|
}
|
|
|
|
XmlSchemaParticle particle = restriction.Particle;
|
|
if (particle is XmlSchemaAll || particle is XmlSchemaSequence) {
|
|
XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle;
|
|
if (group.Items.Count != 1 || !(group.Items[0] is XmlSchemaElement))
|
|
return null;
|
|
XmlSchemaElement itemElement = (XmlSchemaElement)group.Items[0];
|
|
if (!itemElement.IsMultipleOccurrence) return null;
|
|
ElementAccessor itemAccessor = ImportElement(itemElement, ns);
|
|
arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
|
|
arrayMapping.TypeDesc = ((TypeMapping)itemAccessor.Mapping).TypeDesc.CreateArrayTypeDesc();
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
return arrayMapping;
|
|
}
|
|
|
|
void ImportElementMember(XmlSchemaElement element, CodeIdentifiers members, string ns) {
|
|
ElementAccessor accessor;
|
|
if ((accessor = ImportArray(element, ns)) == null) {
|
|
accessor = ImportElement(element, ns);
|
|
}
|
|
|
|
MemberMapping member = new MemberMapping();
|
|
member.Name = CodeIdentifier.MakeValid(Accessor.UnescapeName(accessor.Name));
|
|
member.Name = members.AddUnique(member.Name, member);
|
|
if (member.Name.EndsWith("Specified", StringComparison.Ordinal)) {
|
|
string name = member.Name;
|
|
member.Name = members.AddUnique(member.Name, member);
|
|
members.Remove(name);
|
|
}
|
|
member.TypeDesc = ((TypeMapping)accessor.Mapping).TypeDesc;
|
|
member.Elements = new ElementAccessor[] { accessor };
|
|
if (element.IsMultipleOccurrence)
|
|
member.TypeDesc = member.TypeDesc.CreateArrayTypeDesc();
|
|
|
|
if (element.MinOccurs == 0 && member.TypeDesc.IsValueType && !member.TypeDesc.HasIsEmpty) {
|
|
member.CheckSpecified = SpecifiedAccessor.ReadWrite;
|
|
}
|
|
}
|
|
|
|
TypeMapping ImportDataType(XmlSchemaSimpleType dataType, string typeNs, string identifier, bool isList) {
|
|
TypeMapping mapping = ImportNonXsdPrimitiveDataType(dataType, typeNs);
|
|
if (mapping != null)
|
|
return mapping;
|
|
|
|
if (dataType.Content is XmlSchemaSimpleTypeRestriction) {
|
|
XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)dataType.Content;
|
|
foreach (object o in restriction.Facets) {
|
|
if (o is XmlSchemaEnumerationFacet) {
|
|
return ImportEnumeratedDataType(dataType, typeNs, identifier, isList);
|
|
}
|
|
}
|
|
}
|
|
else if (dataType.Content is XmlSchemaSimpleTypeList || dataType.Content is XmlSchemaSimpleTypeUnion) {
|
|
if (dataType.Content is XmlSchemaSimpleTypeList) {
|
|
// check if we have enumeration list
|
|
XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)dataType.Content;
|
|
if (list.ItemType != null) {
|
|
mapping = ImportDataType(list.ItemType, typeNs, identifier, true);
|
|
if (mapping != null) {
|
|
return mapping;
|
|
}
|
|
}
|
|
}
|
|
mapping = new PrimitiveMapping();
|
|
mapping.TypeDesc = Scope.GetTypeDesc(typeof(string));
|
|
mapping.TypeName = mapping.TypeDesc.DataType.Name;
|
|
return mapping;
|
|
}
|
|
return ImportPrimitiveDataType(dataType);
|
|
}
|
|
|
|
TypeMapping ImportEnumeratedDataType(XmlSchemaSimpleType dataType, string typeNs, string identifier, bool isList) {
|
|
TypeMapping mapping = (TypeMapping)ImportedMappings[dataType];
|
|
if (mapping != null)
|
|
return mapping;
|
|
|
|
XmlSchemaSimpleType sourceDataType = FindDataType(dataType.DerivedFrom);
|
|
TypeDesc sourceTypeDesc = Scope.GetTypeDesc(sourceDataType);
|
|
if (sourceTypeDesc != null && sourceTypeDesc != Scope.GetTypeDesc(typeof(string)))
|
|
return ImportPrimitiveDataType(dataType);
|
|
identifier = Accessor.UnescapeName(identifier);
|
|
string typeName = GenerateUniqueTypeName(identifier);
|
|
EnumMapping enumMapping = new EnumMapping();
|
|
enumMapping.IsReference = Schemas.IsReference(dataType);
|
|
enumMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Enum, null, 0);
|
|
enumMapping.TypeName = identifier;
|
|
enumMapping.Namespace = typeNs;
|
|
enumMapping.IsFlags = isList;
|
|
CodeIdentifiers constants = new CodeIdentifiers();
|
|
|
|
if (!(dataType.Content is XmlSchemaSimpleTypeRestriction))
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEnumContent, dataType.Content.GetType().Name, identifier));
|
|
|
|
XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)dataType.Content;
|
|
|
|
for (int i = 0; i < restriction.Facets.Count; i++) {
|
|
object facet = restriction.Facets[i];
|
|
if (!(facet is XmlSchemaEnumerationFacet)) continue;
|
|
XmlSchemaEnumerationFacet enumeration = (XmlSchemaEnumerationFacet)facet;
|
|
ConstantMapping constant = new ConstantMapping();
|
|
string constantName = CodeIdentifier.MakeValid(enumeration.Value);
|
|
constant.Name = constants.AddUnique(constantName, constant);
|
|
constant.XmlName = enumeration.Value;
|
|
constant.Value = i;
|
|
}
|
|
enumMapping.Constants = (ConstantMapping[])constants.ToArray(typeof(ConstantMapping));
|
|
if (isList && enumMapping.Constants.Length > 63) {
|
|
// if we have 64+ flag constants we cannot map the type to long enum, we will use string mapping instead.
|
|
mapping = new PrimitiveMapping();
|
|
mapping.TypeDesc = Scope.GetTypeDesc(typeof(string));
|
|
mapping.TypeName = mapping.TypeDesc.DataType.Name;
|
|
ImportedMappings.Add(dataType, mapping);
|
|
return mapping;
|
|
}
|
|
ImportedMappings.Add(dataType, enumMapping);
|
|
Scope.AddTypeMapping(enumMapping);
|
|
return enumMapping;
|
|
}
|
|
|
|
PrimitiveMapping ImportPrimitiveDataType(XmlSchemaSimpleType dataType) {
|
|
TypeDesc sourceTypeDesc = GetDataTypeSource(dataType);
|
|
PrimitiveMapping mapping = new PrimitiveMapping();
|
|
mapping.TypeDesc = sourceTypeDesc;
|
|
mapping.TypeName = sourceTypeDesc.DataType.Name;
|
|
return mapping;
|
|
}
|
|
|
|
PrimitiveMapping ImportNonXsdPrimitiveDataType(XmlSchemaSimpleType dataType, string ns) {
|
|
PrimitiveMapping mapping = null;
|
|
TypeDesc typeDesc = null;
|
|
if (dataType.Name != null && dataType.Name.Length != 0) {
|
|
typeDesc = Scope.GetTypeDesc(dataType.Name, ns);
|
|
if (typeDesc != null) {
|
|
mapping = new PrimitiveMapping();
|
|
mapping.TypeDesc = typeDesc;
|
|
mapping.TypeName = typeDesc.DataType.Name;
|
|
}
|
|
}
|
|
return mapping;
|
|
}
|
|
|
|
TypeDesc GetDataTypeSource(XmlSchemaSimpleType dataType) {
|
|
if (dataType.Name != null && dataType.Name.Length != 0) {
|
|
TypeDesc typeDesc = Scope.GetTypeDesc(dataType);
|
|
if (typeDesc != null) return typeDesc;
|
|
}
|
|
if (!dataType.DerivedFrom.IsEmpty) {
|
|
return GetDataTypeSource(FindDataType(dataType.DerivedFrom));
|
|
}
|
|
return Scope.GetTypeDesc(typeof(string));
|
|
}
|
|
|
|
XmlSchemaSimpleType FindDataType(XmlQualifiedName name) {
|
|
TypeDesc typeDesc = Scope.GetTypeDesc(name.Name, name.Namespace);
|
|
if (typeDesc != null && typeDesc.DataType is XmlSchemaSimpleType)
|
|
return (XmlSchemaSimpleType)typeDesc.DataType;
|
|
XmlSchemaSimpleType dataType = (XmlSchemaSimpleType)Schemas.Find(name, typeof(XmlSchemaSimpleType));
|
|
if (dataType != null) {
|
|
return dataType;
|
|
}
|
|
if (name.Namespace == XmlSchema.Namespace)
|
|
return (XmlSchemaSimpleType)Scope.GetTypeDesc(typeof(string)).DataType;
|
|
else
|
|
throw new InvalidOperationException(Res.GetString(Res.XmlMissingDataType, name.ToString()));
|
|
}
|
|
|
|
object FindType(XmlQualifiedName name) {
|
|
if (name != null && name.Namespace == Soap.Encoding) {
|
|
// we have a build-in support fo the encoded types, we need to make sure that we generate the same
|
|
// object model whether http://www.w3.org/2003/05/soap-encoding schema was specified or not.
|
|
object type = Schemas.Find(name, typeof(XmlSchemaComplexType));
|
|
if (type != null) {
|
|
XmlSchemaType encType = (XmlSchemaType)type;
|
|
XmlQualifiedName baseType = encType.DerivedFrom;
|
|
if (!baseType.IsEmpty) {
|
|
return FindType(baseType);
|
|
}
|
|
return encType;
|
|
}
|
|
return FindDataType(name);
|
|
}
|
|
else {
|
|
object type = Schemas.Find(name, typeof(XmlSchemaComplexType));
|
|
if (type != null) {
|
|
return type;
|
|
}
|
|
return FindDataType(name);
|
|
}
|
|
}
|
|
}
|
|
}
|