View Javadoc
1   /*
2    * Copyright (c) 1997, 2012, 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 <tt>next</tt> 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 <tt>next</tt> 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 <tt>binding</tt> 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 <tt>null</tt>. 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 }