1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.commons.schema;
21
22 import java.io.IOException;
23 import java.io.Reader;
24 import java.security.PrivilegedActionException;
25 import java.security.PrivilegedExceptionAction;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Stack;
33
34 import javax.xml.namespace.QName;
35 import javax.xml.parsers.DocumentBuilder;
36 import javax.xml.parsers.DocumentBuilderFactory;
37 import javax.xml.parsers.ParserConfigurationException;
38 import javax.xml.transform.Source;
39 import javax.xml.transform.dom.DOMSource;
40 import javax.xml.transform.sax.SAXSource;
41 import javax.xml.transform.stream.StreamSource;
42
43 import org.apache.ws.commons.schema.constants.Constants;
44 import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
45 import org.apache.ws.commons.schema.resolver.CollectionURIResolver;
46 import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
47 import org.apache.ws.commons.schema.resolver.URIResolver;
48 import org.apache.ws.commons.schema.utils.DOMUtil;
49 import org.apache.ws.commons.schema.utils.NamespacePrefixList;
50 import org.apache.ws.commons.schema.utils.TargetNamespaceValidator;
51 import org.w3c.dom.Document;
52 import org.w3c.dom.Element;
53 import org.w3c.dom.Node;
54 import org.xml.sax.InputSource;
55 import org.xml.sax.SAXException;
56
57
58
59
60
61 public final class XmlSchemaCollection {
62
63
64 private ExtensionRegistry extReg = new ExtensionRegistry();
65
66 public ExtensionRegistry getExtReg() {
67 return extReg;
68 }
69
70 public void setExtReg(ExtensionRegistry extReg) {
71 this.extReg = extReg;
72 }
73
74
75
76
77
78
79 private Map knownNamespaceMap = new HashMap();
80
81
82
83
84
85 public Map getKnownNamespaceMap() {
86 return knownNamespaceMap;
87 }
88
89
90
91
92
93 public void setKnownNamespaceMap(Map knownNamespaceMap) {
94 this.knownNamespaceMap = knownNamespaceMap;
95 }
96
97
98
99
100
101
102 public static class SchemaKey {
103 private final String namespace;
104 private final String systemId;
105 SchemaKey(String pNamespace, String pSystemId) {
106 namespace = pNamespace == null ? Constants.NULL_NS_URI : pNamespace;
107 systemId = pSystemId == null ? "" : pSystemId;
108 }
109
110 String getNamespace() { return namespace; }
111
112 String getSystemId() { return systemId; }
113
114 public int hashCode() {
115 final int PRIME = 31;
116 return (PRIME + namespace.hashCode()) * PRIME + systemId.hashCode();
117 }
118
119 public boolean equals(Object obj) {
120 if (this == obj)
121 return true;
122 if (obj == null)
123 return false;
124 if (getClass() != obj.getClass())
125 return false;
126 final SchemaKey other = (SchemaKey) obj;
127 return namespace.equals(other.namespace) && systemId.equals(other.systemId);
128 }
129
130 public String toString() {
131 return Constants.NULL_NS_URI.equals(namespace) ?
132 systemId : ("{" + namespace + "}" + systemId);
133 }
134 }
135
136
137
138
139 private Map schemas = new HashMap();
140
141
142
143
144
145
146 String baseUri = null;
147
148
149
150 private NamespacePrefixList namespaceContext;
151
152
153
154
155
156 private URIResolver schemaResolver = new DefaultURIResolver();
157
158 XmlSchema xsd = new XmlSchema(XmlSchema.SCHEMA_NS, this);
159
160
161
162
163 Stack stack = new Stack();
164
165
166
167
168
169
170 public void setBaseUri(String baseUri) {
171 this.baseUri = baseUri;
172 if(schemaResolver instanceof CollectionURIResolver) {
173 CollectionURIResolver resolverWithBase =
174 (CollectionURIResolver) schemaResolver;
175 resolverWithBase.setCollectionBaseURI(baseUri);
176 }
177 }
178
179
180
181
182
183 public void setSchemaResolver(URIResolver schemaResolver) {
184 this.schemaResolver = schemaResolver;
185 }
186
187
188
189
190
191 public URIResolver getSchemaResolver() {
192 return schemaResolver;
193 }
194
195
196
197
198
199
200
201 public void init() {
202
203
204
205
206 addSimpleType(xsd, Constants.XSD_ANYSIMPLETYPE.getLocalPart());
207 addSimpleType(xsd, Constants.XSD_ANYTYPE.getLocalPart());
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 addSimpleType(xsd, Constants.XSD_STRING.getLocalPart());
233 addSimpleType(xsd, Constants.XSD_BOOLEAN.getLocalPart());
234 addSimpleType(xsd, Constants.XSD_FLOAT.getLocalPart());
235 addSimpleType(xsd, Constants.XSD_DOUBLE.getLocalPart());
236 addSimpleType(xsd, Constants.XSD_QNAME.getLocalPart());
237 addSimpleType(xsd, Constants.XSD_DECIMAL.getLocalPart());
238 addSimpleType(xsd, Constants.XSD_DURATION.getLocalPart());
239 addSimpleType(xsd, Constants.XSD_DATE.getLocalPart());
240 addSimpleType(xsd, Constants.XSD_TIME.getLocalPart());
241 addSimpleType(xsd, Constants.XSD_DATETIME.getLocalPart());
242 addSimpleType(xsd, Constants.XSD_DAY.getLocalPart());
243 addSimpleType(xsd, Constants.XSD_MONTH.getLocalPart());
244 addSimpleType(xsd, Constants.XSD_MONTHDAY.getLocalPart());
245 addSimpleType(xsd, Constants.XSD_YEAR.getLocalPart());
246 addSimpleType(xsd, Constants.XSD_YEARMONTH.getLocalPart());
247 addSimpleType(xsd, Constants.XSD_NOTATION.getLocalPart());
248 addSimpleType(xsd, Constants.XSD_HEXBIN.getLocalPart());
249 addSimpleType(xsd, Constants.XSD_BASE64.getLocalPart());
250 addSimpleType(xsd, Constants.XSD_ANYURI.getLocalPart());
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 addSimpleType(xsd, Constants.XSD_LONG.getLocalPart());
283 addSimpleType(xsd, Constants.XSD_SHORT.getLocalPart());
284 addSimpleType(xsd, Constants.XSD_BYTE.getLocalPart());
285 addSimpleType(xsd, Constants.XSD_INTEGER.getLocalPart());
286 addSimpleType(xsd, Constants.XSD_INT.getLocalPart());
287 addSimpleType(xsd, Constants.XSD_POSITIVEINTEGER.getLocalPart());
288 addSimpleType(xsd, Constants.XSD_NEGATIVEINTEGER.getLocalPart());
289 addSimpleType(xsd, Constants.XSD_NONPOSITIVEINTEGER.getLocalPart());
290 addSimpleType(xsd, Constants.XSD_NONNEGATIVEINTEGER.getLocalPart());
291 addSimpleType(xsd, Constants.XSD_UNSIGNEDBYTE.getLocalPart());
292 addSimpleType(xsd, Constants.XSD_UNSIGNEDINT.getLocalPart());
293 addSimpleType(xsd, Constants.XSD_UNSIGNEDLONG.getLocalPart());
294 addSimpleType(xsd, Constants.XSD_UNSIGNEDSHORT.getLocalPart());
295
296
297 addSimpleType(xsd, Constants.XSD_NAME.getLocalPart());
298 addSimpleType(xsd, Constants.XSD_NORMALIZEDSTRING.getLocalPart());
299 addSimpleType(xsd, Constants.XSD_NCNAME.getLocalPart());
300 addSimpleType(xsd, Constants.XSD_NMTOKEN.getLocalPart());
301 addSimpleType(xsd, Constants.XSD_NMTOKENS.getLocalPart());
302 addSimpleType(xsd, Constants.XSD_ENTITY.getLocalPart());
303 addSimpleType(xsd, Constants.XSD_ENTITIES.getLocalPart());
304 addSimpleType(xsd, Constants.XSD_ID.getLocalPart());
305 addSimpleType(xsd, Constants.XSD_IDREF.getLocalPart());
306 addSimpleType(xsd, Constants.XSD_IDREFS.getLocalPart());
307 addSimpleType(xsd, Constants.XSD_LANGUAGE.getLocalPart());
308 addSimpleType(xsd, Constants.XSD_TOKEN.getLocalPart());
309
310
311
312
313
314
315
316
317
318 if (System.getProperty(Constants.SystemConstants.EXTENSION_REGISTRY_KEY)!= null){
319 try {
320 Class clazz = Class.forName(System.getProperty(Constants.SystemConstants.EXTENSION_REGISTRY_KEY));
321 this.extReg = (ExtensionRegistry)clazz.newInstance();
322 } catch (ClassNotFoundException e) {
323 System.err.println("The specified extension registry class cannot be found!");
324 } catch (InstantiationException e) {
325 System.err.println("The specified extension registry class cannot be instantiated!");
326 } catch (IllegalAccessException e) {
327 System.err.println("The specified extension registry class cannot be accessed!");
328 }
329 }
330 }
331
332 boolean containsSchema(SchemaKey pKey) {
333 return schemas.containsKey(pKey);
334 }
335
336
337
338
339
340
341
342 XmlSchema getKnownSchema(String namespace) {
343 return (XmlSchema) knownNamespaceMap.get(namespace);
344 }
345
346
347
348
349
350
351 XmlSchema getSchema(SchemaKey pKey) {
352 return (XmlSchema) schemas.get(pKey);
353 }
354
355 void addSchema(SchemaKey pKey, XmlSchema pSchema) {
356 if (schemas.containsKey(pKey)) {
357 throw new IllegalStateException("A schema with target namespace "
358 + pKey.getNamespace() + " and system ID " + pKey.getSystemId()
359 + " is already present.");
360 }
361 schemas.put(pKey, pSchema);
362 }
363
364 private void addSimpleType(XmlSchema schema,String typeName){
365 XmlSchemaSimpleType type;
366 type = new XmlSchemaSimpleType(schema);
367 type.setName(typeName);
368 schema.addType(type);
369 }
370 public XmlSchema read(Reader r, ValidationEventHandler veh) {
371 return read(new InputSource(r), veh);
372 }
373
374 XmlSchema read(final InputSource inputSource, ValidationEventHandler veh,
375 TargetNamespaceValidator namespaceValidator) {
376 try {
377 DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
378 docFac.setNamespaceAware(true);
379 final DocumentBuilder builder = docFac.newDocumentBuilder();
380 Document doc = null;
381 doc = parse_doPriv(inputSource, builder, doc);
382 return read(doc, inputSource.getSystemId(), veh, namespaceValidator);
383 } catch (ParserConfigurationException e) {
384 throw new XmlSchemaException(e.getMessage());
385 } catch (IOException e) {
386 throw new XmlSchemaException(e.getMessage());
387 } catch (SAXException e) {
388 throw new XmlSchemaException(e.getMessage());
389 }
390 }
391
392 private Document parse_doPriv(final InputSource inputSource, final DocumentBuilder builder, Document doc) throws IOException, SAXException {
393 try {
394 doc = (Document) java.security.AccessController.doPrivileged(
395 new PrivilegedExceptionAction() {
396 public Object run() throws IOException, SAXException {
397 return builder.parse(inputSource);
398 }
399 }
400 );
401 } catch (PrivilegedActionException e) {
402 Exception exception = e.getException();
403 if(exception instanceof IOException) {
404 throw (IOException) exception;
405 }
406 if(exception instanceof SAXException) {
407 throw (SAXException) exception;
408 }
409 }
410 return doc;
411 }
412
413
414
415
416
417
418
419
420
421 public XmlSchema read(InputSource inputSource, ValidationEventHandler veh) {
422 return read(inputSource, veh, null);
423 }
424
425
426
427
428
429
430
431
432
433 public XmlSchema read(Source source, ValidationEventHandler veh) {
434 if (source instanceof SAXSource) {
435 return read(((SAXSource) source).getInputSource(), veh);
436 } else if (source instanceof DOMSource) {
437 Node node = ((DOMSource) source).getNode();
438 if (node instanceof Document) {
439 node = ((Document) node).getDocumentElement();
440 }
441 return read((Document) node, veh);
442 } else if (source instanceof StreamSource) {
443 StreamSource ss = (StreamSource) source;
444 InputSource isource = new InputSource(ss.getSystemId());
445 isource.setByteStream(ss.getInputStream());
446 isource.setCharacterStream(ss.getReader());
447 isource.setPublicId(ss.getPublicId());
448 return read(isource, veh);
449 } else {
450 InputSource isource = new InputSource(source.getSystemId());
451 return read(isource, veh);
452 }
453 }
454
455
456
457
458
459
460
461
462
463 public XmlSchema read(Document doc, ValidationEventHandler veh) {
464 SchemaBuilder builder = new SchemaBuilder(this, null);
465 return builder.build(doc, null, veh);
466 }
467
468
469
470
471
472
473
474
475
476 public XmlSchema read(Element elem) {
477 SchemaBuilder builder = new SchemaBuilder(this, null);
478 XmlSchema xmlSchema = builder.handleXmlSchemaElement(elem, null);
479 xmlSchema.setInputEncoding(DOMUtil.getXmlEncoding(elem.getOwnerDocument()));
480 return xmlSchema;
481 }
482
483
484
485
486
487
488
489
490
491
492 public XmlSchema read(Document doc, String systemId, ValidationEventHandler veh) {
493 return read(doc, systemId, veh, null);
494 }
495
496
497
498
499
500
501
502
503
504
505
506 public XmlSchema read(Document doc, String systemId, ValidationEventHandler veh,
507 TargetNamespaceValidator validator) {
508 SchemaBuilder builder = new SchemaBuilder(this, validator);
509 XmlSchema schema = builder.build(doc, systemId, veh);
510 schema.setInputEncoding(DOMUtil.getInputEncoding(doc));
511 return schema;
512 }
513
514
515
516
517
518
519
520
521 public XmlSchema read(Element elem, String systemId) {
522 SchemaBuilder builder = new SchemaBuilder(this, null);
523 XmlSchema xmlSchema = builder.handleXmlSchemaElement(elem, systemId);
524 xmlSchema.setInputEncoding(DOMUtil.getInputEncoding(elem.getOwnerDocument()));
525 return xmlSchema;
526 }
527
528
529
530
531 public XmlSchemaCollection() {
532 init();
533 }
534
535
536
537
538
539
540
541
542
543
544
545 public XmlSchema[] getXmlSchema(String systemId) {
546 if (systemId == null) {
547 systemId = "";
548 }
549 final List result = new ArrayList();
550 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
551 Map.Entry entry = (Map.Entry) iter.next();
552 if (((SchemaKey) entry.getKey()).getSystemId().equals(systemId)) {
553 result.add(entry.getValue());
554 }
555 }
556 return (XmlSchema[]) result.toArray(new XmlSchema[result.size()]);
557 }
558
559
560
561
562
563 public XmlSchema[] getXmlSchemas() {
564 Collection c = schemas.values();
565 return (XmlSchema[]) c.toArray(new XmlSchema[c.size()]);
566 }
567
568
569
570
571
572
573
574 public XmlSchemaElement getElementByQName(QName qname) {
575 String uri = qname.getNamespaceURI();
576 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext();) {
577 Map.Entry entry = (Map.Entry) iter.next();
578 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
579 XmlSchemaElement element = ((XmlSchema) entry.getValue())
580 .getElementByName(qname);
581 if (element != null) {
582 return element;
583 }
584 }
585 }
586 return null;
587 }
588
589
590
591
592
593
594 public XmlSchemaType getTypeByQName(QName schemaTypeName) {
595 String uri = schemaTypeName.getNamespaceURI();
596 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext();) {
597 Map.Entry entry = (Map.Entry) iter.next();
598 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
599 XmlSchemaType type = ((XmlSchema) entry.getValue())
600 .getTypeByName(schemaTypeName);
601 if (type != null) {
602 return type;
603 }
604 }
605 }
606 return null;
607 }
608
609
610
611
612
613
614 public XmlSchemaAttribute getAttributeByQName(QName schemaAttributeName) {
615 String uri = schemaAttributeName.getNamespaceURI();
616 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
617 Map.Entry entry = (Map.Entry) iter.next();
618 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
619 XmlSchemaAttribute attribute = ((XmlSchema) entry.getValue()).getAttributeByName(schemaAttributeName);
620 if (attribute != null) {
621 return attribute;
622 }
623 }
624 }
625 return null;
626 }
627
628
629
630
631
632
633 public XmlSchema schemaForNamespace(String uri) {
634 for (Iterator iter = schemas.entrySet().iterator(); iter.hasNext(); ) {
635 Map.Entry entry = (Map.Entry) iter.next();
636 if (((SchemaKey) entry.getKey()).getNamespace().equals(uri)) {
637 return (XmlSchema) entry.getValue();
638 }
639 }
640 return null;
641 }
642
643 Map unresolvedTypes = new HashMap();
644
645 void addUnresolvedType(QName type, TypeReceiver receiver) {
646 ArrayList receivers = (ArrayList)unresolvedTypes.get(type);
647 if (receivers == null) {
648 receivers = new ArrayList();
649 unresolvedTypes.put(type, receivers);
650 }
651 receivers.add(receiver);
652 }
653
654 void resolveType(QName typeName, XmlSchemaType type) {
655 ArrayList receivers = (ArrayList)unresolvedTypes.get(typeName);
656 if (receivers == null)
657 return;
658 for (Iterator i = receivers.iterator(); i.hasNext();) {
659 TypeReceiver receiver = (TypeReceiver) i.next();
660 receiver.setType(type);
661 }
662 unresolvedTypes.remove(typeName);
663 }
664
665
666
667
668
669 public NamespacePrefixList getNamespaceContext() {
670 return namespaceContext;
671 }
672
673
674
675
676
677
678 public void setNamespaceContext(NamespacePrefixList namespaceContext) {
679 this.namespaceContext = namespaceContext;
680 }
681
682
683
684
685
686
687
688 public void push(SchemaKey pKey) {
689 stack.push(pKey);
690 }
691
692
693
694
695
696 public void pop() {
697 stack.pop();
698 }
699
700
701
702
703
704
705
706
707 public boolean check(SchemaKey pKey) {
708 return (stack.indexOf(pKey)==-1);
709 }
710
711 public String toString() {
712 return super.toString() + "[" + schemas.toString() + "]";
713 }
714 }