Initial commit
[mono.git] / mcs / class / referencesource / System.Xml / System / Xml / Schema / BaseProcessor.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="BaseProcessor.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>  
5 // <owner current="true" primary="true">[....]</owner>                                                              
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Schema {
9
10     using System.Collections;
11     using System.Text; 
12     using System.Diagnostics;
13
14     internal class BaseProcessor {
15         XmlNameTable nameTable;
16         SchemaNames schemaNames; 
17         ValidationEventHandler eventHandler;
18         XmlSchemaCompilationSettings compilationSettings; 
19         int errorCount = 0;
20         string NsXml;
21
22         public BaseProcessor(XmlNameTable nameTable, SchemaNames schemaNames, ValidationEventHandler eventHandler)
23             : this(nameTable, schemaNames, eventHandler, new XmlSchemaCompilationSettings()) {} //Use the default for XmlSchemaCollection
24
25         public BaseProcessor(XmlNameTable nameTable, SchemaNames schemaNames, ValidationEventHandler eventHandler, XmlSchemaCompilationSettings compilationSettings) {
26             Debug.Assert(nameTable != null);
27             this.nameTable = nameTable;
28             this.schemaNames = schemaNames;
29             this.eventHandler = eventHandler;
30             this.compilationSettings = compilationSettings;
31             NsXml = nameTable.Add(XmlReservedNs.NsXml);
32         }
33
34         protected XmlNameTable NameTable {
35             get { return nameTable; }
36         }
37
38         protected SchemaNames SchemaNames {
39             get { 
40                 if (schemaNames == null) {
41                     schemaNames = new SchemaNames(nameTable);
42                 }
43                 return schemaNames; 
44             }
45         }
46
47         protected ValidationEventHandler EventHandler {
48             get { return eventHandler; }
49         }
50
51         protected XmlSchemaCompilationSettings CompilationSettings {
52             get { return compilationSettings; }
53         }
54
55         protected bool HasErrors {
56             get { return errorCount != 0; }
57         }
58
59         protected void AddToTable(XmlSchemaObjectTable table, XmlQualifiedName qname, XmlSchemaObject item) {
60             if (qname.Name.Length == 0) {
61                 return;
62             }
63             XmlSchemaObject existingObject = (XmlSchemaObject)table[qname];
64             
65             if (existingObject != null) {
66                 if (existingObject == item) { 
67                     return;
68                 }
69                 string code = Res.Sch_DupGlobalElement; 
70                 if (item is XmlSchemaAttributeGroup) {
71                     string ns = nameTable.Add(qname.Namespace);
72                     if (Ref.Equal(ns, NsXml)) { //Check for xml namespace
73                         XmlSchema schemaForXmlNS = Preprocessor.GetBuildInSchema();
74                         XmlSchemaObject builtInAttributeGroup = schemaForXmlNS.AttributeGroups[qname];
75                         if ((object)existingObject == (object)builtInAttributeGroup) {
76                             table.Insert(qname, item);
77                             return;
78                         }
79                         else if ((object)item == (object)builtInAttributeGroup) { //trying to overwrite customer's component with built-in, ignore built-in
80                             return;
81                         }
82                     }
83                     else if (IsValidAttributeGroupRedefine(existingObject, item, table)){ //check for redefines
84                         return;
85                     }
86                     code = Res.Sch_DupAttributeGroup;
87                 } 
88                 else if (item is XmlSchemaAttribute) {
89                     string ns = nameTable.Add(qname.Namespace);
90                     if (Ref.Equal(ns, NsXml)) {
91                         XmlSchema schemaForXmlNS = Preprocessor.GetBuildInSchema();
92                         XmlSchemaObject builtInAttribute = schemaForXmlNS.Attributes[qname];
93                         if ((object)existingObject == (object)builtInAttribute) { //replace built-in one
94                             table.Insert(qname, item);
95                             return;
96                         }
97                         else if ((object)item == (object)builtInAttribute) { //trying to overwrite customer's component with built-in, ignore built-in
98                             return;
99                         }
100                     }
101                     code = Res.Sch_DupGlobalAttribute;
102                 } 
103                 else if (item is XmlSchemaSimpleType) {
104                     if (IsValidTypeRedefine(existingObject, item, table)) {
105                         return;
106                     }
107                     code = Res.Sch_DupSimpleType;
108                 } 
109                 else if (item is XmlSchemaComplexType) {
110                     if (IsValidTypeRedefine(existingObject, item, table)) {
111                         return;
112                     }
113                     code = Res.Sch_DupComplexType;
114                 }
115                 else if (item is XmlSchemaGroup) {
116                     if (IsValidGroupRedefine(existingObject, item, table)){ //check for redefines
117                         return;
118                     }
119                     code = Res.Sch_DupGroup;
120                 } 
121                 else if (item is XmlSchemaNotation) {
122                     code = Res.Sch_DupNotation;
123                 }
124                 else if (item is XmlSchemaIdentityConstraint) {
125                     code = Res.Sch_DupIdentityConstraint;
126                 }
127                 else {
128                     Debug.Assert(item is XmlSchemaElement);
129                 }
130                 SendValidationEvent(code, qname.ToString(), item);
131             } 
132             else {
133                 table.Add(qname, item);
134             }
135         }
136
137         private bool IsValidAttributeGroupRedefine(XmlSchemaObject existingObject, XmlSchemaObject item, XmlSchemaObjectTable table) {
138             XmlSchemaAttributeGroup attGroup = item as XmlSchemaAttributeGroup;
139             XmlSchemaAttributeGroup existingAttGroup = existingObject as XmlSchemaAttributeGroup;
140             if (existingAttGroup == attGroup.Redefined) { //attribute group is the redefinition of existingObject
141                 if (existingAttGroup.AttributeUses.Count == 0) { //If the existing one is not already compiled, then replace.
142                     table.Insert(attGroup.QualifiedName, attGroup); //Update with redefined entry                       
143                     return true;
144                 }
145             }
146             else if (existingAttGroup.Redefined == attGroup) { //Redefined type already exists in the set, original type is added after redefined type, ignore the original type
147                 return true;
148             }
149             return false;
150         }
151
152         private bool IsValidGroupRedefine(XmlSchemaObject existingObject, XmlSchemaObject item, XmlSchemaObjectTable table) {
153             XmlSchemaGroup group = item as XmlSchemaGroup;
154             XmlSchemaGroup existingGroup = existingObject as XmlSchemaGroup;
155             if (existingGroup == group.Redefined) { //group is the redefinition of existingObject
156                 if (existingGroup.CanonicalParticle == null) { //If the existing one is not already compiled, then replace.
157                     table.Insert(group.QualifiedName, group); //Update with redefined entry                     
158                     return true;
159                 }
160             }
161             else if (existingGroup.Redefined == group) { //Redefined type already exists in the set, original type is added after redefined type, ignore the original type
162                 return true;
163             }
164             return false;
165         }
166
167         private bool IsValidTypeRedefine(XmlSchemaObject existingObject, XmlSchemaObject item, XmlSchemaObjectTable table) {
168             XmlSchemaType schemaType = item as XmlSchemaType;
169             XmlSchemaType existingType = existingObject as XmlSchemaType;
170             if (existingType == schemaType.Redefined) { //schemaType is the redefinition of existingObject
171                 if (existingType.ElementDecl == null) { //If the existing one is not already compiled, then replace.
172                     table.Insert(schemaType.QualifiedName, schemaType); //Update with redefined entry                   
173                     return true;
174                 }
175             }
176             else if (existingType.Redefined == schemaType) { //Redefined type already exists in the set, original type is added after redefined type, ignore the original type
177                 return true;
178             }
179             return false;
180         }
181
182         protected void SendValidationEvent(string code, XmlSchemaObject source) {
183             SendValidationEvent(new XmlSchemaException(code, source), XmlSeverityType.Error);
184         }
185
186         protected void SendValidationEvent(string code, string msg, XmlSchemaObject source) {
187             SendValidationEvent(new XmlSchemaException(code, msg, source), XmlSeverityType.Error);
188         }
189
190         protected void SendValidationEvent(string code, string msg1, string msg2, XmlSchemaObject source) {
191             SendValidationEvent(new XmlSchemaException(code, new string[] { msg1, msg2 }, source), XmlSeverityType.Error);
192         }
193
194         protected void SendValidationEvent(string code, string[] args, Exception innerException, XmlSchemaObject source) {
195             SendValidationEvent(new XmlSchemaException(code, args, innerException, source.SourceUri, source.LineNumber, source.LinePosition, source), XmlSeverityType.Error);
196         }
197     
198         protected void SendValidationEvent(string code, string msg1, string msg2, string sourceUri, int lineNumber, int linePosition) {
199             SendValidationEvent(new XmlSchemaException(code, new string[] { msg1, msg2 }, sourceUri, lineNumber, linePosition), XmlSeverityType.Error);
200         }
201         
202         protected void SendValidationEvent(string code, XmlSchemaObject source, XmlSeverityType severity) {
203             SendValidationEvent(new XmlSchemaException(code, source), severity);
204         }
205
206         protected void SendValidationEvent(XmlSchemaException e) {
207             SendValidationEvent(e, XmlSeverityType.Error);
208         }
209
210         protected void SendValidationEvent(string code, string msg, XmlSchemaObject source, XmlSeverityType severity) {
211             SendValidationEvent(new XmlSchemaException(code, msg, source), severity);
212         }
213
214         protected void SendValidationEvent(XmlSchemaException e, XmlSeverityType severity) {
215             if (severity == XmlSeverityType.Error) {
216                 errorCount ++;
217             }
218             if (eventHandler != null) {
219                 eventHandler(null, new ValidationEventArgs(e, severity));
220             }
221             else if (severity == XmlSeverityType.Error) {
222                 throw e;
223             }
224         }
225
226         protected void SendValidationEventNoThrow(XmlSchemaException e, XmlSeverityType severity) {
227             if (severity == XmlSeverityType.Error) {
228                 errorCount ++;
229             }
230             if (eventHandler != null) {
231                 eventHandler(null, new ValidationEventArgs(e, severity));
232             }
233         }
234     };
235
236 } // namespace System.Xml