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.Security;
15 using System.Xml.Schema;
16 using System.Xml.Serialization;
17 using System.Runtime.Serialization.Diagnostics;
21 internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
23 if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot))
25 XmlSchemaSet schemas = new XmlSchemaSet();
26 schemas.XmlResolver = null;
27 InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
28 if (stableName.Name == null || stableName.Name.Length == 0)
29 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
32 internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
36 if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
39 if (type == Globals.TypeOfXmlElement)
41 xsdType = CreateAnyElementType();
47 xsdType = CreateAnyType();
48 name = "ArrayOfXmlNode";
51 typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
58 internal static void AddDefaultXmlType(XmlSchemaSet schemas, string localName, string ns)
60 throw new NotImplementedException();
63 static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
67 object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
68 if (attrs == null || attrs.Length == 0)
70 stableName = DataContract.GetDefaultStableName(clrType);
74 XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
77 xsdType = CreateAnyElementType();
80 string methodName = provider.MethodName;
81 if (methodName == null || methodName.Length == 0)
84 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType))));
85 stableName = DataContract.GetDefaultStableName(clrType);
89 MethodInfo getMethod = clrType.GetMethod(methodName, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
90 if (getMethod == null)
91 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
93 if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType)))
94 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))));
96 object typeInfo = getMethod.Invoke(null, new object[] { schemas });
100 if (typeInfo != null)
101 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName)));
102 stableName = DataContract.GetDefaultStableName(clrType);
104 else if (typeInfo == null)
106 xsdType = CreateAnyElementType();
108 stableName = DataContract.GetDefaultStableName(clrType);
112 XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
113 if (providerXsdType != null)
115 string typeName = providerXsdType.Name;
116 string typeNs = null;
117 if (typeName == null || typeName.Length == 0)
119 DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs);
120 stableName = new XmlQualifiedName(typeName, typeNs);
121 providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
122 xsdType = providerXsdType;
126 foreach (XmlSchema schema in schemas.Schemas())
128 foreach (XmlSchemaObject schemaItem in schema.Items)
130 if ((object)schemaItem == (object)providerXsdType)
132 typeNs = schema.TargetNamespace;
134 typeNs = String.Empty;
142 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
143 stableName = new XmlQualifiedName(typeName, typeNs);
147 stableName = (XmlQualifiedName)typeInfo;
153 static XmlSchemaComplexType CreateAnyElementType()
155 XmlSchemaComplexType anyElementType = new XmlSchemaComplexType();
156 anyElementType.IsMixed = false;
157 anyElementType.Particle = new XmlSchemaSequence();
158 XmlSchemaAny any = new XmlSchemaAny();
160 any.ProcessContents = XmlSchemaContentProcessing.Lax;
161 ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any);
162 return anyElementType;
165 static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes)
167 if (nodes == null || nodes.Length == 0)
169 bool hasAnnotation = false;
170 for (int i = 0; i < nodes.Length; i++)
171 if (nodes[i] != null)
173 hasAnnotation = true;
179 XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
180 XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
181 annotation.Items.Add(appInfo);
182 appInfo.Markup = nodes;
186 static XmlSchemaComplexType CreateAnyType()
188 XmlSchemaComplexType anyType = new XmlSchemaComplexType();
189 anyType.IsMixed = true;
190 anyType.Particle = new XmlSchemaSequence();
191 XmlSchemaAny any = new XmlSchemaAny();
193 any.MaxOccurs = Decimal.MaxValue;
194 any.ProcessContents = XmlSchemaContentProcessing.Lax;
195 ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
196 anyType.AnyAttribute = new XmlSchemaAnyAttribute();
200 static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc)
202 XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
204 XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
205 nameAttribute.Value = typeName.Name;
206 actualTypeElement.Attributes.Append(nameAttribute);
208 XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
209 nsAttribute.Value = typeName.Namespace;
210 actualTypeElement.Attributes.Append(nsAttribute);
212 return actualTypeElement;
215 static XmlQualifiedName actualTypeAnnotationName;
216 internal static XmlQualifiedName ActualTypeAnnotationName
220 if (actualTypeAnnotationName == null)
221 actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace);
222 return actualTypeAnnotationName;