View Javadoc

1   /*
2    * Copyright 2005-2010 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.util.Iterator;
20  import javax.wsdl.Definition;
21  import javax.wsdl.Message;
22  import javax.wsdl.Part;
23  import javax.wsdl.Types;
24  import javax.wsdl.WSDLException;
25  import javax.wsdl.extensions.ExtensibilityElement;
26  import javax.wsdl.extensions.schema.Schema;
27  import javax.xml.namespace.QName;
28  
29  import org.springframework.util.Assert;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.w3c.dom.Element;
34  import org.w3c.dom.Node;
35  import org.w3c.dom.NodeList;
36  
37  /**
38   * Default implementation of the {@link MessagesProvider}.
39   * <p/>
40   * Simply adds all elements contained in the schema(s) as messages.
41   *
42   * @author Arjen Poutsma
43   * @since 1.5.0
44   */
45  public class DefaultMessagesProvider implements MessagesProvider {
46  
47      private static final Log logger = LogFactory.getLog(DefaultMessagesProvider.class);
48  
49      public void addMessages(Definition definition) throws WSDLException {
50          Types types = definition.getTypes();
51          Assert.notNull(types, "No types element present in definition");
52          for (Iterator<?> iterator = types.getExtensibilityElements().iterator(); iterator.hasNext();) {
53              ExtensibilityElement extensibilityElement = (ExtensibilityElement) iterator.next();
54              if (extensibilityElement instanceof Schema) {
55                  Schema schema = (Schema) extensibilityElement;
56                  if (schema.getElement() != null) {
57                      createMessages(definition, schema.getElement());
58                  }
59              }
60          }
61          if (definition.getMessages().isEmpty() && logger.isWarnEnabled()) {
62              logger.warn("No messages were created, make sure the referenced schema(s) contain elements");
63          }
64      }
65  
66      private void createMessages(Definition definition, Element schemaElement) throws WSDLException {
67          String schemaTargetNamespace = schemaElement.getAttribute("targetNamespace");
68          Assert.hasText(schemaTargetNamespace, "No targetNamespace defined on schema");
69          if (logger.isDebugEnabled()) {
70              logger.debug("Looking for elements in schema with target namespace [" + schemaTargetNamespace + "]");
71          }
72          NodeList children = schemaElement.getChildNodes();
73          for (int i = 0; i < children.getLength(); i++) {
74              Node child = children.item(i);
75              if (child.getNodeType() == Node.ELEMENT_NODE) {
76                  Element childElement = (Element) child;
77                  if (isMessageElement(childElement)) {
78                      QName elementName = new QName(schemaTargetNamespace, getElementName(childElement));
79                      Message message = definition.createMessage();
80                      populateMessage(definition, message, elementName);
81                      Part part = definition.createPart();
82                      populatePart(definition, part, elementName);
83                      message.addPart(part);
84                      message.setUndefined(false);
85                      definition.addMessage(message);
86                  }
87              }
88          }
89      }
90  
91      /**
92       * Returns the name attribute of the given element.
93       *
94       * @param element the element whose name to return
95       * @return the name of the element
96       */
97      protected String getElementName(Element element) {
98          return element.getAttribute("name");
99      }
100 
101     /**
102      * Indicates whether the given element should be includes as {@link Message} in the definition.
103      * <p/>
104      * Default implementation checks whether the element has the XML Schema namespace, and if it has the local name
105      * "element".
106      *
107      * @param element the element elligable for being a message
108      * @return <code>true</code> if to be included as message; <code>false</code> otherwise
109      */
110     protected boolean isMessageElement(Element element) {
111         return "element".equals(element.getLocalName()) &&
112                 "http://www.w3.org/2001/XMLSchema".equals(element.getNamespaceURI());
113     }
114 
115     /**
116      * Called after the {@link Message} has been created.
117      * <p/>
118      * Default implementation sets the name of the message to the element name.
119      *
120      * @param definition  the WSDL4J <code>Definition</code>
121      * @param message     the WSDL4J <code>Message</code>
122      * @param elementName the element name
123      * @throws WSDLException in case of errors
124      */
125     protected void populateMessage(Definition definition, Message message, QName elementName) throws WSDLException {
126         QName messageName = new QName(definition.getTargetNamespace(), elementName.getLocalPart());
127         if (logger.isDebugEnabled()) {
128             logger.debug("Creating message [" + messageName + "]");
129         }
130         message.setQName(messageName);
131     }
132 
133     /**
134      * Called after the {@link Part} has been created.
135      * <p/>
136      * Default implementation sets the element name of the part.
137      *
138      * @param definition  the WSDL4J <code>Definition</code>
139      * @param part        the WSDL4J <code>Part</code>
140      * @param elementName the elementName @throws WSDLException in case of errors
141      * @see Part#setElementName(javax.xml.namespace.QName)
142      */
143     protected void populatePart(Definition definition, Part part, QName elementName) throws WSDLException {
144         part.setElementName(elementName);
145         part.setName(elementName.getLocalPart());
146     }
147 
148 }