001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.api.pipe;
038:
039: import com.sun.istack.Nullable;
040: import com.sun.xml.ws.api.WSBinding;
041: import com.sun.xml.ws.api.WSService;
042: import com.sun.xml.ws.api.addressing.WSEndpointReference;
043: import com.sun.xml.ws.api.message.Message;
044: import com.sun.xml.ws.api.model.SEIModel;
045: import com.sun.xml.ws.binding.BindingImpl;
046: import com.sun.xml.ws.client.WSServiceDelegate;
047: import com.sun.xml.ws.client.dispatch.DataSourceDispatch;
048: import com.sun.xml.ws.client.dispatch.DispatchImpl;
049: import com.sun.xml.ws.client.dispatch.JAXBDispatch;
050: import com.sun.xml.ws.client.dispatch.MessageDispatch;
051: import com.sun.xml.ws.client.sei.SEIStub;
052: import com.sun.xml.ws.developer.WSBindingProvider;
053: import com.sun.xml.ws.model.SOAPSEIModel;
054:
055: import javax.activation.DataSource;
056: import javax.xml.bind.JAXBContext;
057: import javax.xml.namespace.QName;
058: import javax.xml.soap.SOAPMessage;
059: import javax.xml.transform.Source;
060: import javax.xml.ws.BindingProvider;
061: import javax.xml.ws.Dispatch;
062: import javax.xml.ws.Service;
063: import javax.xml.ws.Service.Mode;
064: import javax.xml.ws.WebServiceException;
065: import java.lang.reflect.Proxy;
066:
067: /**
068: * Factory methods of various stubs.
069: *
070: * <p>
071: * This class provides various methods to create "stub"s,
072: * which are the component that turns a method invocation
073: * into a {@link Message} and back into a return value.
074: *
075: * <p>
076: * This class is meant to serve as the API from JAX-WS to
077: * Tango, so that they don't have hard-code dependency on
078: * our implementation classes.
079: *
080: * <a name="param"></a>
081: * <h2>Common Parameters and Their Meanings</h2>
082: *
083: * <h3>Pipe next</h3>
084: * <p>
085: * Stubs turn a method invocation into a {@link Pipe#process(com.sun.xml.ws.api.message.Packet)} invocation,
086: * and this pipe passed in as the <tt>next</tt> parameter will receive a {@link Message}
087: * from newly created stub.
088: *
089: * <h3>BindingImpl binding</h3>
090: * <p>
091: * Stubs implement {@link BindingProvider}, and its {@link BindingProvider#getBinding()}
092: * will return this <tt>binding</tt> object. Stubs often also use this information
093: * to decide which SOAP version a {@link Message} should be created in.
094: *
095: * <h3>{@link WSService} service</h3>
096: * <p>
097: * This object represents a {@link Service} that owns the newly created stub.
098: * For example, asynchronous method invocation will use {@link Service#getExecutor()}.
099: *
100: * <h3>{@link WSEndpointReference} epr</h3>
101: * <p>
102: * If you want the created {@link Dispatch} to talk to the given EPR, specify the parameter.
103: * Otherwise leave it <tt>null</tt>. Note that the addressing needs to be enabled separately
104: * for this to take effect.
105: *
106: * @author Kohsuke Kawaguchi
107: * @author Kathy Walsh
108: */
109: public abstract class Stubs {
110: private Stubs() {
111: } // no instanciation please
112:
113: /**
114: * Creates a new {@link Dispatch} stub for {@link SOAPMessage}.
115: *
116: * This is short-cut of calling
117: * <pre>
118: * createDispatch(port,owner,binding,SOAPMessage.class,mode,next);
119: * </pre>
120: */
121: public static Dispatch<SOAPMessage> createSAAJDispatch(
122: QName portName, WSService owner, WSBinding binding,
123: Service.Mode mode, Tube next, @Nullable
124: WSEndpointReference epr) {
125: DispatchImpl.checkValidSOAPMessageDispatch(binding, mode);
126: return new com.sun.xml.ws.client.dispatch.SOAPMessageDispatch(
127: portName, mode, (WSServiceDelegate) owner, next,
128: (BindingImpl) binding, epr);
129: }
130:
131: /**
132: * Creates a new {@link Dispatch} stub for {@link DataSource}.
133: *
134: * This is short-cut of calling
135: * <pre>
136: * createDispatch(port,owner,binding,DataSource.class,mode,next);
137: * </pre>
138: */
139: public static Dispatch<DataSource> createDataSourceDispatch(
140: QName portName, WSService owner, WSBinding binding,
141: Service.Mode mode, Tube next, @Nullable
142: WSEndpointReference epr) {
143: DispatchImpl.checkValidDataSourceDispatch(binding, mode);
144: return new DataSourceDispatch(portName, mode,
145: (WSServiceDelegate) owner, next, (BindingImpl) binding,
146: epr);
147: }
148:
149: /**
150: * Creates a new {@link Dispatch} stub for {@link Source}.
151: *
152: * This is short-cut of calling
153: * <pre>
154: * createDispatch(port,owner,binding,Source.class,mode,next);
155: * </pre>
156: */
157: public static Dispatch<Source> createSourceDispatch(QName portName,
158: WSService owner, WSBinding binding, Service.Mode mode,
159: Tube next, @Nullable
160: WSEndpointReference epr) {
161: return DispatchImpl.createSourceDispatch(portName, mode,
162: (WSServiceDelegate) owner, next, (BindingImpl) binding,
163: epr);
164: }
165:
166: /**
167: * Creates a new {@link Dispatch} stub that connects to the given pipe.
168: *
169: * @param portName
170: * see {@link Service#createDispatch(QName, Class, Service.Mode)}.
171: * @param owner
172: * see <a href="#param">common parameters</a>
173: * @param binding
174: * see <a href="#param">common parameters</a>
175: * @param clazz
176: * Type of the {@link Dispatch} to be created.
177: * See {@link Service#createDispatch(QName, Class, Service.Mode)}.
178: * @param mode
179: * The mode of the dispatch.
180: * See {@link Service#createDispatch(QName, Class, Service.Mode)}.
181: * @param next
182: * see <a href="#param">common parameters</a>
183: * @param epr
184: * see <a href="#param">common parameters</a>
185: * TODO: are these parameters making sense?
186: */
187: public static <T> Dispatch<T> createDispatch(QName portName,
188: WSService owner, WSBinding binding, Class<T> clazz,
189: Service.Mode mode, Tube next, @Nullable
190: WSEndpointReference epr) {
191: if (clazz == SOAPMessage.class) {
192: return (Dispatch<T>) createSAAJDispatch(portName, owner,
193: binding, mode, next, epr);
194: } else if (clazz == Source.class) {
195: return (Dispatch<T>) createSourceDispatch(portName, owner,
196: binding, mode, next, epr);
197: } else if (clazz == DataSource.class) {
198: return (Dispatch<T>) createDataSourceDispatch(portName,
199: owner, binding, mode, next, epr);
200: } else if (clazz == Message.class) {
201: if (mode == Mode.MESSAGE)
202: return (Dispatch<T>) createMessageDispatch(portName,
203: owner, binding, next, epr);
204: else
205: throw new WebServiceException(mode
206: + " not supported with Dispatch<Message>");
207: } else
208: throw new WebServiceException("Unknown class type "
209: + clazz.getName());
210: }
211:
212: /**
213: * Creates a new JAXB-based {@link Dispatch} stub that connects to the given pipe.
214: *
215: * @param portName
216: * see {@link Service#createDispatch(QName, Class, Service.Mode)}.
217: * @param owner
218: * see <a href="#param">common parameters</a>
219: * @param binding
220: * see <a href="#param">common parameters</a>
221: * @param jaxbContext
222: * {@link JAXBContext} used to convert between objects and XML.
223: * @param mode
224: * The mode of the dispatch.
225: * See {@link Service#createDispatch(QName, Class, Service.Mode)}.
226: * @param next
227: * see <a href="#param">common parameters</a>
228: * @param epr
229: * see <a href="#param">common parameters</a>
230: */
231: public static Dispatch<Object> createJAXBDispatch(QName portName,
232: WSService owner, WSBinding binding,
233: JAXBContext jaxbContext, Service.Mode mode, Tube next,
234: @Nullable
235: WSEndpointReference epr) {
236: return new JAXBDispatch(portName, jaxbContext, mode,
237: (WSServiceDelegate) owner, next, (BindingImpl) binding,
238: epr);
239: }
240:
241: /**
242: * Creates a new {@link Message}-based {@link Dispatch} stub that connects to the given pipe.
243: * The returned dispatch is always {@link Service.Mode#MESSAGE}.
244: *
245: * @param portName
246: * see {@link Service#createDispatch(QName, Class, Service.Mode)}.
247: * @param owner
248: * see <a href="#param">common parameters</a>
249: * @param binding
250: * see <a href="#param">common parameters</a>
251: * @param next
252: * see <a href="#param">common parameters</a>
253: * @param epr
254: * see <a href="#param">common parameters</a>
255: */
256: public static Dispatch<Message> createMessageDispatch(
257: QName portName, WSService owner, WSBinding binding,
258: Tube next, @Nullable
259: WSEndpointReference epr) {
260: return new MessageDispatch(portName, (WSServiceDelegate) owner,
261: next, (BindingImpl) binding, epr);
262: }
263:
264: /**
265: * Creates a new strongly-typed proxy object that implements a given port interface.
266: *
267: * @param service
268: * see <a href="#param">common parameters</a>
269: * @param binding
270: * see <a href="#param">common parameters</a>
271: * @param model
272: * This model shall represent a port interface.
273: * TODO: can model be constructed from portInterface and binding?
274: * Find out and update.
275: * @param portInterface
276: * The port interface that has operations as Java methods.
277: * @param next
278: * see <a href="#param">common parameters</a>
279: * @param epr
280: * see <a href="#param">common parameters</a>
281: */
282: public <T> T createPortProxy(WSService service, WSBinding binding,
283: SEIModel model, Class<T> portInterface, Tube next,
284: @Nullable
285: WSEndpointReference epr) {
286:
287: SEIStub ps = new SEIStub((WSServiceDelegate) service,
288: (BindingImpl) binding, (SOAPSEIModel) model, next, epr);
289: return portInterface.cast(Proxy.newProxyInstance(portInterface
290: .getClassLoader(), new Class[] { portInterface,
291: WSBindingProvider.class }, ps));
292: }
293: }
|