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