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.client.support.destination;
18  
19  import java.io.IOException;
20  import java.net.URI;
21  import java.util.Properties;
22  import javax.xml.transform.Transformer;
23  import javax.xml.transform.TransformerException;
24  import javax.xml.transform.TransformerFactory;
25  import javax.xml.transform.dom.DOMResult;
26  
27  import org.w3c.dom.Document;
28  
29  import org.springframework.core.io.Resource;
30  import org.springframework.util.Assert;
31  import org.springframework.ws.client.WebServiceIOException;
32  import org.springframework.ws.client.WebServiceTransformerException;
33  import org.springframework.xml.transform.ResourceSource;
34  import org.springframework.xml.xpath.XPathExpression;
35  import org.springframework.xml.xpath.XPathExpressionFactory;
36  
37  /**
38   * Implementation of the {@link DestinationProvider} that resolves a destination URI from a WSDL file.
39   * <p/>
40   * The extraction relies on an XPath expression to locate the URI. By default, the {@link
41   * #DEFAULT_WSDL_LOCATION_EXPRESSION} will be used, but this expression can be overriden by setting the {@link
42   * #setLocationExpression(String) locationExpression} property.
43   *
44   * @author Tareq Abed Rabbo
45   * @author Arjen Poutsma
46   * @since 1.5.4
47   */
48  public class Wsdl11DestinationProvider extends AbstractCachingDestinationProvider {
49  
50      /** Default XPath expression used for extracting all <code>location</code> attributes from the WSDL definition. */
51      public static final String DEFAULT_WSDL_LOCATION_EXPRESSION =
52              "/wsdl:definitions/wsdl:service/wsdl:port/soap:address/@location";
53  
54      private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
55  
56      private Properties expressionNamespaces = new Properties();
57  
58      private XPathExpression locationXPathExpression;
59  
60      private Resource wsdlResource;
61  
62      public Wsdl11DestinationProvider() {
63          expressionNamespaces.setProperty("wsdl", "http://schemas.xmlsoap.org/wsdl/");
64          expressionNamespaces.setProperty("soap", "http://schemas.xmlsoap.org/wsdl/soap/");
65          expressionNamespaces.setProperty("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/");
66  
67          locationXPathExpression = XPathExpressionFactory
68                  .createXPathExpression(DEFAULT_WSDL_LOCATION_EXPRESSION, expressionNamespaces);
69      }
70  
71      /** Sets a WSDL location from which the service destination <code>URI</code> will be resolved. */
72      public void setWsdl(Resource wsdlResource) {
73          Assert.notNull(wsdlResource, "'wsdl' must not be null");
74          Assert.isTrue(wsdlResource.exists(), wsdlResource + " does not exist");
75          this.wsdlResource = wsdlResource;
76      }
77  
78      /**
79       * Sets the XPath expression to use when extracting the service location <code>URI</code> from a WSDL.
80       * <p/>
81       * The expression can use the following bound prefixes: <blockquote> <table> <tr><th>Prefix</th><th>Namespace</th></tr>
82       * <tr><td><code>wsdl</code></td><td><code>http://schemas.xmlsoap.org/wsdl/</code></td></tr>
83       * <tr><td><code>soap</code></td><td><code>http://schemas.xmlsoap.org/wsdl/soap/</code></td></tr>
84       * <tr><td><code>soap12</code></td><td><code>http://schemas.xmlsoap.org/wsdl/soap12/</code></td></tr>
85       * </table></blockquote>
86       * <p/>
87       * Defaults to {@link #DEFAULT_WSDL_LOCATION_EXPRESSION}.
88       */
89      public void setLocationExpression(String expression) {
90          Assert.hasText(expression, "'expression' must not be empty");
91          locationXPathExpression = XPathExpressionFactory
92                  .createXPathExpression(expression, expressionNamespaces);
93      }
94  
95      protected URI lookupDestination() {
96          try {
97              DOMResult result = new DOMResult();
98              Transformer transformer = transformerFactory.newTransformer();
99              transformer.transform(new ResourceSource(wsdlResource), result);
100             Document definitionDocument = (Document) result.getNode();
101             String location = locationXPathExpression.evaluateAsString(definitionDocument);
102             if (logger.isDebugEnabled()) {
103                 logger.debug("Found location [" + location + "] in " + wsdlResource);
104             }
105             return location != null ? URI.create(location) : null;
106         }
107         catch (IOException ex) {
108             throw new WebServiceIOException("Error extracting location from WSDL [" + wsdlResource + "]", ex);
109         }
110         catch (TransformerException ex) {
111             throw new WebServiceTransformerException("Error extracting location from WSDL [" + wsdlResource + "]", ex);
112         }
113     }
114 
115 }