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