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.NotNull;
040: import com.sun.istack.Nullable;
041: import com.sun.xml.ws.addressing.WsaClientTube;
042: import com.sun.xml.ws.api.EndpointAddress;
043: import com.sun.xml.ws.api.WSBinding;
044: import com.sun.xml.ws.api.WSService;
045: import com.sun.xml.ws.api.addressing.AddressingVersion;
046: import com.sun.xml.ws.api.client.ClientPipelineHook;
047: import com.sun.xml.ws.api.model.SEIModel;
048: import com.sun.xml.ws.api.model.wsdl.WSDLPort;
049: import com.sun.xml.ws.api.pipe.helper.PipeAdapter;
050: import com.sun.xml.ws.api.server.Container;
051: import com.sun.xml.ws.binding.BindingImpl;
052: import com.sun.xml.ws.handler.ClientLogicalHandlerTube;
053: import com.sun.xml.ws.handler.ClientMessageHandlerTube;
054: import com.sun.xml.ws.handler.ClientSOAPHandlerTube;
055: import com.sun.xml.ws.handler.HandlerTube;
056: import com.sun.xml.ws.protocol.soap.ClientMUTube;
057: import com.sun.xml.ws.transport.DeferredTransportPipe;
058: import com.sun.xml.ws.util.pipe.DumpTube;
059:
060: import javax.xml.ws.soap.SOAPBinding;
061: import java.io.PrintStream;
062:
063: /**
064: * Factory for well-known {@link Tube} implementations
065: * that the {@link TubelineAssembler} needs to use
066: * to satisfy JAX-WS requirements.
067: *
068: * @author Jitendra Kotamraju
069: */
070: public class ClientTubeAssemblerContext {
071:
072: private final @NotNull
073: EndpointAddress address;
074: private final @NotNull
075: WSDLPort wsdlModel;
076: private final @Nullable
077: SEIModel seiModel;
078: private final @NotNull
079: WSService rootOwner;
080: private final @NotNull
081: WSBinding binding;
082: private final @NotNull
083: Container container;
084: private @NotNull
085: Codec codec;
086:
087: public ClientTubeAssemblerContext(@NotNull
088: EndpointAddress address, @NotNull
089: WSDLPort wsdlModel, @NotNull
090: WSService rootOwner, @NotNull
091: WSBinding binding) {
092: this (address, wsdlModel, rootOwner, binding, Container.NONE);
093: }
094:
095: public ClientTubeAssemblerContext(@NotNull
096: EndpointAddress address, @NotNull
097: WSDLPort wsdlModel, @NotNull
098: WSService rootOwner, @NotNull
099: WSBinding binding, @NotNull
100: Container container) {
101: // WSBinding is actually BindingImpl
102: this (address, wsdlModel, rootOwner, binding, container,
103: ((BindingImpl) binding).createCodec());
104: }
105:
106: public ClientTubeAssemblerContext(@NotNull
107: EndpointAddress address, @NotNull
108: WSDLPort wsdlModel, @NotNull
109: WSService rootOwner, @NotNull
110: WSBinding binding, @NotNull
111: Container container, Codec codec) {
112: this (address, wsdlModel, rootOwner, binding, container, codec,
113: null);
114: }
115:
116: public ClientTubeAssemblerContext(@NotNull
117: EndpointAddress address, @NotNull
118: WSDLPort wsdlModel, @NotNull
119: WSService rootOwner, @NotNull
120: WSBinding binding, @NotNull
121: Container container, Codec codec, SEIModel seiModel) {
122: this .address = address;
123: this .wsdlModel = wsdlModel;
124: this .rootOwner = rootOwner;
125: this .binding = binding;
126: this .container = container;
127: this .codec = codec;
128: this .seiModel = seiModel;
129: }
130:
131: /**
132: * The endpoint address. Always non-null. This parameter is taken separately
133: * from {@link com.sun.xml.ws.api.model.wsdl.WSDLPort} (even though there's {@link com.sun.xml.ws.api.model.wsdl.WSDLPort#getAddress()})
134: * because sometimes WSDL is not available.
135: */
136: public @NotNull
137: EndpointAddress getAddress() {
138: return address;
139: }
140:
141: /**
142: * The created pipeline will be used to serve this port.
143: * Null if the service isn't associated with any port definition in WSDL,
144: * and otherwise non-null.
145: */
146: public @Nullable
147: WSDLPort getWsdlModel() {
148: return wsdlModel;
149: }
150:
151: /**
152: * The pipeline is created for this {@link com.sun.xml.ws.api.WSService}.
153: * Always non-null. (To be precise, the newly created pipeline
154: * is owned by a proxy or a dispatch created from thsi {@link com.sun.xml.ws.api.WSService}.)
155: */
156: public @NotNull
157: WSService getService() {
158: return rootOwner;
159: }
160:
161: /**
162: * The binding of the new pipeline to be created.
163: */
164: public @NotNull
165: WSBinding getBinding() {
166: return binding;
167: }
168:
169: /**
170: * The created pipeline will use seiModel to get java concepts for the endpoint
171: *
172: * @return Null if the service doesn't have SEI model e.g. Dispatch,
173: * and otherwise non-null.
174: */
175: public @Nullable
176: SEIModel getSEIModel() {
177: return seiModel;
178: }
179:
180: /**
181: * Returns the Container in which the client is running
182: *
183: * @return Container in which client is running
184: */
185: public Container getContainer() {
186: return container;
187: }
188:
189: /**
190: * creates a {@link Tube} that dumps messages that pass through.
191: */
192: public Tube createDumpTube(String name, PrintStream out, Tube next) {
193: return new DumpTube(name, out, next);
194: }
195:
196: /**
197: * Creates a {@link Tube} that adds container specific security
198: */
199: public @NotNull
200: Tube createSecurityTube(@NotNull
201: Tube next) {
202: ClientPipelineHook hook = container
203: .getSPI(ClientPipelineHook.class);
204: if (hook != null) {
205: ClientPipeAssemblerContext ctxt = new ClientPipeAssemblerContext(
206: address, wsdlModel, rootOwner, binding, container);
207: return PipeAdapter.adapt(hook.createSecurityPipe(ctxt,
208: PipeAdapter.adapt(next)));
209: }
210: return next;
211: }
212:
213: /**
214: * Creates a {@link Tube} that invokes protocol and logical handlers.
215: */
216: public Tube createWsaTube(Tube next) {
217: if (binding instanceof SOAPBinding
218: && AddressingVersion.isEnabled(binding)
219: && wsdlModel != null)
220: return new WsaClientTube(wsdlModel, binding, next);
221: else
222: return next;
223: }
224:
225: /**
226: * Creates a {@link Tube} that invokes protocol and logical handlers.
227: */
228: public Tube createHandlerTube(Tube next) {
229: HandlerTube cousinHandlerTube = null;
230: //XML/HTTP Binding can have only LogicalHandlerPipe
231: if (binding instanceof SOAPBinding) {
232: //Add MessageHandlerTube
233: HandlerTube messageHandlerTube = new ClientMessageHandlerTube(
234: seiModel, binding, wsdlModel, next);
235: next = cousinHandlerTube = messageHandlerTube;
236:
237: //Add SOAPHandlerTuber
238: HandlerTube soapHandlerTube = new ClientSOAPHandlerTube(
239: binding, next, cousinHandlerTube);
240: next = cousinHandlerTube = soapHandlerTube;
241: }
242: return new ClientLogicalHandlerTube(binding, next,
243: cousinHandlerTube);
244: }
245:
246: /**
247: * Creates a {@link Tube} that performs SOAP mustUnderstand processing.
248: * This pipe should be before HandlerPipes.
249: */
250: public Tube createClientMUTube(Tube next) {
251: if (binding instanceof SOAPBinding)
252: return new ClientMUTube(binding, next);
253: else
254: return next;
255: }
256:
257: /**
258: * Creates a transport pipe (for client), which becomes the terminal pipe.
259: */
260: public Tube createTransportTube() {
261: ClassLoader cl = Thread.currentThread().getContextClassLoader();
262:
263: // wsgen generates a WSDL with the address attribute that says "REPLACE_WITH_ACTUAL_URL".
264: // while it's technically correct to reject such address (since there's no transport registered
265: // with it), it's desirable to allow the user a benefit of doubt, and wait until the runtime
266: // to see if the user configures the endpoint address through request context.
267: // DeferredTransportPipe is used for this purpose.
268: //
269: // Ideally, we shouldn't have @address at all for such cases, but due to the backward
270: // compatibility and the fact that this attribute is mandatory, we have no option but
271: // to check for REPLACE_WITH_ACTUAL_URL.
272: if (address.toString().equals("")
273: || address.toString().equals("REPLACE_WITH_ACTUAL_URL"))
274: return new DeferredTransportPipe(cl, this );
275:
276: return TransportTubeFactory.create(cl, this );
277: }
278:
279: /**
280: * Gets the {@link Codec} that is set by {@link #setCodec} or the default codec
281: * based on the binding.
282: *
283: * @return codec to be used for web service requests
284: */
285: public @NotNull
286: Codec getCodec() {
287: return codec;
288: }
289:
290: /**
291: * Interception point to change {@link Codec} during {@link Tube}line assembly. The
292: * new codec will be used by jax-ws client runtime for encoding/decoding web service
293: * request/response messages. The new codec should be used by the transport tubes.
294: *
295: * <p>
296: * the codec should correctly implement {@link Codec#copy} since it is used while
297: * serving requests concurrently.
298: *
299: * @param codec codec to be used for web service requests
300: */
301: public void setCodec(@NotNull
302: Codec codec) {
303: this.codec = codec;
304: }
305:
306: }
|