View Javadoc

1   /*
2    * Copyright 2004,2007 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.ws.commons.schema;
18  
19  import org.apache.ws.commons.schema.constants.Constants;
20  import org.apache.ws.commons.schema.utils.NamespaceContextOwner;
21  import org.apache.ws.commons.schema.utils.NamespacePrefixList;
22  import org.w3c.dom.Document;
23  
24  import javax.xml.namespace.QName;
25  import javax.xml.transform.*;
26  import javax.xml.transform.dom.DOMSource;
27  import javax.xml.transform.stream.StreamResult;
28  import java.io.IOException;
29  import java.io.OutputStream;
30  import java.io.OutputStreamWriter;
31  import java.io.Writer;
32  
33  
34  /**
35   * Contains the definition of a schema. All XML Schema definition language (XSD)
36   * elements are children of the schema element. Represents the World Wide Web
37   * Consortium (W3C) schema element
38   */
39  
40  // Oct 15th - momo - initial impl
41  // Oct 17th - vidyanand - add SimpleType + element
42  // Oct 18th - momo - add ComplexType
43  // Oct 19th - vidyanand - handle external
44  // Dec 6th - Vidyanand - changed RuntimeExceptions thrown to XmlSchemaExceptions
45  // Jan 15th - Vidyanand - made changes to SchemaBuilder.handleElement to look for an element ref.
46  // Feb 20th - Joni - Change the getXmlSchemaFromLocation schema 
47  //            variable to name s.
48  // Feb 21th - Joni - Port to XMLDomUtil and Tranformation.  
49  
50  public class XmlSchema extends XmlSchemaAnnotated implements NamespaceContextOwner {
51      static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
52      XmlSchemaForm attributeFormDefault, elementFormDefault;
53  
54      XmlSchemaObjectTable attributeGroups,
55      attributes, elements, groups,
56      notations, schemaTypes;
57      XmlSchemaDerivationMethod blockDefault, finalDefault;
58      XmlSchemaObjectCollection includes, items;
59      boolean isCompiled;
60      String syntacticalTargetNamespace, logicalTargetNamespace, version;
61      String schema_ns_prefix = "";
62      XmlSchemaCollection parent;
63      private NamespacePrefixList namespaceContext;
64  
65      /**
66       * Creates new XmlSchema
67       */
68      public XmlSchema(XmlSchemaCollection parent) {
69          this.parent = parent;
70          attributeFormDefault = new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
71          elementFormDefault = new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
72          blockDefault = new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
73          finalDefault = new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
74          items = new XmlSchemaObjectCollection();
75          includes = new XmlSchemaObjectCollection();
76          elements = new XmlSchemaObjectTable();
77          attributeGroups = new XmlSchemaObjectTable();
78          attributes = new XmlSchemaObjectTable();
79          groups = new XmlSchemaObjectTable();
80          notations = new XmlSchemaObjectTable();
81          schemaTypes = new XmlSchemaObjectTable();
82      }
83  
84      public XmlSchema(String namespace, XmlSchemaCollection parent) {
85          this(parent);
86          syntacticalTargetNamespace = logicalTargetNamespace = namespace;
87      }
88  
89      public XmlSchemaForm getAttributeFormDefault() {
90          return attributeFormDefault;
91      }
92  
93      public void setAttributeFormDefault(XmlSchemaForm value) {
94          attributeFormDefault = value;
95      }
96  
97      public XmlSchemaObjectTable getAttributeGroups() {
98          return attributeGroups;
99      }
100 
101     public XmlSchemaObjectTable getAttributes() {
102         return attributes;
103     }
104 
105     public XmlSchemaDerivationMethod getBlockDefault() {
106         return blockDefault;
107     }
108 
109     public void setBlockDefault(XmlSchemaDerivationMethod blockDefault) {
110         this.blockDefault = blockDefault;
111     }
112 
113     public XmlSchemaForm getElementFormDefault() {
114         return elementFormDefault;
115     }
116 
117     public void setElementFormDefault(XmlSchemaForm elementFormDefault) {
118         this.elementFormDefault = elementFormDefault;
119     }
120 
121     public XmlSchemaObjectTable getElements() {
122         return elements;
123     }
124 
125     public XmlSchemaElement getElementByName(QName name) {
126         return (XmlSchemaElement)elements.getItem(name);
127     }
128 
129     public XmlSchemaType getTypeByName(QName name) {
130         return (XmlSchemaType)schemaTypes.getItem(name);
131     }
132 
133     public XmlSchemaDerivationMethod getFinalDefault() {
134         return finalDefault;
135     }
136 
137     public void setFinalDefault(XmlSchemaDerivationMethod finalDefault) {
138         this.finalDefault = finalDefault;
139     }
140 
141     public XmlSchemaObjectTable getGroups() {
142         return groups;
143     }
144 
145     public XmlSchemaObjectCollection getIncludes() {
146         return includes;
147     }
148 
149     public boolean isCompiled() {
150         return isCompiled;
151     }
152 
153     public XmlSchemaObjectCollection getItems() {
154         return items;
155     }
156 
157     public XmlSchemaObjectTable getNotations() {
158         return notations;
159     }
160 
161     public XmlSchemaObjectTable getSchemaTypes() {
162         return schemaTypes;
163     }
164 
165     public String getTargetNamespace() {
166         return syntacticalTargetNamespace;
167     }
168 
169     public void setTargetNamespace(String targetNamespace) {
170         if (!targetNamespace.equals("")) {
171             syntacticalTargetNamespace = logicalTargetNamespace = targetNamespace;
172         }
173     }
174 
175     public String getVersion() {
176         return version;
177     }
178 
179     public void compile(ValidationEventHandler eh) {
180 
181     }
182 
183     public void write(OutputStream out) {
184         write(new OutputStreamWriter(out));
185     }
186 
187     public void write(Writer writer) {
188         serialize_internal(this, writer);
189     }
190 
191     public Document[] getAllSchemas() {
192         try {
193             
194             XmlSchemaSerializer xser = new XmlSchemaSerializer();
195             xser.setExtReg(this.parent.getExtReg());
196             return xser.serializeSchema(this, true);
197 
198         } catch (XmlSchemaSerializer.XmlSchemaSerializerException e) {
199             throw new XmlSchemaException(e.getMessage());
200         }
201     }
202 
203     private  void serialize_internal(XmlSchema schema, Writer out) {
204         try {
205             XmlSchemaSerializer xser = new XmlSchemaSerializer();
206             xser.setExtReg(this.parent.getExtReg());
207             Document[] serializedSchemas = xser.serializeSchema(schema, false);
208             TransformerFactory trFac = TransformerFactory.newInstance();
209             Source source = new DOMSource(serializedSchemas[0]);
210             Result result = new StreamResult(out);
211             javax.xml.transform.Transformer tr = trFac.newTransformer();
212             tr.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
213             tr.setOutputProperty(OutputKeys.INDENT, "yes");
214             tr.transform(source, result);
215             out.flush();
216         } catch (TransformerConfigurationException e) {
217             throw new XmlSchemaException(e.getMessage());
218         } catch (TransformerException e) {
219             throw new XmlSchemaException(e.getMessage());
220         } catch (XmlSchemaSerializer.XmlSchemaSerializerException e) {
221             throw new XmlSchemaException(e.getMessage());
222         } catch (IOException e) {
223             throw new XmlSchemaException(e.getMessage());
224         }
225     }
226 
227     public void addType(XmlSchemaType type) {
228         QName qname = type.getQName();
229         if (schemaTypes.contains(qname)) {
230             throw new RuntimeException("Schema for namespace '" +
231                                        syntacticalTargetNamespace + "' already contains type '" +
232                                        qname.getLocalPart());
233         }
234         schemaTypes.add(qname, type);
235     }
236 
237     public NamespacePrefixList getNamespaceContext() {
238         return namespaceContext;
239     }
240 
241     /**
242      * Sets the schema elements namespace context. This may be used for schema
243      * serialization, until a better mechanism was found.
244      */
245     public void setNamespaceContext(NamespacePrefixList namespaceContext) {
246         this.namespaceContext = namespaceContext;
247     }
248     
249     /**
250      * Override the equals(Object) method with equivalence checking
251      * that is specific to this class.
252      */
253     public boolean equals(Object what) {
254         
255         //Note: this method may no longer be required when line number/position are used correctly in XmlSchemaObject.
256         //Currently they are simply initialized to zero, but they are used in XmlSchemaObject.equals 
257         //which can result in a false positive (e.g. if a WSDL contains 2 inlined schemas).
258         
259         if (what == this) {
260             return true;
261         }
262         
263         //If the inherited behaviour determines that the objects are NOT equal, return false. 
264         //Otherwise, do some further equivalence checking.
265         
266         if(!super.equals(what)) {
267             return false;
268         }
269         
270         if (!(what instanceof XmlSchema)) {
271             return false;
272         }
273 
274         XmlSchema xs = (XmlSchema) what;
275         
276         if (this.id != null) {
277             if (!this.id.equals(xs.id)) {
278                 return false;
279             }
280         } else {
281             if (xs.id != null) {
282                 return false;
283             }
284         }
285         
286         if (this.syntacticalTargetNamespace != null) {
287             if (!this.syntacticalTargetNamespace.equals(xs.syntacticalTargetNamespace)) {
288                 return false;
289             }
290         } else {
291             if (xs.syntacticalTargetNamespace != null) {
292                 return false;
293             }
294         }
295         
296         //TODO decide if further schema content should be checked for equivalence.
297         
298         return true;
299     }
300 }