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 }