View Javadoc

1   /*
2    * Copyright 2007 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.builder;
18  
19  import java.io.IOException;
20  import java.util.ArrayList;
21  import java.util.List;
22  import javax.xml.namespace.QName;
23  import javax.xml.parsers.DocumentBuilder;
24  import javax.xml.parsers.DocumentBuilderFactory;
25  import javax.xml.parsers.ParserConfigurationException;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.w3c.dom.Document;
30  import org.w3c.dom.Element;
31  import org.w3c.dom.Node;
32  import org.w3c.dom.NodeList;
33  import org.xml.sax.SAXException;
34  
35  import org.springframework.core.io.Resource;
36  import org.springframework.util.Assert;
37  import org.springframework.util.StringUtils;
38  import org.springframework.xml.namespace.QNameUtils;
39  import org.springframework.xml.sax.SaxUtils;
40  
41  /**
42   * Helper class for dealing with XSD schemas. Exposes the target namespace, and the list of qualified names declared in
43   * a schema.
44   *
45   * @author Arjen Poutsma
46   * @since 1.0.2
47   * @deprecated as of Spring Web Services 1.5: superseded by {@link org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition}
48   *             and the {@link org.springframework.ws.wsdl.wsdl11.provider} package
49   */
50  class XsdSchemaHelper {
51  
52      private static final Log logger = LogFactory.getLog(XsdSchemaHelper.class);
53  
54      private static final String SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema";
55  
56      static final QName SCHEMA_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "schema", "xsd");
57  
58      static final QName ELEMENT_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "element", "xsd");
59  
60      static final QName INCLUDE_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "include", "xsd");
61  
62      static final QName IMPORT_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "import", "xsd");
63  
64      private final Resource schemaResource;
65  
66      private final Element schemaElement;
67  
68      private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
69  
70      static {
71          documentBuilderFactory.setNamespaceAware(true);
72      }
73  
74      public XsdSchemaHelper(Resource schemaResource) throws ParserConfigurationException, IOException, SAXException {
75          Assert.notNull(schemaResource, "schema must not be empty or null");
76          Assert.isTrue(schemaResource.exists(), "schema \"" + schemaResource + "\" does not exit");
77          this.schemaResource = schemaResource;
78          DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
79          Document schemaDocument = documentBuilder.parse(SaxUtils.createInputSource(schemaResource));
80          schemaElement = schemaDocument.getDocumentElement();
81          Assert.isTrue(SCHEMA_NAME.getLocalPart().equals(schemaElement.getLocalName()),
82                  "schema document root element has invalid local name : [" + schemaElement.getLocalName() +
83                          "] instead of [schema]");
84          Assert.isTrue(SCHEMA_NAME.getNamespaceURI().equals(schemaElement.getNamespaceURI()),
85                  "schema document root element has invalid namespace uri: [" + schemaElement.getNamespaceURI() +
86                          "] instead of [" + SCHEMA_NAME.getNamespaceURI() + "]");
87          Assert.hasLength(getTargetNamespace(), "schema [" + schemaResource + "] has no targetNamespace");
88      }
89  
90      public String getTargetNamespace() {
91          return schemaElement.getAttribute("targetNamespace");
92      }
93  
94      public Element getSchemaElement() {
95          return schemaElement;
96      }
97  
98      public List getElementDeclarations(boolean followIncludeImport) {
99          List declarations = new ArrayList();
100         getElementDeclarationsInternal(declarations, followIncludeImport);
101         return declarations;
102     }
103 
104     private void getElementDeclarationsInternal(List declarations, boolean followIncludeImport) {
105         NodeList children = schemaElement.getChildNodes();
106         for (int i = 0; i < children.getLength(); i++) {
107             if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
108                 Element childElement = (Element) children.item(i);
109                 QName childName = QNameUtils.getQNameForNode(childElement);
110                 if (ELEMENT_NAME.equals(childName)) {
111                     declarations.add(getElementName(childElement));
112                 }
113                 else if (followIncludeImport) {
114                     if (INCLUDE_NAME.equals(childName) || IMPORT_NAME.equals(childName)) {
115                         String schemaLocation = childElement.getAttribute("schemaLocation");
116                         if (StringUtils.hasLength(schemaLocation)) {
117                             try {
118                                 Resource resource = schemaResource.createRelative(schemaLocation);
119                                 if (resource.exists()) {
120                                     XsdSchemaHelper helper = new XsdSchemaHelper(resource);
121                                     helper.getElementDeclarationsInternal(declarations, followIncludeImport);
122                                 }
123                                 else {
124                                     logger.warn("Imported/Includes schema with location " + schemaLocation +
125                                             " does not exist");
126                                 }
127                             }
128                             catch (Exception ex) {
129                                 logger.warn(ex);
130                                 // ignore
131                             }
132                         }
133                     }
134                 }
135             }
136         }
137     }
138 
139     private QName getElementName(Element element) {
140         String attributeValue = element.getAttribute("name");
141         return StringUtils.hasLength(attributeValue) ? new QName(getTargetNamespace(), attributeValue) : null;
142     }
143 
144 
145 }