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