1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ws.commons.schema;
18
19 import org.apache.ws.commons.schema.constants.Constants;
20 import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
21 import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
22 import org.apache.ws.commons.schema.resolver.URIResolver;
23 import org.apache.ws.commons.schema.utils.NamespacePrefixList;
24 import org.apache.ws.commons.schema.utils.TargetNamespaceValidator;
25 import org.w3c.dom.Document;
26 import org.w3c.dom.Element;
27 import org.w3c.dom.Node;
28 import org.xml.sax.InputSource;
29 import org.xml.sax.SAXException;
30
31 import javax.xml.namespace.QName;
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.transform.Source;
36 import javax.xml.transform.dom.DOMSource;
37 import javax.xml.transform.sax.SAXSource;
38 import javax.xml.transform.stream.StreamSource;
39 import java.io.IOException;
40 import java.io.Reader;
41 import java.util.*;
42
43
44
45
46
47 public final class XmlSchemaCollection {
48
49
50 private ExtensionRegistry extReg = new ExtensionRegistry();
51
52 public ExtensionRegistry getExtReg() {
53 return extReg;
54 }
55
56 public void setExtReg(ExtensionRegistry extReg) {
57 this.extReg = extReg;
58 }
59
60
61 static class SchemaKey {
62 private final String namespace;
63 private final String systemId;
64 SchemaKey(String pNamespace, String pSystemId) {
65 namespace = pNamespace == null ? Constants.NULL_NS_URI : pNamespace;
66 systemId = pSystemId == null ? "" : pSystemId;
67 }
68 String getNamespace() { return namespace; }
69 String getSystemId() { return systemId; }
70 public int hashCode() {
71 final int PRIME = 31;
72 return (PRIME + namespace.hashCode()) * PRIME + systemId.hashCode();
73 }
74 public boolean equals(Object obj) {
75 if (this == obj)
76 return true;
77 if (obj == null)
78 return false;
79 if (getClass() != obj.getClass())
80 return false;
81 final SchemaKey other = (SchemaKey) obj;
82 return namespace.equals(other.namespace) && systemId.equals(other.systemId);
83 }
84 public String toString() {
85 return Constants.NULL_NS_URI.equals(namespace) ?
86 systemId : ("{" + namespace + "}" + systemId);
87 }
88 }
89
90
91
92
93 private Map schemas = new HashMap();
94
95
96
97
98
99
100 String baseUri = null;
101
102
103
104 private NamespacePrefixList namespaceContext;
105
106
107
108
109
110 URIResolver schemaResolver = new DefaultURIResolver();
111
112 XmlSchema xsd = new XmlSchema(XmlSchema.SCHEMA_NS, this);
113
114
115
116
117 Stack stack = new Stack();
118
119
120
121
122
123
124 public void setBaseUri(String baseUri){
125 this.baseUri = baseUri;
126 }
127
128
129
130
131
132 public void setSchemaResolver(URIResolver schemaResolver) {
133 this.schemaResolver = schemaResolver;
134 }
135
136
137
138
139
140
141
142 public void init() {
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 addSimpleType(xsd, Constants.XSD_STRING.getLocalPart());
167 addSimpleType(xsd, Constants.XSD_BOOLEAN.getLocalPart());
168 addSimpleType(xsd, Constants.XSD_FLOAT.getLocalPart());
169 addSimpleType(xsd, Constants.XSD_DOUBLE.getLocalPart());
170 addSimpleType(xsd, Constants.XSD_QNAME.getLocalPart());
171 addSimpleType(xsd, Constants.XSD_DECIMAL.getLocalPart());
172 addSimpleType(xsd, Constants.XSD_DURATION.getLocalPart());
173 addSimpleType(xsd, Constants.XSD_DATE.getLocalPart());
174 addSimpleType(xsd, Constants.XSD_TIME.getLocalPart());
175 addSimpleType(xsd, Constants.XSD_DATETIME.getLocalPart());
176 addSimpleType(xsd, Constants.XSD_DAY.getLocalPart());
177 addSimpleType(xsd, Constants.XSD_MONTH.getLocalPart());
178 addSimpleType(xsd, Constants.XSD_MONTHDAY.getLocalPart());
179 addSimpleType(xsd, Constants.XSD_YEAR.getLocalPart());
180 addSimpleType(xsd, Constants.XSD_YEARMONTH.getLocalPart());
181 addSimpleType(xsd, Constants.XSD_NOTATION.getLocalPart());
182 addSimpleType(xsd, Constants.XSD_HEXBIN.getLocalPart());
183 addSimpleType(xsd, Constants.XSD_BASE64.getLocalPart());
184 addSimpleType(xsd, Constants.XSD_ANYURI.getLocalPart());
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 addSimpleType(xsd, Constants.XSD_LONG.getLocalPart());
217 addSimpleType(xsd, Constants.XSD_SHORT.getLocalPart());
218 addSimpleType(xsd, Constants.XSD_BYTE.getLocalPart());
219 addSimpleType(xsd, Constants.XSD_INTEGER.getLocalPart());
220 addSimpleType(xsd, Constants.XSD_INT.getLocalPart());
221 addSimpleType(xsd, Constants.XSD_POSITIVEINTEGER.getLocalPart());
222 addSimpleType(xsd, Constants.XSD_NEGATIVEINTEGER.getLocalPart());
223 addSimpleType(xsd, Constants.XSD_NONPOSITIVEINTEGER.getLocalPart());
224 addSimpleType(xsd, Constants.XSD_NONNEGATIVEINTEGER.getLocalPart());
225 addSimpleType(xsd, Constants.XSD_UNSIGNEDBYTE.getLocalPart());
226 addSimpleType(xsd, Constants.XSD_UNSIGNEDINT.getLocalPart());
227 addSimpleType(xsd, Constants.XSD_UNSIGNEDLONG.getLocalPart());
228 addSimpleType(xsd, Constants.XSD_UNSIGNEDSHORT.getLocalPart());
229
230
231 addSimpleType(xsd, Constants.XSD_NAME.getLocalPart());
232 addSimpleType(xsd, Constants.XSD_NORMALIZEDSTRING.getLocalPart());
233 addSimpleType(xsd, Constants.XSD_NCNAME.getLocalPart());
234 addSimpleType(xsd, Constants.XSD_NMTOKEN.getLocalPart());
235 addSimpleType(xsd, Constants.XSD_NMTOKENS.getLocalPart());
236 addSimpleType(xsd, Constants.XSD_ENTITY.getLocalPart());
237 addSimpleType(xsd, Constants.XSD_ENTITIES.getLocalPart());
238 addSimpleType(xsd, Constants.XSD_ID.getLocalPart());
239 addSimpleType(xsd, Constants.XSD_IDREF.getLocalPart());
240 addSimpleType(xsd, Constants.XSD_IDREFS.getLocalPart());
241 addSimpleType(xsd, Constants.XSD_LANGUAGE.getLocalPart());
242 addSimpleType(xsd, Constants.XSD_TOKEN.getLocalPart());
243
244 SchemaKey key = new SchemaKey(XmlSchema.SCHEMA_NS, null);
245 addSchema(key, xsd);
246
247
248
249
250
251
252 if (System.getProperty(Constants.SystemConstants.EXTENSION_REGISTRY_KEY)!= null){
253 try {
254 Class clazz = Class.forName(System.getProperty(Constants.SystemConstants.EXTENSION_REGISTRY_KEY));
255 this.extReg = (ExtensionRegistry)clazz.newInstance();
256 } catch (ClassNotFoundException e) {
257 System.err.println("The specified extension registry class cannot be found!");
258 } catch (InstantiationException e) {
259 System.err.println("The specified extension registry class cannot be instantiated!");
260 } catch (IllegalAccessException e) {
261 System.err.println("The specified extension registry class cannot be accessed!");
262 }
263 }
264 }
265
266 boolean containsSchema(SchemaKey pKey) {
267 return schemas.containsKey(pKey);
268 }
269
270 XmlSchema getSchema(SchemaKey pKey) {
271 return (XmlSchema) schemas.get(pKey);
272 }
273
274 void addSchema(SchemaKey pKey, XmlSchema pSchema) {
275 if (schemas.containsKey(pKey)) {
276 throw new IllegalStateException("A schema with target namespace "
277 + pKey.getNamespace() + " and system ID " + pKey.getSystemId()
278 + " is already present.");
279 }
280 schemas.put(pKey, pSchema);
281 }
282
283 private void addSimpleType(XmlSchema schema,String typeName){
284 XmlSchemaSimpleType type;
285 type = new XmlSchemaSimpleType(schema);
286 type.setName(typeName);
287 schema.addType(type);
288 }
289 public XmlSchema read(Reader r, ValidationEventHandler veh) {
290 return read(new InputSource(r), veh);
291 }
292
293 XmlSchema read(InputSource inputSource, ValidationEventHandler veh,
294 TargetNamespaceValidator namespaceValidator) {
295 try {
296 DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
297 docFac.setNamespaceAware(true);
298 DocumentBuilder builder = docFac.newDocumentBuilder();
299 Document doc = builder.parse(inputSource);
300 return read(doc, inputSource.getSystemId(), veh, namespaceValidator);
301 } catch (ParserConfigurationException e) {
302 throw new XmlSchemaException(e.getMessage());
303 } catch (IOException e) {
304 throw new XmlSchemaException(e.getMessage());
305 } catch (SAXException e) {
306 throw new XmlSchemaException(e.getMessage());
307 }
308 }
309
310 public XmlSchema read(InputSource inputSource, ValidationEventHandler veh) {
311 return read(inputSource, veh, null);
312 }
313
314 public XmlSchema read(Source source, ValidationEventHandler veh) {
315 if (source instanceof SAXSource) {
316 return read(((SAXSource) source).getInputSource(), veh);
317 } else if (source instanceof DOMSource) {
318 Node node = ((DOMSource) source).getNode();
319 if (node instanceof Document) {
320 node = ((Document) node).getDocumentElement();
321 }
322 return read((Document) node, veh);
323 } else if (source instanceof StreamSource) {
324 StreamSource ss = (StreamSource) source;
325 InputSource isource = new InputSource(ss.getSystemId());
326 isource.setByteStream(ss.getInputStream());
327 isource.setCharacterStream(ss.getReader());
328 isource.setPublicId(ss.getPublicId());
329 return read(isource, veh);
330 } else {
331 InputSource isource = new InputSource(source.getSystemId());
332 return read(isource, veh);
333 }
334 }
335
336 public XmlSchema read(Document doc, ValidationEventHandler veh) {
337 SchemaBuilder builder = new SchemaBuilder(this, null);
338 return builder.build(doc, null, veh);
339 }
340
341 public XmlSchema read(Element elem) {
342 SchemaBuilder builder = new SchemaBuilder(this, null);
343 return builder.handleXmlSchemaElement(elem, null);
344 }
345
346 public XmlSchema read(Document doc, String uri, ValidationEventHandler veh) {
347 return read(doc, uri, veh, null);
348 }
349
350 public XmlSchema read(Document doc, String uri, ValidationEventHandler veh,
351 TargetNamespaceValidator validator) {
352 SchemaBuilder builder = new SchemaBuilder(this, validator);
353 return builder.build(doc, uri, veh);
354 }
355
356 public XmlSchema read(Element elem, String uri) {
357 SchemaBuilder builder = new SchemaBuilder(this, null);
358 return builder.handleXmlSchemaElement(elem, uri);
359 }
360
361
362
363
364 public XmlSchemaCollection() {
365 init();
366 }
367
368
369
370
371
372
373
374
375
376
377 public XmlSchema[] getXmlSchema(String systemId) {
378 if (systemId == null) {
379 systemId = "";
380 }
381 final List result = new ArrayList();
382 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
383 Map.Entry entry = (Map.Entry) iter.next();
384 if (((SchemaKey) entry.getKey()).getSystemId().equals(systemId)) {
385 result.add(entry.getValue());
386 }
387 }
388 return (XmlSchema[]) result.toArray(new XmlSchema[result.size()]);
389 }
390
391
392
393
394 public XmlSchema[] getXmlSchemas() {
395 Collection c = schemas.values();
396 return (XmlSchema[]) c.toArray(new XmlSchema[c.size()]);
397 }
398
399 public XmlSchemaElement getElementByQName(QName qname) {
400 String uri = qname.getNamespaceURI();
401 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
402 Map.Entry entry = (Map.Entry) iter.next();
403 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
404 XmlSchemaElement element = ((XmlSchema) entry.getValue()).getElementByName(qname);
405 if (element != null) {
406 return element;
407 }
408 }
409 }
410 return null;
411 }
412
413 public XmlSchemaType getTypeByQName(QName schemaTypeName) {
414 String uri = schemaTypeName.getNamespaceURI();
415 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
416 Map.Entry entry = (Map.Entry) iter.next();
417 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
418 XmlSchemaType type = ((XmlSchema) entry.getValue()).getTypeByName(schemaTypeName);
419 if (type != null) {
420 return type;
421 }
422 }
423 }
424 return null;
425 }
426
427 Map unresolvedTypes = new HashMap();
428
429 void addUnresolvedType(QName type, TypeReceiver receiver) {
430 ArrayList receivers = (ArrayList)unresolvedTypes.get(type);
431 if (receivers == null) {
432 receivers = new ArrayList();
433 unresolvedTypes.put(type, receivers);
434 }
435 receivers.add(receiver);
436 }
437
438 void resolveType(QName typeName, XmlSchemaType type) {
439 ArrayList receivers = (ArrayList)unresolvedTypes.get(typeName);
440 if (receivers == null)
441 return;
442 for (Iterator i = receivers.iterator(); i.hasNext();) {
443 TypeReceiver receiver = (TypeReceiver) i.next();
444 receiver.setType(type);
445 }
446 unresolvedTypes.remove(typeName);
447 }
448
449 public NamespacePrefixList getNamespaceContext() {
450 return namespaceContext;
451 }
452
453 public void setNamespaceContext(NamespacePrefixList namespaceContext) {
454 this.namespaceContext = namespaceContext;
455 }
456
457 public void push(SchemaKey pKey){
458 stack.push(pKey);
459 }
460
461 public void pop(){
462 stack.pop();
463 }
464
465 public boolean check(SchemaKey pKey){
466 return (stack.indexOf(pKey)==-1);
467 }
468 }