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