View Javadoc

1   /*
2    * Copyright 2008 the original author or authors.
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.springframework.xml.xsd.commons;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import javax.xml.namespace.QName;
26  import javax.xml.transform.Source;
27  import javax.xml.transform.dom.DOMSource;
28  import javax.xml.transform.stream.StreamSource;
29  
30  import org.apache.ws.commons.schema.XmlSchema;
31  import org.apache.ws.commons.schema.XmlSchemaCollection;
32  import org.apache.ws.commons.schema.XmlSchemaSerializer;
33  import org.w3c.dom.Document;
34  
35  import org.springframework.beans.BeanInstantiationException;
36  import org.springframework.beans.BeanUtils;
37  import org.springframework.core.io.Resource;
38  import org.springframework.core.io.UrlResource;
39  import org.springframework.util.Assert;
40  import org.springframework.xml.validation.XmlValidator;
41  import org.springframework.xml.validation.XmlValidatorFactory;
42  import org.springframework.xml.xsd.XsdSchema;
43  
44  /**
45   * Implementation of the {@link XsdSchema} interface that uses Apache WS-Commons XML Schema.
46   *
47   * @author Arjen Poutsma
48   * @see <a href="http://ws.apache.org/commons/XmlSchema/">Commons XML Schema</a>
49   * @since 1.5.0
50   */
51  public class CommonsXsdSchema implements XsdSchema {
52  
53      private final XmlSchema schema;
54  
55      private final XmlSchemaCollection collection;
56  
57      /**
58       * Create a new instance of the  {@link CommonsXsdSchema} class with the specified {@link XmlSchema} reference.
59       *
60       * @param schema the Commons <code>XmlSchema</code> object; must not be <code>null</code>
61       * @throws IllegalArgumentException if the supplied <code>schema</code> is <code>null</code>
62       */
63      protected CommonsXsdSchema(XmlSchema schema) {
64          this(schema, null);
65      }
66  
67      /**
68       * Create a new instance of the  {@link CommonsXsdSchema} class with the specified {@link XmlSchema} and {@link
69       * XmlSchemaCollection} reference.
70       *
71       * @param schema     the Commons <code>XmlSchema</code> object; must not be <code>null</code>
72       * @param collection the Commons <code>XmlSchemaCollection</code> object; can be <code>null</code>
73       * @throws IllegalArgumentException if the supplied <code>schema</code> is <code>null</code>
74       */
75      protected CommonsXsdSchema(XmlSchema schema, XmlSchemaCollection collection) {
76          Assert.notNull(schema, "'schema' must not be null");
77          this.schema = schema;
78          this.collection = collection;
79      }
80  
81      public String getTargetNamespace() {
82          return schema.getTargetNamespace();
83      }
84  
85      public QName[] getElementNames() {
86          List result = new ArrayList();
87          Iterator iterator = schema.getElements().getNames();
88          while (iterator.hasNext()) {
89              QName name = (QName) iterator.next();
90              result.add(name);
91          }
92          return (QName[]) result.toArray(new QName[result.size()]);
93      }
94  
95      public Source getSource() {
96          // try to use the the package-friendly XmlSchemaSerializer first, fall back to slower stream-based version
97          try {
98              XmlSchemaSerializer serializer = (XmlSchemaSerializer) BeanUtils.instantiateClass(XmlSchemaSerializer.class)
99                      ;
100             if (collection != null) {
101                 serializer.setExtReg(collection.getExtReg());
102             }
103             Document[] serializedSchemas = serializer.serializeSchema(schema, false);
104             return new DOMSource(serializedSchemas[0]);
105         }
106         catch (BeanInstantiationException ex) {
107             // ignore
108         }
109         catch (XmlSchemaSerializer.XmlSchemaSerializerException ex) {
110             // ignore
111         }
112         ByteArrayOutputStream bos = new ByteArrayOutputStream();
113         schema.write(bos);
114         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
115         return new StreamSource(bis);
116     }
117 
118     public XmlValidator createValidator() throws IOException {
119         Resource resource = new UrlResource(schema.getSourceURI());
120         return XmlValidatorFactory.createValidator(resource, XmlValidatorFactory.SCHEMA_W3C_XML);
121     }
122 
123     /** Returns the wrapped Commons <code>XmlSchema</code> object. */
124     public XmlSchema getSchema() {
125         return schema;
126     }
127 
128     public String toString() {
129         StringBuffer buffer = new StringBuffer("CommonsXsdSchema");
130         buffer.append('{');
131         buffer.append(getTargetNamespace());
132         buffer.append('}');
133         return buffer.toString();
134     }
135 
136 }