New test.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaKeyref.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.Xml;\r
26 using System.Xml.Serialization;\r
27 \r
28 namespace System.Xml.Schema\r
29 {\r
30         /// <summary>\r
31         /// Summary description for XmlSchemaKeyref.\r
32         /// </summary>\r
33         public class XmlSchemaKeyref : XmlSchemaIdentityConstraint\r
34         {\r
35                 private XmlQualifiedName refer;\r
36                 const string xmlname = "keyref";\r
37                 private XmlSchemaIdentityConstraint target;\r
38 \r
39                 public XmlSchemaKeyref()\r
40                 {\r
41                         refer = XmlQualifiedName.Empty;\r
42                 }\r
43 \r
44                 [System.Xml.Serialization.XmlAttribute("refer")]\r
45                 public XmlQualifiedName Refer\r
46                 {\r
47                         get{ return  refer; } \r
48                         set{ refer = value; }\r
49                 }\r
50 \r
51                 internal XmlSchemaIdentityConstraint Target\r
52                 {\r
53                         get { return target; }\r
54                 }\r
55 \r
56                 /// <remarks>\r
57                 /// 1. name must be present\r
58                 /// 2. selector and field must be present\r
59                 /// 3. refer must be present\r
60                 /// </remarks>\r
61                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
62                 {\r
63                         base.Compile(h, schema);\r
64 \r
65                         if(refer == null || refer.IsEmpty)\r
66                                 error(h,"refer must be present");\r
67                         else if(!XmlSchemaUtil.CheckQName(refer))\r
68                                 error(h,"Refer is not a valid XmlQualifiedName");\r
69 \r
70                         return errorCount;\r
71                 }\r
72                 \r
73                 internal override int Validate (ValidationEventHandler h, XmlSchema schema)\r
74                 {\r
75                         // Find target key\r
76                         XmlSchemaIdentityConstraint target = schema.NamedIdentities [this.Refer] as XmlSchemaIdentityConstraint;\r
77                         if (target == null)\r
78                                 error (h, "Target key was not found.");\r
79                         else if (target is XmlSchemaKeyref)\r
80                                 error (h, "Target identity constraint was keyref.");\r
81                         else if (target.Fields.Count != this.Fields.Count)\r
82                                 error (h, "Target identity constraint has different number of fields.");\r
83                         else\r
84                                 this.target = target;\r
85                         return errorCount;\r
86                 }\r
87 \r
88                 /*\r
89                 internal new void error(ValidationEventHandler handle, string message)\r
90                 {\r
91                         errorCount++;\r
92                         ValidationHandler.RaiseValidationError(handle, this, message);\r
93                 }\r
94                 */\r
95                 //<key \r
96                 //  id = ID \r
97                 //  name = NCName \r
98                 //  refer = QName \r
99                 //  {any attributes with non-schema namespace . . .}>\r
100                 //  Content: (annotation?, (selector, field+))\r
101                 //</key>\r
102                 internal static XmlSchemaKeyref Read(XmlSchemaReader reader, ValidationEventHandler h)\r
103                 {\r
104                         XmlSchemaKeyref keyref = new XmlSchemaKeyref();\r
105                         reader.MoveToElement();\r
106 \r
107                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
108                         {\r
109                                 error(h,"Should not happen :1: XmlSchemaKeyref.Read, name="+reader.Name,null);\r
110                                 reader.Skip();\r
111                                 return null;\r
112                         }\r
113 \r
114                         keyref.LineNumber = reader.LineNumber;\r
115                         keyref.LinePosition = reader.LinePosition;\r
116                         keyref.SourceUri = reader.BaseURI;\r
117 \r
118                         while(reader.MoveToNextAttribute())\r
119                         {\r
120                                 if(reader.Name == "id")\r
121                                 {\r
122                                         keyref.Id = reader.Value;\r
123                                 }\r
124                                 else if(reader.Name == "name")\r
125                                 {\r
126                                         keyref.Name = reader.Value;\r
127                                 }\r
128                                 else if(reader.Name == "refer")\r
129                                 {\r
130                                         Exception innerex;\r
131                                         keyref.refer = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
132                                         if(innerex != null)\r
133                                                 error(h, reader.Value + " is not a valid value for refer attribute",innerex);\r
134                                 }\r
135                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
136                                 {\r
137                                         error(h,reader.Name + " is not a valid attribute for keyref",null);\r
138                                 }\r
139                                 else\r
140                                 {\r
141                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,keyref);\r
142                                 }\r
143                         }\r
144                         \r
145                         reader.MoveToElement();\r
146                         if(reader.IsEmptyElement)\r
147                                 return keyref;\r
148 \r
149                         //  Content: annotation?, selector, field+\r
150                         int level = 1;\r
151                         while(reader.ReadNextElement())\r
152                         {\r
153                                 if(reader.NodeType == XmlNodeType.EndElement)\r
154                                 {\r
155                                         if(reader.LocalName != xmlname)\r
156                                                 error(h,"Should not happen :2: XmlSchemaKeyref.Read, name="+reader.Name,null);\r
157                                         break;\r
158                                 }\r
159                                 if(level <= 1 && reader.LocalName == "annotation")\r
160                                 {\r
161                                         level = 2; //Only one annotation\r
162                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
163                                         if(annotation != null)\r
164                                                 keyref.Annotation = annotation;\r
165                                         continue;\r
166                                 }\r
167                                 if(level <= 2 && reader.LocalName == "selector")\r
168                                 {\r
169                                         level = 3;\r
170                                         XmlSchemaXPath selector = XmlSchemaXPath.Read(reader,h,"selector");\r
171                                         if(selector != null)\r
172                                                 keyref.Selector = selector;\r
173                                         continue;\r
174                                 }\r
175                                 if(level <= 3 && reader.LocalName == "field")\r
176                                 {\r
177                                         level = 3;\r
178                                         if(keyref.Selector == null)\r
179                                                 error(h,"selector must be defined before field declarations",null);\r
180                                         XmlSchemaXPath field = XmlSchemaXPath.Read(reader,h,"field");\r
181                                         if(field != null)\r
182                                                 keyref.Fields.Add(field);\r
183                                         continue;\r
184                                 }\r
185                                 reader.RaiseInvalidElementError();\r
186                         }\r
187                         return keyref;\r
188                 }\r
189         }\r
190 }\r