[bcl] Don't build not installed mobile assemblies
[mono.git] / mcs / class / System.Runtime.Serialization / ReferenceSources / SchemaExporter_mobile.cs
1
2 namespace System.Runtime.Serialization
3 {
4         using System;
5         using System.Collections;
6         using System.Collections.Generic;
7         using System.Collections.ObjectModel;
8         using System.Diagnostics;
9         using System.Globalization;
10         using System.IO;
11         using System.Reflection;
12         using System.Runtime.Diagnostics;
13         using System.Security;
14         using System.Xml;
15         using System.Xml.Schema;
16         using System.Xml.Serialization;
17         using System.Runtime.Serialization.Diagnostics;
18
19         class SchemaExporter
20         {
21         internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
22         {
23             if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot))
24                 return;
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))));
30         }
31
32         internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
33         {
34             xsdType = null;
35             hasRoot = true;
36             if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
37             {
38                 string name = null;
39                 if (type == Globals.TypeOfXmlElement)
40                 {
41                     xsdType = CreateAnyElementType();
42                     name = "XmlElement";
43                     hasRoot = false;
44                 }
45                 else
46                 {
47                     xsdType = CreateAnyType();
48                     name = "ArrayOfXmlNode";
49                     hasRoot = true;
50                 }
51                 typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
52                 return true;
53             }
54             typeName = null;
55             return false;
56         }
57
58         static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
59         {
60             xsdType = null;
61             hasRoot = true;
62             object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
63             if (attrs == null || attrs.Length == 0)
64             {
65                 stableName = DataContract.GetDefaultStableName(clrType);
66                 return false;
67             }
68
69             XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
70             if (provider.IsAny)
71             {
72                 xsdType = CreateAnyElementType();
73                 hasRoot = false;
74             }
75             string methodName = provider.MethodName;
76             if (methodName == null || methodName.Length == 0)
77             {
78                 if (!provider.IsAny)
79                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType))));
80                 stableName = DataContract.GetDefaultStableName(clrType);
81             }
82             else
83             {
84                 MethodInfo getMethod = clrType.GetMethod(methodName,  /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
85                 if (getMethod == null)
86                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
87
88                 if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType)))
89                     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))));
90
91                 object typeInfo = getMethod.Invoke(null, new object[] { schemas });
92
93                 if (provider.IsAny)
94                 {
95                     if (typeInfo != null)
96                         throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName)));
97                     stableName = DataContract.GetDefaultStableName(clrType);
98                 }
99                 else if (typeInfo == null)
100                 {
101                     xsdType = CreateAnyElementType();
102                     hasRoot = false;
103                     stableName = DataContract.GetDefaultStableName(clrType);
104                 }
105                 else
106                 {
107                     XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
108                     if (providerXsdType != null)
109                     {
110                         string typeName = providerXsdType.Name;
111                         string typeNs = null;
112                         if (typeName == null || typeName.Length == 0)
113                         {
114                             DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs);
115                             stableName = new XmlQualifiedName(typeName, typeNs);
116                             providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
117                             xsdType = providerXsdType;
118                         }
119                         else
120                         {
121                             foreach (XmlSchema schema in schemas.Schemas())
122                             {
123                                 foreach (XmlSchemaObject schemaItem in schema.Items)
124                                 {
125                                     if ((object)schemaItem == (object)providerXsdType)
126                                     {
127                                         typeNs = schema.TargetNamespace;
128                                         if (typeNs == null)
129                                             typeNs = String.Empty;
130                                         break;
131                                     }
132                                 }
133                                 if (typeNs != null)
134                                     break;
135                             }
136                             if (typeNs == null)
137                                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
138                             stableName = new XmlQualifiedName(typeName, typeNs);
139                         }
140                     }
141                     else
142                         stableName = (XmlQualifiedName)typeInfo;
143                 }
144             }
145             return true;
146         }
147
148         static XmlSchemaComplexType CreateAnyElementType()
149         {
150             XmlSchemaComplexType anyElementType = new XmlSchemaComplexType();
151             anyElementType.IsMixed = false;
152             anyElementType.Particle = new XmlSchemaSequence();
153             XmlSchemaAny any = new XmlSchemaAny();
154             any.MinOccurs = 0;
155             any.ProcessContents = XmlSchemaContentProcessing.Lax;
156             ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any);
157             return anyElementType;
158         }
159
160         static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes)
161         {
162             if (nodes == null || nodes.Length == 0)
163                 return null;
164             bool hasAnnotation = false;
165             for (int i = 0; i < nodes.Length; i++)
166                 if (nodes[i] != null)
167                 {
168                     hasAnnotation = true;
169                     break;
170                 }
171             if (!hasAnnotation)
172                 return null;
173
174             XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
175             XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
176             annotation.Items.Add(appInfo);
177             appInfo.Markup = nodes;
178             return annotation;
179         }
180
181         static XmlSchemaComplexType CreateAnyType()
182         {
183             XmlSchemaComplexType anyType = new XmlSchemaComplexType();
184             anyType.IsMixed = true;
185             anyType.Particle = new XmlSchemaSequence();
186             XmlSchemaAny any = new XmlSchemaAny();
187             any.MinOccurs = 0;
188             any.MaxOccurs = Decimal.MaxValue;
189             any.ProcessContents = XmlSchemaContentProcessing.Lax;
190             ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
191             anyType.AnyAttribute = new XmlSchemaAnyAttribute();
192             return anyType;
193         }
194
195         static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc)
196         {
197             XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
198
199             XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
200             nameAttribute.Value = typeName.Name;
201             actualTypeElement.Attributes.Append(nameAttribute);
202
203             XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
204             nsAttribute.Value = typeName.Namespace;
205             actualTypeElement.Attributes.Append(nsAttribute);
206
207             return actualTypeElement;
208         }
209
210         static XmlQualifiedName actualTypeAnnotationName;
211         internal static XmlQualifiedName ActualTypeAnnotationName
212         {
213             get
214             {
215                 if (actualTypeAnnotationName == null)
216                     actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace);
217                 return actualTypeAnnotationName;
218             }
219         }
220         }
221 }
222