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