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