New test.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaSimpleTypeUnion.cs
1 // Author: Dwivedi, Ajay kumar\r
2 //            Adwiv@Yahoo.com\r
3
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24 using System;\r
25 using System.Collections;\r
26 using System.Xml;\r
27 using System.Xml.Serialization;\r
28 \r
29 namespace System.Xml.Schema\r
30 {\r
31         /// <summary>\r
32         /// Summary description for XmlSchemaSimpleTypeUnion.\r
33         /// </summary>\r
34         public class XmlSchemaSimpleTypeUnion : XmlSchemaSimpleTypeContent\r
35         {\r
36                 private XmlSchemaObjectCollection baseTypes;\r
37                 private XmlQualifiedName[] memberTypes;\r
38                 const string xmlname = "union";\r
39                 private object [] validatedTypes;\r
40 #if NET_2_0\r
41                 private XmlSchemaSimpleType [] validatedSchemaTypes;\r
42 #endif\r
43 \r
44                 public XmlSchemaSimpleTypeUnion()\r
45                 {\r
46                         baseTypes = new XmlSchemaObjectCollection();\r
47                 }\r
48 \r
49                 [XmlElement("simpleType",typeof(XmlSchemaSimpleType))]\r
50                 public XmlSchemaObjectCollection BaseTypes \r
51                 {\r
52                         get{ return baseTypes; }\r
53                 }\r
54 \r
55                 [System.Xml.Serialization.XmlAttribute("memberTypes")]\r
56                 public XmlQualifiedName[] MemberTypes\r
57                 {\r
58                         get{ return  memberTypes; } \r
59                         set{ memberTypes = value; }\r
60                 }\r
61 \r
62 #if NET_2_0\r
63                 [XmlIgnore]\r
64                 public XmlSchemaSimpleType [] BaseMemberTypes {\r
65                         get { return validatedSchemaTypes; }\r
66                 }\r
67 #endif\r
68 \r
69                 internal object [] ValidatedTypes\r
70                 {\r
71                         get { return validatedTypes; }\r
72                 }\r
73 \r
74                 /// <remarks>\r
75                 /// 1. Circular union type definition is disallowed. (WTH is this?)\r
76                 /// 2. id must be a valid ID\r
77                 /// </remarks>\r
78                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
79                 {\r
80                         // If this is already compiled this time, simply skip.\r
81                         if (CompilationId == schema.CompilationId)\r
82                                 return 0;\r
83 \r
84 #if NET_2_0\r
85                         foreach (XmlSchemaObject obj in BaseTypes)\r
86                                 obj.Parent = this;\r
87 #endif\r
88 \r
89                         errorCount = 0;\r
90 \r
91                         int count = BaseTypes.Count;\r
92 \r
93                         foreach(XmlSchemaObject obj in baseTypes)\r
94                         {\r
95                                 if(obj != null && obj is XmlSchemaSimpleType)\r
96                                 {\r
97                                         XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;\r
98                                         errorCount += stype.Compile(h, schema);\r
99                                 }\r
100                                 else\r
101                                 {\r
102                                         error(h, "baseTypes can't have objects other than a simpletype");\r
103                                 }\r
104                         }\r
105                         \r
106                         if(memberTypes!=null)\r
107                         {\r
108                                 for(int i=0; i< memberTypes.Length; i++)\r
109                                 {\r
110                                         if(memberTypes[i] == null || !XmlSchemaUtil.CheckQName(MemberTypes[i]))\r
111                                         {\r
112                                                 error (h,"Invalid membertype");\r
113                                                 memberTypes[i] = XmlQualifiedName.Empty;\r
114                                         }\r
115                                         else\r
116                                         {\r
117                                                 count += MemberTypes.Length;\r
118                                         }\r
119                                 }\r
120                         }\r
121 \r
122                         if(count == 0)\r
123                                 error(h, "Atleast one simpletype or membertype must be present");\r
124 \r
125                         XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
126 \r
127                         \r
128 \r
129                         this.CompilationId = schema.CompilationId;\r
130                         return errorCount;\r
131                 }\r
132                 \r
133                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
134                 {\r
135                         if (IsValidated (schema.ValidationId))\r
136                                 return errorCount;\r
137 \r
138                         ArrayList al = new ArrayList ();\r
139                         // Validate MemberTypes\r
140                         if (MemberTypes != null) {\r
141                                 foreach (XmlQualifiedName memberTypeName in MemberTypes) {\r
142                                         object type = null;\r
143                                         XmlSchemaType xstype = schema.FindSchemaType (memberTypeName) as XmlSchemaSimpleType;\r
144                                         if (xstype != null) {\r
145                                                 errorCount += xstype.Validate (h, schema);\r
146                                                 type = xstype;\r
147                                         } else if (memberTypeName == XmlSchemaComplexType.AnyTypeName) {\r
148                                                 type = XmlSchemaSimpleType.AnySimpleType;
149                                         } else if (memberTypeName.Namespace == XmlSchema.Namespace ||\r
150                                                 memberTypeName.Namespace == XmlSchema.XdtNamespace) {\r
151                                                 type = XmlSchemaDatatype.FromName (memberTypeName);\r
152                                                 if (type == null)\r
153                                                         error (h, "Invalid schema type name was specified: " + memberTypeName);\r
154                                         }\r
155                                         // otherwise, it might be missing sub components.\r
156                                         else if (!schema.IsNamespaceAbsent (memberTypeName.Namespace))\r
157                                                 error (h, "Referenced base schema type " + memberTypeName + " was not found in the corresponding schema.");\r
158 \r
159                                         al.Add (type);\r
160                                 }\r
161                         }\r
162                         if (BaseTypes != null) {\r
163                                 foreach (XmlSchemaSimpleType st in BaseTypes) {\r
164                                         st.Validate (h, schema);\r
165                                         al.Add (st);\r
166                                 }\r
167                         }\r
168                         this.validatedTypes = al.ToArray ();\r
169 \r
170 #if NET_2_0\r
171                         if (validatedTypes != null) {\r
172                                 validatedSchemaTypes = new XmlSchemaSimpleType [validatedTypes.Length];\r
173                                 for (int i = 0; i < validatedTypes.Length; i++) {\r
174                                         object t = validatedTypes [i];\r
175                                         XmlSchemaSimpleType st = t as XmlSchemaSimpleType;\r
176                                         if (st == null && t != null)\r
177                                                 st = XmlSchemaType.GetBuiltInSimpleType (((XmlSchemaDatatype) t).TypeCode);\r
178                                         validatedSchemaTypes [i] = st;\r
179                                 }\r
180                         }\r
181 #endif\r
182 \r
183                         ValidationId = schema.ValidationId;\r
184                         return errorCount;\r
185                 }\r
186 \r
187                 //<union \r
188                 //  id = ID \r
189                 //  memberTypes = List of QName \r
190                 //  {any attributes with non-schema namespace . . .}>\r
191                 //  Content: (annotation?, (simpleType*))\r
192                 //</union>\r
193                 internal static XmlSchemaSimpleTypeUnion Read(XmlSchemaReader reader, ValidationEventHandler h)\r
194                 {\r
195                         XmlSchemaSimpleTypeUnion union = new XmlSchemaSimpleTypeUnion();\r
196                         reader.MoveToElement();\r
197 \r
198                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
199                         {\r
200                                 error(h,"Should not happen :1: XmlSchemaSimpleTypeUnion.Read, name="+reader.Name,null);\r
201                                 reader.Skip();\r
202                                 return null;\r
203                         }\r
204 \r
205                         union.LineNumber = reader.LineNumber;\r
206                         union.LinePosition = reader.LinePosition;\r
207                         union.SourceUri = reader.BaseURI;\r
208 \r
209                         //Read Attributes\r
210                         while(reader.MoveToNextAttribute())\r
211                         {\r
212                                 if(reader.Name == "id")\r
213                                 {\r
214                                         union.Id = reader.Value;\r
215                                 }\r
216                                 else if(reader.Name == "memberTypes")\r
217                                 {\r
218                                         Exception innerEx;\r
219                                         string[] names = XmlSchemaUtil.SplitList(reader.Value);\r
220                                         union.memberTypes = new XmlQualifiedName[names.Length];\r
221                                         for(int i=0;i<names.Length;i++)\r
222                                         {\r
223                                                 union.memberTypes[i] = XmlSchemaUtil.ToQName(reader,names[i],out innerEx);\r
224                                                 if(innerEx != null)\r
225                                                         error(h,"'"+names[i] + "' is not a valid memberType",innerEx);\r
226                                         }\r
227                                 }\r
228                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
229                                 {\r
230                                         error(h,reader.Name + " is not a valid attribute for union",null);\r
231                                 }\r
232                                 else\r
233                                 {\r
234                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,union);\r
235                                 }\r
236                         }\r
237                         \r
238                         reader.MoveToElement();\r
239                         if(reader.IsEmptyElement)\r
240                                 return union;\r
241 \r
242                         //  Content: annotation?, simpleType*\r
243                         int level = 1;\r
244                         while(reader.ReadNextElement())\r
245                         {\r
246                                 if(reader.NodeType == XmlNodeType.EndElement)\r
247                                 {\r
248                                         if(reader.LocalName != xmlname)\r
249                                                 error(h,"Should not happen :2: XmlSchemaSimpleTypeUnion.Read, name="+reader.Name,null);\r
250                                         break;\r
251                                 }\r
252                                 if(level <= 1 && reader.LocalName == "annotation")\r
253                                 {\r
254                                         level = 2; //Only one annotation\r
255                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
256                                         if(annotation != null)\r
257                                                 union.Annotation = annotation;\r
258                                         continue;\r
259                                 }\r
260                                 if(level <=2 && reader.LocalName == "simpleType")\r
261                                 {\r
262                                         level = 2;\r
263                                         XmlSchemaSimpleType stype = XmlSchemaSimpleType.Read(reader,h);\r
264                                         if(stype != null)\r
265                                                 union.baseTypes.Add(stype);\r
266                                         continue;\r
267                                 }\r
268                                 reader.RaiseInvalidElementError();\r
269                         }\r
270                         return union;\r
271                 }\r
272 \r
273         }\r
274 }\r