2 namespace System.Runtime.Serialization
5 using System.Collections;
6 using System.Collections.Generic;
7 using System.Collections.ObjectModel;
8 using System.Diagnostics;
9 using System.Globalization;
11 using System.Reflection;
12 using System.Runtime.Diagnostics;
13 using System.ServiceModel.Diagnostics;
14 using System.Security;
16 using System.Xml.Schema;
17 using System.Xml.Serialization;
18 using System.Runtime.Serialization.Diagnostics;
22 internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
24 if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot))
26 XmlSchemaSet schemas = new XmlSchemaSet();
27 schemas.XmlResolver = null;
28 InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
29 if (stableName.Name == null || stableName.Name.Length == 0)
30 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
33 internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
37 if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
40 if (type == Globals.TypeOfXmlElement)
42 xsdType = CreateAnyElementType();
48 xsdType = CreateAnyType();
49 name = "ArrayOfXmlNode";
52 typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
59 static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
63 object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
64 if (attrs == null || attrs.Length == 0)
66 stableName = DataContract.GetDefaultStableName(clrType);
70 XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
73 xsdType = CreateAnyElementType();
76 string methodName = provider.MethodName;
77 if (methodName == null || methodName.Length == 0)
80 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType))));
81 stableName = DataContract.GetDefaultStableName(clrType);
85 MethodInfo getMethod = clrType.GetMethod(methodName, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
86 if (getMethod == null)
87 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
89 if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType)))
90 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnTypeOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName, DataContract.GetClrTypeFullName(getMethod.ReturnType), DataContract.GetClrTypeFullName(Globals.TypeOfXmlQualifiedName), typeof(XmlSchemaType))));
92 object typeInfo = getMethod.Invoke(null, new object[] { schemas });
97 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName)));
98 stableName = DataContract.GetDefaultStableName(clrType);
100 else if (typeInfo == null)
102 xsdType = CreateAnyElementType();
104 stableName = DataContract.GetDefaultStableName(clrType);
108 XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
109 if (providerXsdType != null)
111 string typeName = providerXsdType.Name;
112 string typeNs = null;
113 if (typeName == null || typeName.Length == 0)
115 DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs);
116 stableName = new XmlQualifiedName(typeName, typeNs);
117 providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
118 xsdType = providerXsdType;
122 foreach (XmlSchema schema in schemas.Schemas())
124 foreach (XmlSchemaObject schemaItem in schema.Items)
126 if ((object)schemaItem == (object)providerXsdType)
128 typeNs = schema.TargetNamespace;
130 typeNs = String.Empty;
138 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
139 stableName = new XmlQualifiedName(typeName, typeNs);
143 stableName = (XmlQualifiedName)typeInfo;
149 static XmlSchemaComplexType CreateAnyElementType()
151 XmlSchemaComplexType anyElementType = new XmlSchemaComplexType();
152 anyElementType.IsMixed = false;
153 anyElementType.Particle = new XmlSchemaSequence();
154 XmlSchemaAny any = new XmlSchemaAny();
156 any.ProcessContents = XmlSchemaContentProcessing.Lax;
157 ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any);
158 return anyElementType;
161 static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes)
163 if (nodes == null || nodes.Length == 0)
165 bool hasAnnotation = false;
166 for (int i = 0; i < nodes.Length; i++)
167 if (nodes[i] != null)
169 hasAnnotation = true;
175 XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
176 XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
177 annotation.Items.Add(appInfo);
178 appInfo.Markup = nodes;
182 static XmlSchemaComplexType CreateAnyType()
184 XmlSchemaComplexType anyType = new XmlSchemaComplexType();
185 anyType.IsMixed = true;
186 anyType.Particle = new XmlSchemaSequence();
187 XmlSchemaAny any = new XmlSchemaAny();
189 any.MaxOccurs = Decimal.MaxValue;
190 any.ProcessContents = XmlSchemaContentProcessing.Lax;
191 ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
192 anyType.AnyAttribute = new XmlSchemaAnyAttribute();
196 static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc)
198 XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
200 XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
201 nameAttribute.Value = typeName.Name;
202 actualTypeElement.Attributes.Append(nameAttribute);
204 XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
205 nsAttribute.Value = typeName.Namespace;
206 actualTypeElement.Attributes.Append(nsAttribute);
208 return actualTypeElement;
211 static XmlQualifiedName actualTypeAnnotationName;
212 internal static XmlQualifiedName ActualTypeAnnotationName
216 if (actualTypeAnnotationName == null)
217 actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace);
218 return actualTypeAnnotationName;