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