View Javadoc

1   /*
2    * Copyright 2005-2012 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.io.UnsupportedEncodingException;
23  import java.util.ArrayList;
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.springframework.beans.BeanInstantiationException;
31  import org.springframework.beans.BeanUtils;
32  import org.springframework.core.io.Resource;
33  import org.springframework.core.io.UrlResource;
34  import org.springframework.util.Assert;
35  import org.springframework.xml.validation.XmlValidator;
36  import org.springframework.xml.validation.XmlValidatorFactory;
37  import org.springframework.xml.xsd.XsdSchema;
38  
39  import org.apache.ws.commons.schema.XmlSchema;
40  import org.apache.ws.commons.schema.XmlSchemaCollection;
41  import org.apache.ws.commons.schema.XmlSchemaSerializer;
42  import org.w3c.dom.Document;
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  {@code 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  {@code 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<QName> result = new ArrayList<QName>(schema.getElements().keySet());
87          return result.toArray(new QName[result.size()]);
88      }
89  
90      public Source getSource() {
91          // try to use the the package-friendly XmlSchemaSerializer first, fall back to slower stream-based version
92          try {
93              XmlSchemaSerializer serializer = BeanUtils.instantiateClass(XmlSchemaSerializer.class);
94              if (collection != null) {
95                  serializer.setExtReg(collection.getExtReg());
96              }
97              Document[] serializedSchemas = serializer.serializeSchema(schema, false);
98              return new DOMSource(serializedSchemas[0]);
99          }
100         catch (BeanInstantiationException ex) {
101             // ignore
102         }
103         catch (XmlSchemaSerializer.XmlSchemaSerializerException ex) {
104             // ignore
105         }
106         ByteArrayOutputStream bos = new ByteArrayOutputStream();
107         try {
108             schema.write(bos);
109         }
110         catch (UnsupportedEncodingException ex) {
111             throw new CommonsXsdSchemaException(ex.getMessage(), ex);
112         }
113         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
114         return new StreamSource(bis);
115     }
116 
117     public XmlValidator createValidator() throws IOException {
118         Resource resource = new UrlResource(schema.getSourceURI());
119         return XmlValidatorFactory.createValidator(resource, XmlValidatorFactory.SCHEMA_W3C_XML);
120     }
121 
122     /** Returns the wrapped Commons <code>XmlSchema</code> object. */
123     public XmlSchema getSchema() {
124         return schema;
125     }
126 
127     public String toString() {
128         StringBuilder builder = new StringBuilder("CommonsXsdSchema");
129         builder.append('{');
130         builder.append(getTargetNamespace());
131         builder.append('}');
132         return builder.toString();
133     }
134 
135 }