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 }