Skip to content

Commit 13f537f

Browse files
committed
SWS-791 - Transform schemaLocation in WsdlDefinitionHandlerAdapter
1 parent 71e81b0 commit 13f537f

File tree

4 files changed

+138
-93
lines changed

4 files changed

+138
-93
lines changed

core/src/main/java/org/springframework/ws/transport/http/WsdlDefinitionHandlerAdapter.java

Lines changed: 115 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -43,27 +43,27 @@
4343
import org.w3c.dom.Node;
4444

4545
/**
46-
* Adapter to use the <code>WsdlDefinition</code> interface with the generic <code>DispatcherServlet</code>.
46+
* Adapter to use the {@code WsdlDefinition} interface with the generic {@code DispatcherServlet}.
4747
* <p/>
48-
* Reads the source from the mapped <code>WsdlDefinition</code> implementation, and writes that as the result to the
49-
* <code>HttpServletResponse</code>.
48+
* Reads the source from the mapped {@code WsdlDefinition} implementation, and writes that as the result to the
49+
* {@code HttpServletResponse}.
5050
* <p/>
51-
* If the property <code>transformLocations</code> is set to <code>true</code>, this adapter will change
52-
* <code>location</code> attributes in the WSDL definition to reflect the URL of the incoming request. If the location
51+
* If the property {@code transformLocations} is set to {@code true}, this adapter will change
52+
* {@code location} attributes in the WSDL definition to reflect the URL of the incoming request. If the location
5353
* field in the original WSDL is an absolute path, the scheme, hostname, and port will be changed. If the location is a
5454
* relative path, the scheme, hostname, port, and context path will be prepended. This behavior can be customized by
55-
* overriding the <code>transformLocation()</code> method.
55+
* overriding the {@code transformLocation()} method.
5656
* <p/>
57-
* For instance, if the location attribute defined in the WSDL is <code>http://localhost:8080/context/services/myService</code>,
58-
* and the request URI for the WSDL is <code>http://example.com/context/myService.wsdl</code>, the location will be
59-
* changed to <code>http://example.com/context/services/myService</code>.
57+
* For instance, if the location attribute defined in the WSDL is {@code http://localhost:8080/context/services/myService},
58+
* and the request URI for the WSDL is {@code http://example.com/context/myService.wsdl}, the location will be
59+
* changed to {@code http://example.com/context/services/myService}.
6060
* <p/>
61-
* If the location attribute defined in the WSDL is <code>/services/myService</code>, and the request URI for the WSDL
62-
* is <code>http://example.com:8080/context/myService.wsdl</code>, the location will be changed to
63-
* <code>http://example.com:8080/context/services/myService</code>.
61+
* If the location attribute defined in the WSDL is {@code /services/myService}, and the request URI for the WSDL
62+
* is {@code http://example.com:8080/context/myService.wsdl}, the location will be changed to
63+
* {@code http://example.com:8080/context/services/myService}.
6464
* <p/>
65-
* When <code>transformLocations</code> is enabled, all <code>location</code> attributes found in the WSDL definition
66-
* are changed by default. This behavior can be customized by changing the <code>locationExpression</code> property,
65+
* When {@code transformLocations} is enabled, all {@code location} attributes found in the WSDL definition
66+
* are changed by default. This behavior can be customized by changing the {@code locationExpression} property,
6767
* which is an XPath expression that matches the attributes to change.
6868
*
6969
* @author Arjen Poutsma
@@ -75,9 +75,12 @@
7575
*/
7676
public class WsdlDefinitionHandlerAdapter extends TransformerObjectSupport implements HandlerAdapter, InitializingBean {
7777

78-
/** Default XPath expression used for extracting all <code>location</code> attributes from the WSDL definition. */
78+
/** Default XPath expression used for extracting all {@code location} attributes from the WSDL definition. */
7979
public static final String DEFAULT_LOCATION_EXPRESSION = "//@location";
8080

81+
/** Default XPath expression used for extracting all {@code schemaLocation} attributes from the WSDL definition. */
82+
public static final String DEFAULT_SCHEMA_LOCATION_EXPRESSION = "//@schemaLocation";
83+
8184
private static final String CONTENT_TYPE = "text/xml";
8285

8386
private static final Log logger = LogFactory.getLog(WsdlDefinitionHandlerAdapter.class);
@@ -86,29 +89,50 @@ public class WsdlDefinitionHandlerAdapter extends TransformerObjectSupport imple
8689

8790
private String locationExpression = DEFAULT_LOCATION_EXPRESSION;
8891

92+
private String schemaLocationExpression = DEFAULT_SCHEMA_LOCATION_EXPRESSION;
93+
8994
private XPathExpression locationXPathExpression;
9095

96+
private XPathExpression schemaLocationXPathExpression;
97+
9198
private boolean transformLocations = false;
9299

100+
private boolean transformSchemaLocations = false;
101+
93102
/**
94-
* Sets the XPath expression used for extracting the <code>location</code> attributes from the WSDL 1.1 definition.
103+
* Sets the XPath expression used for extracting the {@code location} attributes from the WSDL 1.1 definition.
95104
* <p/>
96-
* Defaults to <code>DEFAULT_LOCATION_EXPRESSION</code>.
97-
*
98-
* @see #DEFAULT_LOCATION_EXPRESSION
105+
* Defaults to {@code DEFAULT_LOCATION_EXPRESSION}.
99106
*/
100107
public void setLocationExpression(String locationExpression) {
101108
this.locationExpression = locationExpression;
102109
}
103110

111+
/**
112+
* Sets the XPath expression used for extracting the {@code schemaLocation} attributes from the WSDL 1.1 definition.
113+
* <p/>
114+
* Defaults to {@code DEFAULT_SCHEMA_LOCATION_EXPRESSION}.
115+
*/
116+
public void setSchemaLocationExpression(String schemaLocationExpression) {
117+
this.schemaLocationExpression = schemaLocationExpression;
118+
}
119+
104120
/**
105121
* Sets whether relative address locations in the WSDL are to be transformed using the request URI of the incoming
106-
* <code>HttpServletRequest</code>. Defaults to <code>false</code>.
122+
* {@code HttpServletRequest}. Defaults to {@code false}.
107123
*/
108124
public void setTransformLocations(boolean transformLocations) {
109125
this.transformLocations = transformLocations;
110126
}
111127

128+
/**
129+
* Sets whether relative address schema locations in the WSDL are to be transformed using the request URI of the
130+
* incoming {@code HttpServletRequest}. Defaults to {@code false}.
131+
*/
132+
public void setTransformSchemaLocations(boolean transformSchemaLocations) {
133+
this.transformSchemaLocations = transformSchemaLocations;
134+
}
135+
112136
public long getLastModified(HttpServletRequest request, Object handler) {
113137
Source definitionSource = ((WsdlDefinition) handler).getSource();
114138
return LastModifiedHelper.getLastModified(definitionSource);
@@ -117,17 +141,25 @@ public long getLastModified(HttpServletRequest request, Object handler) {
117141
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
118142
throws Exception {
119143
if (HttpTransportConstants.METHOD_GET.equals(request.getMethod())) {
120-
response.setContentType(CONTENT_TYPE);
121-
Transformer transformer = createTransformer();
122144
WsdlDefinition definition = (WsdlDefinition) handler;
145+
146+
Transformer transformer = createTransformer();
123147
Source definitionSource = definition.getSource();
124-
if (transformLocations) {
148+
149+
if (transformLocations || transformSchemaLocations) {
125150
DOMResult domResult = new DOMResult();
126151
transformer.transform(definitionSource, domResult);
127152
Document definitionDocument = (Document) domResult.getNode();
128-
transformLocations(definitionDocument, request);
153+
if (transformLocations) {
154+
transformLocations(definitionDocument, request);
155+
}
156+
if (transformSchemaLocations) {
157+
transformSchemaLocations(definitionDocument, request);
158+
}
129159
definitionSource = new DOMSource(definitionDocument);
130160
}
161+
162+
response.setContentType(CONTENT_TYPE);
131163
StreamResult responseResult = new StreamResult(response.getOutputStream());
132164
transformer.transform(definitionSource, responseResult);
133165
}
@@ -144,22 +176,72 @@ public boolean supports(Object handler) {
144176
public void afterPropertiesSet() throws Exception {
145177
locationXPathExpression =
146178
XPathExpressionFactory.createXPathExpression(locationExpression, expressionNamespaces);
179+
schemaLocationXPathExpression =
180+
XPathExpressionFactory.createXPathExpression(schemaLocationExpression, expressionNamespaces);
181+
}
182+
183+
/**
184+
* Transforms all {@code location} attributes to reflect the server name given {@code HttpServletRequest}.
185+
* Determines the suitable attributes by evaluating the defined XPath expression, and delegates to
186+
* {@code transformLocation} to do the transformation for all attributes that match.
187+
* <p/>
188+
* This method is only called when the {@code transformLocations} property is true.
189+
*
190+
* @see #setLocationExpression(String)
191+
* @see #setTransformLocations(boolean)
192+
* @see #transformLocation(String,javax.servlet.http.HttpServletRequest)
193+
*/
194+
protected void transformLocations(Document definitionDocument, HttpServletRequest request) throws Exception {
195+
transformLocationsInternal(locationXPathExpression, definitionDocument, request);
196+
}
197+
198+
/**
199+
* Transforms all {@code schemaLocation} attributes to reflect the server name given {@code HttpServletRequest}.
200+
* Determines the suitable attributes by evaluating the defined XPath expression, and delegates to
201+
* {@code transformLocation} to do the transformation for all attributes that match.
202+
* <p/>
203+
* This method is only called when the {@code transformSchemaLocations} property is true.
204+
*
205+
* @see #setSchemaLocationExpression(String)
206+
* @see #setTransformSchemaLocations(boolean)
207+
* @see #transformLocation(String,javax.servlet.http.HttpServletRequest)
208+
*/
209+
protected void transformSchemaLocations(Document definitionDocument, HttpServletRequest request) throws Exception {
210+
transformLocationsInternal(schemaLocationXPathExpression, definitionDocument, request);
147211
}
148212

213+
private void transformLocationsInternal(XPathExpression xPathExpression,
214+
Document definitionDocument,
215+
HttpServletRequest request) throws Exception {
216+
List<Node> locationNodes = xPathExpression.evaluateAsNodeList(definitionDocument);
217+
for (Node locationNode : locationNodes) {
218+
if (locationNode instanceof Attr) {
219+
Attr location = (Attr) locationNode;
220+
if (StringUtils.hasLength(location.getValue())) {
221+
String newLocation = transformLocation(location.getValue(), request);
222+
if (logger.isDebugEnabled()) {
223+
logger.debug("Transforming [" + location.getValue() + "] to [" + newLocation + "]");
224+
}
225+
location.setValue(newLocation);
226+
}
227+
}
228+
}
229+
}
230+
149231
/**
150232
* Transform the given location string to reflect the given request. If the given location is a full url, the
151233
* scheme, server name, and port are changed. If it is a relative url, the scheme, server name, and port are
152234
* prepended. Can be overridden in subclasses to change this behavior.
153235
* <p/>
154-
* For instance, if the location attribute defined in the WSDL is <code>http://localhost:8080/context/services/myService</code>,
155-
* and the request URI for the WSDL is <code>http://example.com:8080/context/myService.wsdl</code>, the location
156-
* will be changed to <code>http://example.com:8080/context/services/myService</code>.
236+
* For instance, if the location attribute defined in the WSDL is {@code http://localhost:8080/context/services/myService},
237+
* and the request URI for the WSDL is {@code http://example.com:80/context/myService.wsdl}, the location
238+
* will be changed to {@code http://example.com:80/context/services/myService}.
157239
* <p/>
158-
* If the location attribute defined in the WSDL is <code>/services/myService</code>, and the request URI for the
159-
* WSDL is <code>http://example.com:8080/context/myService.wsdl</code>, the location will be changed to
160-
* <code>http://example.com:8080/context/services/myService</code>.
240+
* If the location attribute defined in the WSDL is {@code /services/myService}, and the request URI for the
241+
* WSDL is {@code http://example.com:8080/context/myService.wsdl}, the location will be changed to
242+
* {@code http://example.com:8080/context/services/myService}.
161243
* <p/>
162-
* This method is only called when the <code>transformLocations</code> property is true.
244+
* This method is only called when the {@code transformLocations} property is true.
163245
*/
164246
protected String transformLocation(String location, HttpServletRequest request) {
165247
StringBuilder url = new StringBuilder(request.getScheme());
@@ -184,31 +266,4 @@ protected String transformLocation(String location, HttpServletRequest request)
184266
// unknown location, return the original
185267
return location;
186268
}
187-
188-
/**
189-
* Transforms all <code>location</code> attributes to reflect the server name given <code>HttpServletRequest</code>.
190-
* Determines the suitable attributes by evaluating the defined XPath expression, and delegates to
191-
* <code>transformLocation</code> to do the transformation for all attributes that match.
192-
* <p/>
193-
* This method is only called when the <code>transformLocations</code> property is true.
194-
*
195-
* @see #setLocationExpression(String)
196-
* @see #setTransformLocations(boolean)
197-
* @see #transformLocation(String,javax.servlet.http.HttpServletRequest)
198-
*/
199-
protected void transformLocations(Document definitionDocument, HttpServletRequest request) throws Exception {
200-
List<Node> locationNodes = locationXPathExpression.evaluateAsNodeList(definitionDocument);
201-
for (Node locationNode : locationNodes) {
202-
if (locationNode instanceof Attr) {
203-
Attr location = (Attr) locationNode;
204-
if (StringUtils.hasLength(location.getValue())) {
205-
String newLocation = transformLocation(location.getValue(), request);
206-
if (logger.isDebugEnabled()) {
207-
logger.debug("Transforming [" + location.getValue() + "] to [" + newLocation + "]");
208-
}
209-
location.setValue(newLocation);
210-
}
211-
}
212-
}
213-
}
214269
}

0 commit comments

Comments
 (0)