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.WsaServerTube;
042: import com.sun.xml.ws.api.addressing.AddressingVersion;
043: import com.sun.xml.ws.api.model.SEIModel;
044: import com.sun.xml.ws.api.model.wsdl.WSDLPort;
045: import com.sun.xml.ws.api.pipe.helper.PipeAdapter;
046: import com.sun.xml.ws.api.server.ServerPipelineHook;
047: import com.sun.xml.ws.api.server.WSEndpoint;
048: import com.sun.xml.ws.binding.BindingImpl;
049: import com.sun.xml.ws.handler.HandlerTube;
050: import com.sun.xml.ws.handler.ServerLogicalHandlerTube;
051: import com.sun.xml.ws.handler.ServerMessageHandlerTube;
052: import com.sun.xml.ws.handler.ServerSOAPHandlerTube;
053: import com.sun.xml.ws.protocol.soap.ServerMUTube;
054: import com.sun.xml.ws.util.pipe.DumpTube;
055:
056: import javax.xml.ws.soap.SOAPBinding;
057: import java.io.PrintStream;
058:
059: /**
060: * Factory for well-known server {@link Tube} implementations
061: * that the {@link TubelineAssembler} needs to use
062: * to satisfy JAX-WS requirements.
063: *
064: * @author Jitendra Kotamraju
065: */
066: public class ServerTubeAssemblerContext {
067:
068: private final SEIModel seiModel;
069: private final WSDLPort wsdlModel;
070: private final WSEndpoint endpoint;
071: private final BindingImpl binding;
072: private final Tube terminal;
073: private final boolean isSynchronous;
074: private @NotNull
075: Codec codec;
076:
077: public ServerTubeAssemblerContext(@Nullable
078: SEIModel seiModel, @Nullable
079: WSDLPort wsdlModel, @NotNull
080: WSEndpoint endpoint, @NotNull
081: Tube terminal, boolean isSynchronous) {
082: this .seiModel = seiModel;
083: this .wsdlModel = wsdlModel;
084: this .endpoint = endpoint;
085: this .terminal = terminal;
086: // WSBinding is actually BindingImpl
087: this .binding = (BindingImpl) endpoint.getBinding();
088: this .isSynchronous = isSynchronous;
089: this .codec = this .binding.createCodec();
090: }
091:
092: /**
093: * The created pipeline will use seiModel to get java concepts for the endpoint
094: *
095: * @return Null if the service doesn't have SEI model e.g. Provider endpoints,
096: * and otherwise non-null.
097: */
098: public @Nullable
099: SEIModel getSEIModel() {
100: return seiModel;
101: }
102:
103: /**
104: * The created pipeline will be used to serve this port.
105: *
106: * @return Null if the service isn't associated with any port definition in WSDL,
107: * and otherwise non-null.
108: */
109: public @Nullable
110: WSDLPort getWsdlModel() {
111: return wsdlModel;
112: }
113:
114: /**
115: *
116: * The created pipeline is used to serve this {@link com.sun.xml.ws.api.server.WSEndpoint}.
117: * Specifically, its {@link com.sun.xml.ws.api.WSBinding} should be of interest to many
118: * {@link com.sun.xml.ws.api.pipe.Pipe}s.
119: * @return Always non-null.
120: */
121: public @NotNull
122: WSEndpoint getEndpoint() {
123: return endpoint;
124: }
125:
126: /**
127: * The last {@link com.sun.xml.ws.api.pipe.Pipe} in the pipeline. The assembler is expected to put
128: * additional {@link com.sun.xml.ws.api.pipe.Pipe}s in front of it.
129: *
130: * <p>
131: * (Just to give you the idea how this is used, normally the terminal pipe
132: * is the one that invokes the user application or {@link javax.xml.ws.Provider}.)
133: *
134: * @return always non-null terminal pipe
135: */
136: public @NotNull
137: Tube getTerminalTube() {
138: return terminal;
139: }
140:
141: /**
142: * If this server pipeline is known to be used for serving synchronous transport,
143: * then this method returns true. This can be potentially use as an optimization
144: * hint, since often synchronous versions are cheaper to execute than asycnhronous
145: * versions.
146: */
147: public boolean isSynchronous() {
148: return isSynchronous;
149: }
150:
151: /**
152: * Creates a {@link Tube} that performs SOAP mustUnderstand processing.
153: * This pipe should be before HandlerPipes.
154: */
155: public @NotNull
156: Tube createServerMUTube(@NotNull
157: Tube next) {
158: if (binding instanceof SOAPBinding)
159: return new ServerMUTube(binding, next);
160: else
161: return next;
162: }
163:
164: /**
165: * Creates a {@link Tube} that invokes protocol and logical handlers.
166: */
167: public @NotNull
168: Tube createHandlerTube(@NotNull
169: Tube next) {
170: if (!binding.getHandlerChain().isEmpty()) {
171: HandlerTube cousin = new ServerLogicalHandlerTube(binding,
172: wsdlModel, next);
173: next = cousin;
174: if (binding instanceof SOAPBinding) {
175: //Add SOAPHandlerTube
176: next = cousin = new ServerSOAPHandlerTube(binding,
177: next, cousin);
178:
179: //Add MessageHandlerTube
180: next = new ServerMessageHandlerTube(seiModel, binding,
181: next, cousin);
182: }
183: }
184: return next;
185: }
186:
187: /**
188: * Creates a {@link Tube} that does the monitoring of the invocation for a
189: * container
190: */
191: public @NotNull
192: Tube createMonitoringTube(@NotNull
193: Tube next) {
194: ServerPipelineHook hook = endpoint.getContainer().getSPI(
195: ServerPipelineHook.class);
196: if (hook != null) {
197: ServerPipeAssemblerContext ctxt = new ServerPipeAssemblerContext(
198: seiModel, wsdlModel, endpoint, terminal,
199: isSynchronous);
200: return PipeAdapter.adapt(hook.createMonitoringPipe(ctxt,
201: PipeAdapter.adapt(next)));
202: }
203: return next;
204: }
205:
206: /**
207: * Creates a {@link Tube} that adds container specific security
208: */
209: public @NotNull
210: Tube createSecurityTube(@NotNull
211: Tube next) {
212: ServerPipelineHook hook = endpoint.getContainer().getSPI(
213: ServerPipelineHook.class);
214: if (hook != null) {
215: ServerPipeAssemblerContext ctxt = new ServerPipeAssemblerContext(
216: seiModel, wsdlModel, endpoint, terminal,
217: isSynchronous);
218: return PipeAdapter.adapt(hook.createSecurityPipe(ctxt,
219: PipeAdapter.adapt(next)));
220: }
221: return next;
222: }
223:
224: /**
225: * creates a {@link Tube} that dumps messages that pass through.
226: */
227: public Tube createDumpTube(String name, PrintStream out, Tube next) {
228: return new DumpTube(name, out, next);
229: }
230:
231: /**
232: * Creates WS-Addressing pipe
233: */
234: public Tube createWsaTube(Tube next) {
235: if (binding instanceof SOAPBinding
236: && AddressingVersion.isEnabled(binding)
237: && wsdlModel != null)
238: return new WsaServerTube(endpoint, wsdlModel, binding, next);
239: else
240: return next;
241: }
242:
243: /**
244: * Gets the {@link Codec} that is set by {@link #setCodec} or the default codec
245: * based on the binding. The codec is a full codec that is responsible for
246: * encoding/decoding entire protocol message(for e.g: it is responsible to
247: * encode/decode entire MIME messages in SOAP binding)
248: *
249: * @return codec to be used for web service requests
250: * @see {@link Codecs}
251: */
252: public @NotNull
253: Codec getCodec() {
254: return codec;
255: }
256:
257: /**
258: * Interception point to change {@link Codec} during {@link Tube}line assembly. The
259: * new codec will be used by jax-ws server runtime for encoding/decoding web service
260: * request/response messages. {@link WSEndpoint#createCodec()} will return a copy
261: * of this new codec and will be used in the server runtime.
262: *
263: * <p>
264: * The codec is a full codec that is responsible for
265: * encoding/decoding entire protocol message(for e.g: it is responsible to
266: * encode/decode entire MIME messages in SOAP binding)
267: *
268: * <p>
269: * the codec should correctly implement {@link Codec#copy} since it is used while
270: * serving requests concurrently.
271: *
272: * @param codec codec to be used for web service requests
273: * @see {@link Codecs}
274: */
275: public void setCodec(@NotNull
276: Codec codec) {
277: this.codec = codec;
278: }
279:
280: }
|