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.ws.wsdl.wsdl11.provider;
18  
19  import java.io.IOException;
20  import javax.wsdl.Definition;
21  import javax.wsdl.Types;
22  import javax.wsdl.WSDLException;
23  import javax.wsdl.extensions.schema.Schema;
24  import javax.xml.namespace.QName;
25  import javax.xml.transform.TransformerException;
26  import javax.xml.transform.dom.DOMResult;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.w3c.dom.Document;
31  import org.w3c.dom.Element;
32  
33  import org.springframework.util.Assert;
34  import org.springframework.ws.wsdl.WsdlDefinitionException;
35  import org.springframework.xml.transform.TransformerObjectSupport;
36  import org.springframework.xml.validation.XmlValidator;
37  import org.springframework.xml.xsd.XsdSchema;
38  import org.springframework.xml.xsd.XsdSchemaCollection;
39  
40  /**
41   * Implementation of {@link TypesProvider} that inlines a {@link XsdSchema} or {@link XsdSchemaCollection} into the
42   * WSDL.
43   *
44   * @author Arjen Poutsma
45   * @since 1.5.0
46   */
47  public class InliningXsdSchemaTypesProvider extends TransformerObjectSupport implements TypesProvider {
48  
49      private static final Log logger = LogFactory.getLog(InliningXsdSchemaTypesProvider.class);
50  
51      /** The prefix used to register the schema namespace in the WSDL. */
52      public static final String SCHEMA_PREFIX = "sch";
53  
54      private XsdSchemaCollection schemaCollection;
55  
56      /**
57       * Sets the single XSD schema to inline. Either this property, or {@link #setSchemaCollection(XsdSchemaCollection)
58       * schemaCollection} must be set.
59       */
60      public void setSchema(final XsdSchema schema) {
61          this.schemaCollection = new XsdSchemaCollection() {
62  
63              public XsdSchema[] getXsdSchemas() {
64                  return new XsdSchema[]{schema};
65              }
66  
67              public XmlValidator createValidator() throws IOException {
68                  throw new UnsupportedOperationException();
69              }
70          };
71      }
72  
73      /** Returns the XSD schema collection to inline. */
74      public XsdSchemaCollection getSchemaCollection() {
75          return schemaCollection;
76      }
77  
78      /**
79       * Sets the XSD schema collection to inline. Either this property, or {@link #setSchema(XsdSchema) schema} must be
80       * set.
81       */
82      public void setSchemaCollection(XsdSchemaCollection schemaCollection) {
83          this.schemaCollection = schemaCollection;
84      }
85  
86      public void addTypes(Definition definition) throws WSDLException {
87          Assert.notNull(getSchemaCollection(), "setting 'schema' or 'schemaCollection' is required");
88          Types types = definition.createTypes();
89          XsdSchema[] schemas = schemaCollection.getXsdSchemas();
90          for (int i = 0; i < schemas.length; i++) {
91              if (logger.isDebugEnabled()) {
92                  logger.debug("Inlining " + schemas[i]);
93              }
94              if (schemas.length == 1) {
95                  definition.addNamespace(SCHEMA_PREFIX, schemas[i].getTargetNamespace());
96              }
97              else {
98                  String prefix = SCHEMA_PREFIX + i;
99                  definition.addNamespace(prefix, schemas[i].getTargetNamespace());
100             }
101             Element schemaElement = getSchemaElement(schemas[i]);
102             Schema schema = (Schema) definition.getExtensionRegistry()
103                     .createExtension(Types.class, new QName("http://www.w3.org/2001/XMLSchema", "schema"));
104             types.addExtensibilityElement(schema);
105             schema.setElement(schemaElement);
106         }
107         definition.setTypes(types);
108     }
109 
110     private Element getSchemaElement(XsdSchema schema) {
111         try {
112             DOMResult result = new DOMResult();
113             transform(schema.getSource(), result);
114             Document schemaDocument = (Document) result.getNode();
115             return schemaDocument.getDocumentElement();
116         }
117         catch (TransformerException e) {
118             throw new WsdlDefinitionException("Could not transform schema source to Document");
119         }
120     }
121 
122 }