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 java.util.Properties;
21 import javax.wsdl.Binding;
22 import javax.wsdl.BindingFault;
23 import javax.wsdl.BindingInput;
24 import javax.wsdl.BindingOperation;
25 import javax.wsdl.BindingOutput;
26 import javax.wsdl.Definition;
27 import javax.wsdl.Fault;
28 import javax.wsdl.Input;
29 import javax.wsdl.Output;
30 import javax.wsdl.Port;
31 import javax.wsdl.WSDLException;
32 import javax.wsdl.extensions.ExtensibilityElement;
33 import javax.wsdl.extensions.ExtensionRegistry;
34 import javax.wsdl.extensions.soap.SOAPAddress;
35 import javax.wsdl.extensions.soap.SOAPBinding;
36 import javax.wsdl.extensions.soap.SOAPBody;
37 import javax.wsdl.extensions.soap.SOAPFault;
38 import javax.wsdl.extensions.soap.SOAPOperation;
39 import javax.xml.namespace.QName;
40
41 import org.springframework.util.Assert;
42
43 /**
44 * Implementation of the {@link BindingsProvider} and {@link ServicesProvider} interfaces that are SOAP 1.1 specific.
45 * <p/>
46 * By setting the {@link #setSoapActions(java.util.Properties) soapActions} property, the SOAP Actions defined in the
47 * resulting WSDL can be set. Additionaly, the transport uri can be changed from the default HTTP transport by using the
48 * {@link #setTransportUri(String) transportUri} property.
49 *
50 * @author Arjen Poutsma
51 * @since 1.5.0
52 */
53 public class Soap11Provider extends DefaultConcretePartProvider {
54
55 /** The default transport URI, which indicates an HTTP transport. */
56 public static final String DEFAULT_TRANSPORT_URI = "http://schemas.xmlsoap.org/soap/http";
57
58 /** The prefix of the WSDL SOAP 1.1 namespace. */
59 public static final String SOAP_11_NAMESPACE_PREFIX = "soap";
60
61 /** The WSDL SOAP 1.1 namespace. */
62 public static final String SOAP_11_NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/soap/";
63
64 private String transportUri = DEFAULT_TRANSPORT_URI;
65
66 private Properties soapActions = new Properties();
67
68 private String locationUri;
69
70 /**
71 * Constructs a new version of the {@link Soap11Provider}.
72 * <p/>
73 * Sets the {@link #setBindingSuffix(String) binding suffix} to <code>Soap11</code>.
74 */
75 public Soap11Provider() {
76 setBindingSuffix("Soap11");
77 }
78
79 /**
80 * Returns the SOAP Actions for this binding. Keys are {@link BindingOperation#getName() binding operation names};
81 * values are {@link javax.wsdl.extensions.soap.SOAPOperation#getSoapActionURI() SOAP Action URIs}.
82 *
83 * @return the soap actions
84 */
85 public Properties getSoapActions() {
86 return soapActions;
87 }
88
89 /**
90 * Sets the SOAP Actions for this binding. Keys are {@link BindingOperation#getName() binding operation names};
91 * values are {@link javax.wsdl.extensions.soap.SOAPOperation#getSoapActionURI() SOAP Action URIs}.
92 *
93 * @param soapActions the soap
94 */
95 public void setSoapActions(Properties soapActions) {
96 Assert.notNull(soapActions, "'soapActions' must not be null");
97 this.soapActions = soapActions;
98 }
99
100 /**
101 * Returns the value used for the binding transport attribute value. Defaults to {@link #DEFAULT_TRANSPORT_URI}.
102 *
103 * @return the binding transport value
104 */
105 public String getTransportUri() {
106 return transportUri;
107 }
108
109 /**
110 * Sets the value used for the binding transport attribute value. Defaults to {@link #DEFAULT_TRANSPORT_URI}.
111 *
112 * @param transportUri the binding transport value
113 */
114 public void setTransportUri(String transportUri) {
115 Assert.notNull(transportUri, "'transportUri' must not be null");
116 this.transportUri = transportUri;
117 }
118
119 /** Returns the value used for the SOAP Address location attribute value. */
120 public String getLocationUri() {
121 return locationUri;
122 }
123
124 /** Sets the value used for the SOAP Address location attribute value. */
125 public void setLocationUri(String locationUri) {
126 this.locationUri = locationUri;
127 }
128
129 /**
130 * Called after the {@link Binding} has been created, but before any sub-elements are added. Subclasses can override
131 * this method to define the binding name, or add extensions to it.
132 * <p/>
133 * Default implementation calls {@link DefaultConcretePartProvider#populateBinding(Definition, Binding)}, adds the
134 * SOAP 1.1 namespace, creates a {@link SOAPBinding}, and calls {@link #populateSoapBinding(SOAPBinding, Binding)}
135 * sets the binding name to the port type name with the {@link #getBindingSuffix() suffix} appended to it.
136 *
137 * @param definition the WSDL4J <code>Definition</code>
138 * @param binding the WSDL4J <code>Binding</code>
139 */
140 @Override
141 protected void populateBinding(Definition definition, Binding binding) throws WSDLException {
142 definition.addNamespace(SOAP_11_NAMESPACE_PREFIX, SOAP_11_NAMESPACE_URI);
143 super.populateBinding(definition, binding);
144 SOAPBinding soapBinding = (SOAPBinding) createSoapExtension(definition, Binding.class, "binding");
145 populateSoapBinding(soapBinding, binding);
146 binding.addExtensibilityElement(soapBinding);
147 }
148
149 /**
150 * Called after the {@link SOAPBinding} has been created.
151 * <p/>
152 * Default implementation sets the binding style to <code>"document"</code>, and set the transport URI to the {@link
153 * #setTransportUri(String) transportUri} property value. Subclasses can override this behavior.
154 *
155 * @param soapBinding the WSDL4J <code>SOAPBinding</code>
156 * @throws WSDLException in case of errors
157 * @see SOAPBinding#setStyle(String)
158 * @see SOAPBinding#setTransportURI(String)
159 * @see #setTransportUri(String)
160 * @see #DEFAULT_TRANSPORT_URI
161 */
162 protected void populateSoapBinding(SOAPBinding soapBinding, Binding binding) throws WSDLException {
163 soapBinding.setStyle("document");
164 soapBinding.setTransportURI(getTransportUri());
165 }
166
167 /**
168 * Called after the {@link BindingFault} has been created. Subclasses can override this method to define the name,
169 * or add extensions to it.
170 * <p/>
171 * Default implementation calls {@link DefaultConcretePartProvider#populateBindingFault(Definition, BindingFault,
172 * Fault)}, creates a {@link SOAPFault}, and calls {@link #populateSoapFault(BindingFault, SOAPFault)}.
173 *
174 * @param definition the WSDL4J <code>Definition</code>
175 * @param bindingFault the WSDL4J <code>BindingFault</code>
176 * @param fault the corresponding WSDL4J <code>Fault</code> @throws WSDLException in case of errors
177 */
178 @Override
179 protected void populateBindingFault(Definition definition, BindingFault bindingFault, Fault fault)
180 throws WSDLException {
181 super.populateBindingFault(definition, bindingFault, fault);
182 SOAPFault soapFault = (SOAPFault) createSoapExtension(definition, BindingFault.class, "fault");
183 populateSoapFault(bindingFault, soapFault);
184 bindingFault.addExtensibilityElement(soapFault);
185 }
186
187 /**
188 * Called after the {@link SOAPFault} has been created.
189 * <p/>
190 * Default implementation sets the use style to <code>"literal"</code>, and sets the name equal to the binding
191 * fault. Subclasses can override this behavior.
192 *
193 * @param bindingFault the WSDL4J <code>BindingFault</code>
194 * @param soapFault the WSDL4J <code>SOAPFault</code>
195 * @throws WSDLException in case of errors
196 * @see SOAPFault#setUse(String)
197 */
198 protected void populateSoapFault(BindingFault bindingFault, SOAPFault soapFault) throws WSDLException {
199 soapFault.setName(bindingFault.getName());
200 soapFault.setUse("literal");
201 }
202
203 /**
204 * Called after the {@link BindingInput} has been created. Subclasses can implement this method to define the name,
205 * or add extensions to it.
206 * <p/>
207 * Default implementation calls {@link DefaultConcretePartProvider#populateBindingInput(Definition,
208 * javax.wsdl.BindingInput, javax.wsdl.Input)}, creates a {@link SOAPBody}, and calls {@link
209 * #populateSoapBody(SOAPBody)}.
210 *
211 * @param definition the WSDL4J <code>Definition</code>
212 * @param bindingInput the WSDL4J <code>BindingInput</code>
213 * @param input the corresponding WSDL4J <code>Input</code> @throws WSDLException in case of errors
214 */
215 @Override
216 protected void populateBindingInput(Definition definition, BindingInput bindingInput, Input input)
217 throws WSDLException {
218 super.populateBindingInput(definition, bindingInput, input);
219 SOAPBody soapBody = (SOAPBody) createSoapExtension(definition, BindingInput.class, "body");
220 populateSoapBody(soapBody);
221 bindingInput.addExtensibilityElement(soapBody);
222 }
223
224 /**
225 * Called after the {@link SOAPBody} has been created.
226 * <p/>
227 * Default implementation sets the use style to <code>"literal"</code>. Subclasses can override this behavior.
228 *
229 * @param soapBody the WSDL4J <code>SOAPBody</code>
230 * @throws WSDLException in case of errors
231 * @see SOAPBody#setUse(String)
232 */
233 protected void populateSoapBody(SOAPBody soapBody) throws WSDLException {
234 soapBody.setUse("literal");
235 }
236
237 /**
238 * Called after the {@link BindingOperation} has been created, but before any sub-elements are added. Subclasses can
239 * implement this method to define the binding name, or add extensions to it.
240 * <p/>
241 * Default implementation calls {@link DefaultConcretePartProvider#populateBindingOperation(Definition,
242 * BindingOperation)}, creates a {@link SOAPOperation}, and calls {@link #populateSoapOperation} sets the name of
243 * the binding operation to the name of the operation.
244 *
245 * @param definition the WSDL4J <code>Definition</code>
246 * @param bindingOperation the WSDL4J <code>BindingOperation</code>
247 * @throws WSDLException in case of errors
248 */
249 @Override
250 protected void populateBindingOperation(Definition definition, BindingOperation bindingOperation)
251 throws WSDLException {
252 super.populateBindingOperation(definition, bindingOperation);
253 SOAPOperation soapOperation =
254 (SOAPOperation) createSoapExtension(definition, BindingOperation.class, "operation");
255 populateSoapOperation(soapOperation, bindingOperation);
256 bindingOperation.addExtensibilityElement(soapOperation);
257 }
258
259 /**
260 * Called after the {@link SOAPOperation} has been created.
261 * <p/>
262 * Default implementation sets <code>SOAPAction</code> to the corresponding {@link
263 * #setSoapActions(java.util.Properties) soapActions} property, and defaults to "".
264 *
265 * @param soapOperation the WSDL4J <code>SOAPOperation</code>
266 * @param bindingOperation the WSDL4J <code>BindingOperation</code>
267 * @throws WSDLException in case of errors
268 * @see SOAPOperation#setSoapActionURI(String)
269 * @see #setSoapActions(java.util.Properties)
270 */
271 protected void populateSoapOperation(SOAPOperation soapOperation, BindingOperation bindingOperation)
272 throws WSDLException {
273 String bindingOperationName = bindingOperation.getName();
274 String soapAction = getSoapActions().getProperty(bindingOperationName, "");
275 soapOperation.setSoapActionURI(soapAction);
276 }
277
278 /**
279 * Called after the {@link BindingInput} has been created. Subclasses can implement this method to define the name,
280 * or add extensions to it.
281 * <p/>
282 * Default implementation calls {@link DefaultConcretePartProvider#populateBindingOutput(Definition, BindingOutput,
283 * Output)}, creates a {@link SOAPBody}, and calls {@link #populateSoapBody(SOAPBody)}.
284 *
285 * @param definition the WSDL4J <code>Definition</code>
286 * @param bindingOutput the WSDL4J <code>BindingOutput</code>
287 * @param output the corresponding WSDL4J <code>Output</code> @throws WSDLException in case of errors
288 */
289 @Override
290 protected void populateBindingOutput(Definition definition, BindingOutput bindingOutput, Output output)
291 throws WSDLException {
292 super.populateBindingOutput(definition, bindingOutput, output);
293 SOAPBody soapBody = (SOAPBody) createSoapExtension(definition, BindingOutput.class, "body");
294 populateSoapBody(soapBody);
295 bindingOutput.addExtensibilityElement(soapBody);
296 }
297
298 /**
299 * Called after the {@link Port} has been created, but before any sub-elements are added. Subclasses can implement
300 * this method to define the port name, or add extensions to it.
301 * <p/>
302 * Default implementation calls {@link DefaultConcretePartProvider#populatePort(javax.wsdl.Definition,javax.wsdl.Port)},
303 * creates a {@link SOAPAddress}, and calls {@link #populateSoapAddress(SOAPAddress)}.
304 *
305 * @param port the WSDL4J <code>Port</code>
306 * @throws WSDLException in case of errors
307 */
308 @Override
309 protected void populatePort(Definition definition, Port port) throws WSDLException {
310 for (Iterator<?> iterator = port.getBinding().getExtensibilityElements().iterator(); iterator.hasNext();) {
311 if (iterator.next() instanceof SOAPBinding) {
312 // this is a SOAP 1.1 binding, create a SOAP Address for it
313 super.populatePort(definition, port);
314 SOAPAddress soapAddress = (SOAPAddress) createSoapExtension(definition, Port.class, "address");
315 populateSoapAddress(soapAddress);
316 port.addExtensibilityElement(soapAddress);
317 return;
318 }
319 }
320 }
321
322 /**
323 * Called after the {@link SOAPAddress} has been created. Default implementation sets the location URI to the value
324 * set on this builder. Subclasses can override this behavior.
325 *
326 * @param soapAddress the WSDL4J <code>SOAPAddress</code>
327 * @throws WSDLException in case of errors
328 * @see SOAPAddress#setLocationURI(String)
329 * @see #setLocationUri(String)
330 */
331 protected void populateSoapAddress(SOAPAddress soapAddress) throws WSDLException {
332 soapAddress.setLocationURI(getLocationUri());
333 }
334
335 /**
336 * Creates a SOAP extensibility element.
337 *
338 * @param definition the WSDL4J <code>Definition</code>
339 * @param parentType a class object indicating where in the WSDL definition this extension will exist
340 * @param localName the local name of the extensibility element
341 * @return the extensibility element
342 * @throws WSDLException in case of errors
343 * @see ExtensionRegistry#createExtension(Class, QName)
344 */
345 private ExtensibilityElement createSoapExtension(Definition definition, Class<?> parentType, String localName)
346 throws WSDLException {
347 return definition.getExtensionRegistry()
348 .createExtension(parentType, new QName(SOAP_11_NAMESPACE_URI, localName));
349 }
350
351 }