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