1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.api.pipe; 27 28 import com.sun.istack.internal.Nullable; 29 import com.sun.xml.internal.ws.api.WSBinding; 30 import com.sun.xml.internal.ws.api.WSService; 31 import com.sun.xml.internal.ws.api.client.WSPortInfo; 32 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; 33 import com.sun.xml.internal.ws.api.message.Message; 34 import com.sun.xml.internal.ws.api.message.Packet; 35 import com.sun.xml.internal.ws.api.model.SEIModel; 36 import com.sun.xml.internal.ws.binding.BindingImpl; 37 import com.sun.xml.internal.ws.client.WSServiceDelegate; 38 import com.sun.xml.internal.ws.client.dispatch.DataSourceDispatch; 39 import com.sun.xml.internal.ws.client.dispatch.DispatchImpl; 40 import com.sun.xml.internal.ws.client.dispatch.JAXBDispatch; 41 import com.sun.xml.internal.ws.client.dispatch.MessageDispatch; 42 import com.sun.xml.internal.ws.client.dispatch.PacketDispatch; 43 import com.sun.xml.internal.ws.client.sei.SEIStub; 44 import com.sun.xml.internal.ws.developer.WSBindingProvider; 45 import com.sun.xml.internal.ws.model.SOAPSEIModel; 46 47 import javax.activation.DataSource; 48 import javax.xml.bind.JAXBContext; 49 import javax.xml.namespace.QName; 50 import javax.xml.soap.SOAPMessage; 51 import javax.xml.transform.Source; 52 import javax.xml.ws.BindingProvider; 53 import javax.xml.ws.Dispatch; 54 import javax.xml.ws.Service; 55 import javax.xml.ws.Service.Mode; 56 import javax.xml.ws.WebServiceException; 57 import java.lang.reflect.Proxy; 58 59 /** 60 * Factory methods of various stubs. 61 * 62 * <p> 63 * This class provides various methods to create "stub"s, 64 * which are the component that turns a method invocation 65 * into a {@link Message} and back into a return value. 66 * 67 * <p> 68 * This class is meant to serve as the API from JAX-WS to 69 * Tango, so that they don't have hard-code dependency on 70 * our implementation classes. 71 * 72 * <a name="param"></a> 73 * <h2>Common Parameters and Their Meanings</h2> 74 * 75 * <h3>Pipe next</h3> 76 * <p> 77 * Stubs turn a method invocation into a {@link Pipe#process(com.sun.xml.internal.ws.api.message.Packet)} invocation, 78 * and this pipe passed in as the {@code next} parameter will receive a {@link Message} 79 * from newly created stub. All the methods taking Tube <<next>> parameter are deprecated. JAX-WS Runtime takes care of 80 * creating the tubeline when the {@code next} parameter is not passed. This gives flexibility for the JAX-WS Runtime 81 * to pass extra information during the tube line creation via {@link ClientTubeAssemblerContext}. 82 * 83 * <h3>WSPortInfo portInfo</h3> 84 * <p> Gives information about the port for which the "stub" being created. Such information includes Port QName, 85 * target endpoint address, and bindingId etc. 86 * 87 * <h3>BindingImpl binding</h3> 88 * <p> 89 * Stubs implement {@link BindingProvider}, and its {@link BindingProvider#getBinding()} 90 * will return this {@code binding} object. Stubs often also use this information 91 * to decide which SOAP version a {@link Message} should be created in. 92 * 93 * <h3>{@link WSService} service</h3> 94 * <p> 95 * This object represents a {@link Service} that owns the newly created stub. 96 * For example, asynchronous method invocation will use {@link Service#getExecutor()}. 97 * 98 * <h3>{@link WSEndpointReference} epr</h3> 99 * <p> 100 * If you want the created {@link Dispatch} to talk to the given EPR, specify the parameter. 101 * Otherwise leave it {@code null}. Note that the addressing needs to be enabled separately 102 * for this to take effect. 103 * 104 * @author Kohsuke Kawaguchi 105 * @author Kathy Walsh 106 */ 107 public abstract class Stubs { 108 private Stubs() {} // no instanciation please 109 110 /** 111 * Creates a new {@link Dispatch} stub for {@link SOAPMessage}. 112 * 113 * This is short-cut of calling 114 * <pre> 115 * createDispatch(port,owner,binding,SOAPMessage.class,mode,next); 116 * </pre> 117 */ 118 @Deprecated 119 public static Dispatch<SOAPMessage> createSAAJDispatch(QName portName, WSService owner, WSBinding binding, Service.Mode mode, Tube next, @Nullable WSEndpointReference epr) { 120 DispatchImpl.checkValidSOAPMessageDispatch(binding, mode); 121 return new com.sun.xml.internal.ws.client.dispatch.SOAPMessageDispatch(portName, mode, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 122 } 123 124 /** 125 * Creates a new {@link Dispatch} stub for {@link SOAPMessage}. 126 * 127 * This is short-cut of calling 128 * <pre> 129 * createDispatch(port,owner,binding,SOAPMessage.class,mode,next); 130 * </pre> 131 */ 132 public static Dispatch<SOAPMessage> createSAAJDispatch(WSPortInfo portInfo, WSBinding binding, Service.Mode mode, @Nullable WSEndpointReference epr) { 133 DispatchImpl.checkValidSOAPMessageDispatch(binding, mode); 134 return new com.sun.xml.internal.ws.client.dispatch.SOAPMessageDispatch(portInfo, mode, (BindingImpl)binding, epr); 135 } 136 137 /** 138 * Creates a new {@link Dispatch} stub for {@link DataSource}. 139 * 140 * This is short-cut of calling 141 * <pre> 142 * createDispatch(port,owner,binding,DataSource.class,mode,next); 143 * </pre> 144 */ 145 @Deprecated 146 public static Dispatch<DataSource> createDataSourceDispatch(QName portName, WSService owner, WSBinding binding, Service.Mode mode, Tube next, @Nullable WSEndpointReference epr) { 147 DispatchImpl.checkValidDataSourceDispatch(binding, mode); 148 return new DataSourceDispatch(portName, mode, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 149 } 150 151 /** 152 * Creates a new {@link Dispatch} stub for {@link DataSource}. 153 * 154 * This is short-cut of calling 155 * <pre> 156 * createDispatch(port,owner,binding,DataSource.class,mode,next); 157 * </pre> 158 */ 159 public static Dispatch<DataSource> createDataSourceDispatch(WSPortInfo portInfo, WSBinding binding, Service.Mode mode,@Nullable WSEndpointReference epr) { 160 DispatchImpl.checkValidDataSourceDispatch(binding, mode); 161 return new DataSourceDispatch(portInfo, mode, (BindingImpl)binding, epr); 162 } 163 164 /** 165 * Creates a new {@link Dispatch} stub for {@link Source}. 166 * 167 * This is short-cut of calling 168 * <pre> 169 * createDispatch(port,owner,binding,Source.class,mode,next); 170 * </pre> 171 */ 172 @Deprecated 173 public static Dispatch<Source> createSourceDispatch(QName portName, WSService owner, WSBinding binding, Service.Mode mode, Tube next, @Nullable WSEndpointReference epr) { 174 return DispatchImpl.createSourceDispatch(portName, mode, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 175 } 176 177 /** 178 * Creates a new {@link Dispatch} stub for {@link Source}. 179 * 180 * This is short-cut of calling 181 * <pre> 182 * createDispatch(port,owner,binding,Source.class,mode,next); 183 * </pre> 184 */ 185 public static Dispatch<Source> createSourceDispatch(WSPortInfo portInfo, WSBinding binding, Service.Mode mode, @Nullable WSEndpointReference epr) { 186 return DispatchImpl.createSourceDispatch(portInfo, mode, (BindingImpl)binding, epr); 187 } 188 189 /** 190 * Creates a new {@link Dispatch} stub that connects to the given pipe. 191 * 192 * @param portName 193 * see {@link Service#createDispatch(QName, Class, Service.Mode)}. 194 * @param owner 195 * see <a href="#param">common parameters</a> 196 * @param binding 197 * see <a href="#param">common parameters</a> 198 * @param clazz 199 * Type of the {@link Dispatch} to be created. 200 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 201 * @param mode 202 * The mode of the dispatch. 203 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 204 * @param next 205 * see <a href="#param">common parameters</a> 206 * @param epr 207 * see <a href="#param">common parameters</a> 208 * TODO: are these parameters making sense? 209 */ 210 @SuppressWarnings("unchecked") 211 public static <T> Dispatch<T> createDispatch(QName portName, 212 WSService owner, 213 WSBinding binding, 214 Class<T> clazz, Service.Mode mode, Tube next, 215 @Nullable WSEndpointReference epr) { 216 if (clazz == SOAPMessage.class) { 217 return (Dispatch<T>) createSAAJDispatch(portName, owner, binding, mode, next, epr); 218 } else if (clazz == Source.class) { 219 return (Dispatch<T>) createSourceDispatch(portName, owner, binding, mode, next, epr); 220 } else if (clazz == DataSource.class) { 221 return (Dispatch<T>) createDataSourceDispatch(portName, owner, binding, mode, next, epr); 222 } else if (clazz == Message.class) { 223 if(mode==Mode.MESSAGE) 224 return (Dispatch<T>) createMessageDispatch(portName, owner, binding, next, epr); 225 else 226 throw new WebServiceException(mode+" not supported with Dispatch<Message>"); 227 } else if (clazz == Packet.class) { 228 return (Dispatch<T>) createPacketDispatch(portName, owner, binding, next, epr); 229 } else 230 throw new WebServiceException("Unknown class type " + clazz.getName()); 231 } 232 233 /** 234 * Creates a new {@link Dispatch} stub that connects to the given pipe. 235 * 236 * @param portInfo 237 * see <a href="#param">common parameters</a> 238 * @param owner 239 * see <a href="#param">common parameters</a> 240 * @param binding 241 * see <a href="#param">common parameters</a> 242 * @param clazz 243 * Type of the {@link Dispatch} to be created. 244 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 245 * @param mode 246 * The mode of the dispatch. 247 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 248 * @param epr 249 * see <a href="#param">common parameters</a> 250 * TODO: are these parameters making sense? 251 */ 252 public static <T> Dispatch<T> createDispatch(WSPortInfo portInfo, 253 WSService owner, 254 WSBinding binding, 255 Class<T> clazz, Service.Mode mode, 256 @Nullable WSEndpointReference epr) { 257 if (clazz == SOAPMessage.class) { 258 return (Dispatch<T>) createSAAJDispatch(portInfo, binding, mode, epr); 259 } else if (clazz == Source.class) { 260 return (Dispatch<T>) createSourceDispatch(portInfo, binding, mode, epr); 261 } else if (clazz == DataSource.class) { 262 return (Dispatch<T>) createDataSourceDispatch(portInfo, binding, mode, epr); 263 } else if (clazz == Message.class) { 264 if(mode==Mode.MESSAGE) 265 return (Dispatch<T>) createMessageDispatch(portInfo, binding, epr); 266 else 267 throw new WebServiceException(mode+" not supported with Dispatch<Message>"); 268 } else if (clazz == Packet.class) { 269 if(mode==Mode.MESSAGE) 270 return (Dispatch<T>) createPacketDispatch(portInfo, binding, epr); 271 else 272 throw new WebServiceException(mode+" not supported with Dispatch<Packet>"); 273 } else 274 throw new WebServiceException("Unknown class type " + clazz.getName()); 275 } 276 277 /** 278 * Creates a new JAXB-based {@link Dispatch} stub that connects to the given pipe. 279 * 280 * @param portName 281 * see {@link Service#createDispatch(QName, Class, Service.Mode)}. 282 * @param owner 283 * see <a href="#param">common parameters</a> 284 * @param binding 285 * see <a href="#param">common parameters</a> 286 * @param jaxbContext 287 * {@link JAXBContext} used to convert between objects and XML. 288 * @param mode 289 * The mode of the dispatch. 290 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 291 * @param next 292 * see <a href="#param">common parameters</a> 293 * @param epr 294 * see <a href="#param">common parameters</a> 295 */ 296 @Deprecated 297 public static Dispatch<Object> createJAXBDispatch( 298 QName portName, WSService owner, WSBinding binding, 299 JAXBContext jaxbContext, Service.Mode mode, Tube next, 300 @Nullable WSEndpointReference epr) { 301 return new JAXBDispatch(portName, jaxbContext, mode, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 302 } 303 304 /** 305 * Creates a new JAXB-based {@link Dispatch} stub that connects to the given pipe. 306 * 307 * @param portInfo see <a href="#param">common parameters</a> 308 * @param binding see <a href="#param">common parameters</a> 309 * @param jaxbContext {@link JAXBContext} used to convert between objects and XML. 310 * @param mode The mode of the dispatch. 311 * See {@link Service#createDispatch(QName, Class, Service.Mode)}. 312 * @param epr see <a href="#param">common parameters</a> 313 */ 314 public static Dispatch<Object> createJAXBDispatch( 315 WSPortInfo portInfo, WSBinding binding, 316 JAXBContext jaxbContext, Service.Mode mode, 317 @Nullable WSEndpointReference epr) { 318 return new JAXBDispatch(portInfo, jaxbContext, mode, (BindingImpl) binding, epr); 319 } 320 321 322 /** 323 * Creates a new {@link Message}-based {@link Dispatch} stub that connects to the given pipe. 324 * The returned dispatch is always {@link Mode#MESSAGE}. 325 * 326 * @param portName 327 * see {@link Service#createDispatch(QName, Class, Service.Mode)}. 328 * @param owner 329 * see <a href="#param">common parameters</a> 330 * @param binding 331 * see <a href="#param">common parameters</a> 332 * @param next 333 * see <a href="#param">common parameters</a> 334 * @param epr 335 * see <a href="#param">common parameters</a> 336 */ 337 @Deprecated 338 public static Dispatch<Message> createMessageDispatch( 339 QName portName, WSService owner, WSBinding binding, 340 Tube next, @Nullable WSEndpointReference epr) { 341 return new MessageDispatch(portName, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 342 } 343 344 345 /** 346 * Creates a new {@link Message}-based {@link Dispatch} stub that connects to the given pipe. 347 * The returned dispatch is always {@link Mode#MESSAGE}. 348 * 349 * @param portInfo 350 * see <a href="#param">common parameters</a> 351 * @param binding 352 * see <a href="#param">common parameters</a> 353 * @param epr 354 * see <a href="#param">common parameters</a> 355 */ 356 public static Dispatch<Message> createMessageDispatch( 357 WSPortInfo portInfo, WSBinding binding, 358 @Nullable WSEndpointReference epr) { 359 return new MessageDispatch(portInfo, (BindingImpl)binding, epr); 360 } 361 362 /** 363 * Creates a new {@link Packet}-based {@link Dispatch} stub that connects to the given pipe. 364 * 365 * @param portName 366 * see {@link Service#createDispatch(QName, Class, Service.Mode)}. 367 * @param owner 368 * see <a href="#param">common parameters</a> 369 * @param binding 370 * see <a href="#param">common parameters</a> 371 * @param next 372 * see <a href="#param">common parameters</a> 373 * @param epr 374 * see <a href="#param">common parameters</a> 375 */ 376 public static Dispatch<Packet> createPacketDispatch( 377 QName portName, WSService owner, WSBinding binding, 378 Tube next, @Nullable WSEndpointReference epr) { 379 return new PacketDispatch(portName, (WSServiceDelegate)owner, next, (BindingImpl)binding, epr); 380 } 381 382 /** 383 * Creates a new {@link Message}-based {@link Dispatch} stub that connects to the given pipe. 384 * The returned dispatch is always {@link Mode#MESSAGE}. 385 * 386 * @param portInfo 387 * see <a href="#param">common parameters</a> 388 * @param binding 389 * see <a href="#param">common parameters</a> 390 * @param epr 391 * see <a href="#param">common parameters</a> 392 */ 393 public static Dispatch<Packet> createPacketDispatch( 394 WSPortInfo portInfo, WSBinding binding, 395 @Nullable WSEndpointReference epr) { 396 return new PacketDispatch(portInfo, (BindingImpl)binding, epr); 397 } 398 399 /** 400 * Creates a new strongly-typed proxy object that implements a given port interface. 401 * 402 * @param service 403 * see <a href="#param">common parameters</a> 404 * @param binding 405 * see <a href="#param">common parameters</a> 406 * @param model 407 * This model shall represent a port interface. 408 * TODO: can model be constructed from portInterface and binding? 409 * Find out and update. 410 * @param portInterface 411 * The port interface that has operations as Java methods. 412 * @param next 413 * see <a href="#param">common parameters</a> 414 * @param epr 415 * see <a href="#param">common parameters</a> 416 */ 417 public <T> T createPortProxy( WSService service, WSBinding binding, SEIModel model, 418 Class<T> portInterface, Tube next, @Nullable WSEndpointReference epr ) { 419 420 SEIStub ps = new SEIStub((WSServiceDelegate)service,(BindingImpl)binding, (SOAPSEIModel)model, next, epr); 421 return portInterface.cast( 422 Proxy.newProxyInstance( portInterface.getClassLoader(), 423 new Class[]{portInterface, WSBindingProvider.class}, ps )); 424 } 425 426 /** 427 * Creates a new strongly-typed proxy object that implements a given port interface. 428 * 429 * @param portInfo 430 * see <a href="#param">common parameters</a> 431 * @param binding 432 * see <a href="#param">common parameters</a> 433 * @param model 434 * This model shall represent a port interface. 435 * TODO: can model be constructed from portInterface and binding? 436 * Find out and update. 437 * @param portInterface 438 * The port interface that has operations as Java methods. 439 * @param epr 440 * see <a href="#param">common parameters</a> 441 */ 442 public <T> T createPortProxy( WSPortInfo portInfo, WSBinding binding, SEIModel model, 443 Class<T> portInterface, @Nullable WSEndpointReference epr ) { 444 445 SEIStub ps = new SEIStub(portInfo, (BindingImpl)binding, (SOAPSEIModel)model, epr); 446 return portInterface.cast( 447 Proxy.newProxyInstance( portInterface.getClassLoader(), 448 new Class[]{portInterface, WSBindingProvider.class}, ps )); 449 } 450 }