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.utils.NamespaceContextOwner;
24 import org.apache.ws.commons.schema.utils.NamespacePrefixList;
25 import org.w3c.dom.Document;
26
27 import javax.xml.namespace.QName;
28 import javax.xml.transform.*;
29 import javax.xml.transform.dom.DOMSource;
30 import javax.xml.transform.stream.StreamResult;
31 import javax.xml.transform.stream.StreamSource;
32 import java.io.*;
33 import java.util.Map;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.Stack;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class XmlSchema extends XmlSchemaAnnotated implements NamespaceContextOwner {
56 private static final String UTF_8_ENCODING = "UTF-8";
57 static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
58 XmlSchemaForm attributeFormDefault, elementFormDefault;
59
60 XmlSchemaObjectTable attributeGroups,
61 attributes, elements, groups,
62 notations, schemaTypes;
63 XmlSchemaDerivationMethod blockDefault, finalDefault;
64 XmlSchemaObjectCollection includes, items;
65 boolean isCompiled;
66 String syntacticalTargetNamespace, logicalTargetNamespace, version;
67 String schema_ns_prefix = "";
68 XmlSchemaCollection parent;
69
70 private NamespacePrefixList namespaceContext;
71
72 private String inputEncoding;
73
74 public void setInputEncoding(String encoding){
75 this.inputEncoding = encoding;
76 }
77
78
79
80
81
82
83
84
85
86 public XmlSchema(XmlSchemaCollection parent) {
87 this(null, null, parent);
88 }
89
90
91
92
93 public XmlSchema() {
94 this(null, null, null);
95 }
96
97
98
99
100
101
102
103 public XmlSchema(String namespace, String systemId, XmlSchemaCollection parent) {
104 this.parent = parent;
105 attributeFormDefault = new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
106 elementFormDefault = new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
107 blockDefault = new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
108 finalDefault = new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
109 items = new XmlSchemaObjectCollection();
110 includes = new XmlSchemaObjectCollection();
111 elements = new XmlSchemaObjectTable();
112 attributeGroups = new XmlSchemaObjectTable();
113 attributes = new XmlSchemaObjectTable();
114 groups = new XmlSchemaObjectTable();
115 notations = new XmlSchemaObjectTable();
116 schemaTypes = new XmlSchemaObjectTable();
117
118 syntacticalTargetNamespace = logicalTargetNamespace = namespace;
119 if (logicalTargetNamespace == null) {
120 logicalTargetNamespace = "";
121 }
122 if(parent != null) {
123 XmlSchemaCollection.SchemaKey schemaKey =
124 new XmlSchemaCollection.SchemaKey(this.logicalTargetNamespace, systemId);
125 if (parent.containsSchema(schemaKey)) {
126 throw new XmlSchemaException("Schema name conflict in collection");
127 } else {
128 parent.addSchema(schemaKey, this);
129 }
130 }
131 }
132
133 public XmlSchema(String namespace, XmlSchemaCollection parent) {
134 this(namespace, namespace, parent);
135
136 }
137
138 public XmlSchemaForm getAttributeFormDefault() {
139 return attributeFormDefault;
140 }
141
142 public void setAttributeFormDefault(XmlSchemaForm value) {
143 attributeFormDefault = value;
144 }
145
146 public XmlSchemaObjectTable getAttributeGroups() {
147 return attributeGroups;
148 }
149
150 public XmlSchemaObjectTable getAttributes() {
151 return attributes;
152 }
153
154 public XmlSchemaDerivationMethod getBlockDefault() {
155 return blockDefault;
156 }
157
158 public void setBlockDefault(XmlSchemaDerivationMethod blockDefault) {
159 this.blockDefault = blockDefault;
160 }
161
162 public XmlSchemaForm getElementFormDefault() {
163 return elementFormDefault;
164 }
165
166 public void setElementFormDefault(XmlSchemaForm elementFormDefault) {
167 this.elementFormDefault = elementFormDefault;
168 }
169
170 public XmlSchemaObjectTable getElements() {
171 return elements;
172 }
173
174
175 protected XmlSchemaElement getElementByName(QName name, boolean deep,
176 Stack schemaStack) {
177 if (schemaStack != null && schemaStack.contains(this)) {
178
179 return null;
180 } else {
181 XmlSchemaElement element = (XmlSchemaElement) elements
182 .getItem(name);
183 if (deep) {
184 if (element == null) {
185
186 for (Iterator includedItems = includes.getIterator(); includedItems
187 .hasNext();) {
188
189 XmlSchema schema = getSchema(includedItems.next());
190
191 if (schema != null) {
192
193
194
195 if (schemaStack == null) {
196 schemaStack = new Stack();
197 }
198 schemaStack.push(this);
199 element = schema.getElementByName(name, deep,
200 schemaStack);
201 if (element != null) {
202 return element;
203 }
204 }
205 }
206 } else {
207 return element;
208 }
209 }
210
211 return element;
212 }
213 }
214
215
216
217
218
219
220
221 public XmlSchemaElement getElementByName(String name) {
222 QName nameToSearchFor = new QName(this.getTargetNamespace(),name);
223 return this.getElementByName(nameToSearchFor, false, null);
224 }
225
226
227
228
229
230
231 public XmlSchemaElement getElementByName(QName name) {
232 return this.getElementByName(name, true, null);
233 }
234
235
236
237
238
239
240
241
242
243 protected XmlSchemaType getTypeByName(QName name, boolean deep,
244 Stack schemaStack) {
245 if (schemaStack != null && schemaStack.contains(this)) {
246
247 return null;
248 } else {
249 XmlSchemaType type = (XmlSchemaType) schemaTypes.getItem(name);
250
251 if (deep) {
252 if (type == null) {
253
254 for (Iterator includedItems = includes.getIterator(); includedItems
255 .hasNext();) {
256
257 XmlSchema schema = getSchema(includedItems.next());
258
259 if (schema != null) {
260
261
262 if (schemaStack == null) {
263 schemaStack = new Stack();
264 }
265 schemaStack.push(this);
266 type = schema
267 .getTypeByName(name, deep, schemaStack);
268 if (type != null) {
269 return type;
270 }
271 }
272 }
273 } else {
274 return type;
275 }
276 }
277
278 return type;
279 }
280 }
281
282
283
284
285
286
287
288 public XmlSchemaType getTypeByName(QName name) {
289 return getTypeByName(name, true, null);
290 }
291
292
293
294
295
296
297 public XmlSchemaType getTypeByName(String name) {
298 QName nameToSearchFor = new QName(this.getTargetNamespace(),name);
299 return getTypeByName(nameToSearchFor, false, null);
300 }
301
302
303
304
305
306
307
308 private XmlSchema getSchema(Object includeOrImport) {
309 XmlSchema schema;
310 if (includeOrImport instanceof XmlSchemaImport) {
311 schema = ((XmlSchemaImport) includeOrImport).getSchema();
312 } else if (includeOrImport instanceof XmlSchemaInclude) {
313 schema = ((XmlSchemaInclude) includeOrImport).getSchema();
314 } else {
315
316 schema = null;
317 }
318
319 return schema;
320 }
321
322
323
324 public XmlSchemaDerivationMethod getFinalDefault() {
325 return finalDefault;
326 }
327
328 public void setFinalDefault(XmlSchemaDerivationMethod finalDefault) {
329 this.finalDefault = finalDefault;
330 }
331
332 public XmlSchemaObjectTable getGroups() {
333 return groups;
334 }
335
336 public XmlSchemaObjectCollection getIncludes() {
337 return includes;
338 }
339
340 public boolean isCompiled() {
341 return isCompiled;
342 }
343
344 public XmlSchemaObjectCollection getItems() {
345 return items;
346 }
347
348 public XmlSchemaObjectTable getNotations() {
349 return notations;
350 }
351
352 public XmlSchemaObjectTable getSchemaTypes() {
353 return schemaTypes;
354 }
355
356 public String getTargetNamespace() {
357 return syntacticalTargetNamespace;
358 }
359
360 public void setTargetNamespace(String targetNamespace) {
361 if (!targetNamespace.equals("")) {
362 syntacticalTargetNamespace = logicalTargetNamespace = targetNamespace;
363 }
364 }
365
366 public String getVersion() {
367 return version;
368 }
369
370 public void compile(ValidationEventHandler eh) {
371
372 }
373
374
375
376
377
378 public void write(OutputStream out) {
379 try {
380 if (this.inputEncoding!= null &&
381 !"".equals(this.inputEncoding)){
382 write(new OutputStreamWriter(out,this.inputEncoding));
383 }else{
384
385 write(new OutputStreamWriter(out,UTF_8_ENCODING));
386 }
387 } catch (UnsupportedEncodingException e) {
388
389 write(new OutputStreamWriter(out));
390 }
391
392 }
393
394
395
396
397
398
399 public void write(OutputStream out, Map options) {
400 try {
401 if (this.inputEncoding!= null &&
402 !"".equals(this.inputEncoding)){
403 write(new OutputStreamWriter(out,this.inputEncoding),options);
404 }else{
405 write(new OutputStreamWriter(out,UTF_8_ENCODING),options);
406 }
407 } catch (UnsupportedEncodingException e) {
408
409 write(new OutputStreamWriter(out));
410 }
411
412 }
413
414
415
416
417
418 public void write(Writer writer,Map options) {
419 serialize_internal(this, writer,options);
420 }
421
422
423
424
425 public void write(Writer writer) {
426 serialize_internal(this, writer,null);
427 }
428
429 public Document[] getAllSchemas() {
430 try {
431
432 XmlSchemaSerializer xser = new XmlSchemaSerializer();
433 xser.setExtReg(this.parent.getExtReg());
434 return xser.serializeSchema(this, true);
435
436 } catch (XmlSchemaSerializer.XmlSchemaSerializerException e) {
437 throw new XmlSchemaException(e.getMessage());
438 }
439 }
440
441
442
443
444
445
446
447 private void serialize_internal(XmlSchema schema, Writer out, Map options) {
448
449 try {
450 XmlSchemaSerializer xser = new XmlSchemaSerializer();
451 xser.setExtReg(this.parent.getExtReg());
452 Document[] serializedSchemas = xser.serializeSchema(schema, false);
453 TransformerFactory trFac = TransformerFactory.newInstance();
454
455 try {
456 trFac.setAttribute("indent-number", "4");
457 } catch (IllegalArgumentException e) {
458
459
460 }
461
462 Source source = new DOMSource(serializedSchemas[0]);
463 Result result = new StreamResult(out);
464 javax.xml.transform.Transformer tr = trFac.newTransformer();
465
466
467 if (schema.inputEncoding!= null &&
468 !"".equals(schema.inputEncoding)){
469 tr.setOutputProperty(OutputKeys.ENCODING,schema.inputEncoding);
470 }
471
472
473
474
475
476 if (options==null){
477 options = new HashMap();
478 loadDefaultOptions(options);
479 }
480 Iterator keys = options.keySet().iterator();
481 while (keys.hasNext()) {
482 Object key = keys.next();
483 tr.setOutputProperty((String)key, (String)options.get(key));
484 }
485
486 tr.transform(source, result);
487 out.flush();
488 } catch (TransformerConfigurationException e) {
489 throw new XmlSchemaException(e.getMessage());
490 } catch (TransformerException e) {
491 throw new XmlSchemaException(e.getMessage());
492 } catch (XmlSchemaSerializer.XmlSchemaSerializerException e) {
493 throw new XmlSchemaException(e.getMessage());
494 } catch (IOException e) {
495 throw new XmlSchemaException(e.getMessage());
496 }
497 }
498
499
500
501
502
503 private void loadDefaultOptions(Map options) {
504 options.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
505 options.put(OutputKeys.INDENT, "yes");
506 }
507
508 public void addType(XmlSchemaType type) {
509 QName qname = type.getQName();
510 if (schemaTypes.contains(qname)) {
511 throw new XmlSchemaException(" Schema for namespace '" +
512 syntacticalTargetNamespace + "' already contains type '" +
513 qname.getLocalPart() + "'");
514 }
515 schemaTypes.add(qname, type);
516 }
517
518 public NamespacePrefixList getNamespaceContext() {
519 return namespaceContext;
520 }
521
522
523
524
525
526 public void setNamespaceContext(NamespacePrefixList namespaceContext) {
527 this.namespaceContext = namespaceContext;
528 }
529
530
531
532
533
534 public boolean equals(Object what) {
535
536
537
538
539
540 if (what == this) {
541 return true;
542 }
543
544
545
546
547 if(!super.equals(what)) {
548 return false;
549 }
550
551 if (!(what instanceof XmlSchema)) {
552 return false;
553 }
554
555 XmlSchema xs = (XmlSchema) what;
556
557 if (this.id != null) {
558 if (!this.id.equals(xs.id)) {
559 return false;
560 }
561 } else {
562 if (xs.id != null) {
563 return false;
564 }
565 }
566
567 if (this.syntacticalTargetNamespace != null) {
568 if (!this.syntacticalTargetNamespace.equals(xs.syntacticalTargetNamespace)) {
569 return false;
570 }
571 } else {
572 if (xs.syntacticalTargetNamespace != null) {
573 return false;
574 }
575 }
576
577
578
579 return true;
580 }
581 public String getInputEncoding() {
582 return inputEncoding;
583 }
584
585 public String toString() {
586 return super.toString() + "[" + logicalTargetNamespace + "]";
587 }
588 }