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: package com.sun.xml.ws.api.pipe;
037:
038: import com.sun.xml.ws.api.message.Message;
039: import com.sun.xml.ws.api.message.Packet;
040: import com.sun.xml.ws.api.pipe.helper.AbstractFilterPipeImpl;
041: import com.sun.xml.ws.api.pipe.helper.AbstractPipeImpl;
042:
043: import javax.annotation.PreDestroy;
044: import javax.xml.ws.Dispatch;
045: import javax.xml.ws.Provider;
046: import javax.xml.ws.WebServiceException;
047: import javax.xml.ws.handler.Handler;
048: import javax.xml.ws.handler.LogicalHandler;
049: import javax.xml.ws.handler.MessageContext;
050: import javax.xml.ws.handler.soap.SOAPHandler;
051:
052: /**
053: * Abstraction of the intermediate layers in the processing chain
054: * and transport.
055: *
056: * <h2>What is a {@link Pipe}?</h2>
057: * <p>
058: * Transport is a kind of pipe. It sends the {@link Packet}
059: * through, say, HTTP connection, and receives the data back into another {@link Packet}.
060: *
061: * <p>
062: * More often, a pipe is a filter. It acts on a packet,
063: * and then it passes the packet into another pipe. It can
064: * do the same on the way back.
065: *
066: * <p>
067: * For example, XWSS will be a {@link Pipe}
068: * that delegates to another {@link Pipe}, and it can wrap a {@link Packet} into
069: * another {@link Packet} to encrypt the body and add a header, for example.
070: *
071: * <p>
072: * Yet another kind of filter pipe is those that wraps {@link LogicalHandler}
073: * and {@link SOAPHandler}. These pipes are heavy-weight; they often consume
074: * a message in a packet and create a new one, and then pass it to the next pipe.
075: * For performance reason it probably makes sense to have one {@link Pipe}
076: * instance that invokes a series of {@link LogicalHandler}s, another one
077: * for {@link SOAPHandler}.
078: *
079: * <p>
080: * There would be a {@link Pipe} implementation that invokes {@link Provider}.
081: * There would be a {@link Pipe} implementation that invokes a service method
082: * on the user's code.
083: * There would be a {@link Dispatch} implementation that invokes a {@link Pipe}.
084: *
085: * <p>
086: * WS-MEX can be implemented as a {@link Pipe} that looks for
087: * {@link Message#getPayloadNamespaceURI()} and serves the request.
088: *
089: *
090: * <h2>Pipe Lifecycle</h2>
091: * {@link Pipe}line is expensive to set up, so once it's created it will be reused.
092: * A {@link Pipe}line is not reentrant; one pipeline is used to process one request/response
093: * at at time. The same pipeline instance may serve request/response for different threads,
094: * if one comes after another and they don't overlap.
095: * <p>
096: * Where a need arises to process multiple requests concurrently, a pipeline
097: * gets cloned through {@link PipeCloner}. Note that this need may happen on
098: * both server (because it quite often serves multiple requests concurrently)
099: * and client (because it needs to support asynchronous method invocations.)
100: * <p>
101: * Created pipelines (including cloned ones and the original) may be discarded and GCed
102: * at any time at the discretion of whoever owns pipelines. Pipes can, however, expect
103: * at least one copy (or original) of pipeline to live at any given time while a pipeline
104: * owner is interested in the given pipeline configuration (in more concerete terms,
105: * for example, as long as a dispatch object lives, it's going to keep at least one
106: * copy of a pipeline alive.)
107: * <p>
108: * Before a pipeline owner dies, it may invoke {@link #preDestroy()} on the last
109: * remaining pipeline. It is "may" for pipeline owners that live in the client-side
110: * of JAX-WS (such as dispatches and proxies), but it is a "must" for pipeline owners
111: * that live in the server-side of JAX-WS.
112: * <p>
113: * This last invocation gives a chance for some pipes to clean up any state/resource
114: * acquired (such as WS-RM's sequence, WS-Trust's SecurityToken), although as stated above,
115: * this is not required for clients.
116: *
117: *
118: *
119: * <h2>Pipe and State</h2>
120: * <p>
121: * The lifecycle of pipelines is designed to allow a {@link Pipe} to store various
122: * state in easily accessible fashion.
123: *
124: *
125: * <h3>Per-packet state</h3>
126: * <p>
127: * Any information that changes from a packet to packet should be
128: * stored in {@link Packet}. This includes information like
129: * transport-specific headers.
130: *
131: * <h3>Per-thread state</h3>
132: * <p>
133: * Any expensive objects that are non-reentrant can be stored in
134: * instance variables of a {@link Pipe}, since {@link #process(Packet)} is
135: * non reentrant. When a pipe is copied, new instances should be allocated
136: * so that two {@link Pipe} instances don't share thread-unsafe resources.
137: * This includes things like canonicalizers, JAXB unmarshallers, buffers,
138: * and so on.
139: *
140: * <h3>Per-proxy/per-endpoint state</h3>
141: * <p>
142: * Information that is tied to a particular proxy/dispatch can be stored
143: * in a separate object that is referenced from a pipe. When
144: * a new pipe is copied, you can simply hand out a reference to the newly
145: * created one, so that all copied pipes refer to the same instance.
146: * See the following code as an example:
147: *
148: * <pre>
149: * class PipeImpl {
150: * // this object stores per-proxy state
151: * class DataStore {
152: * int counter;
153: * }
154: *
155: * private DataStore ds;
156: *
157: * // create a fresh new pipe
158: * public PipeImpl(...) {
159: * ....
160: * ds = new DataStore();
161: * }
162: *
163: * // copy constructor
164: * private PipeImpl(PipeImpl that, PipeCloner cloner) {
165: * cloner.add(that,this);
166: * ...
167: * this.ds = that.ds;
168: * }
169: *
170: * public PipeImpl copy(PipeCloner pc) {
171: * return new PipeImpl(this,pc);
172: * }
173: * }
174: * </pre>
175: *
176: * <p>
177: * Note that access to such resource often needs to be synchronized,
178: * since multiple copies of pipelines may execute concurrently.
179: *
180: * <p>
181: * If such information is read-only,
182: * it can be stored as instance variables of a pipe,
183: * and its reference copied as pipes get copied. (The only difference between
184: * this and per-thread state is that you just won't allocate new things when
185: * pipes get copied here.)
186: *
187: *
188: * <h3>VM-wide state</h3>
189: * <p>
190: * <tt>static</tt> is always there for you to use.
191: *
192: *
193: *
194: * <h2>Pipes and Handlers</h2>
195: * <p>
196: * JAX-WS has a notion of {@link LogicalHandler} and {@link SOAPHandler}, and
197: * we intend to have one {@link Pipe} implementation that invokes all the
198: * {@link LogicalHandler}s and another {@link Pipe} implementation that invokes
199: * all the {@link SOAPHandler}s. Those implementations need to convert a {@link Message}
200: * into an appropriate format, but grouping all the handlers together eliminates
201: * the intermediate {@link Message} instanciation between such handlers.
202: * <p>
203: * This grouping also allows such implementations to follow the event notifications
204: * to handlers (i.e. {@link Handler#close(MessageContext)} method.
205: *
206: *
207: * <pre>
208: * TODO: Possible types of pipe:
209: * creator: create message from wire
210: * to SAAJ SOAP message
211: * to cached representation
212: * directly to JAXB beans
213: * transformer: transform message from one representation to another
214: * JAXB beans to encoded SOAP message
215: * StAX writing + JAXB bean to encoded SOAP message
216: * modifier: modify message
217: * add SOAP header blocks
218: * security processing
219: * header block processor:
220: * process certain SOAP header blocks
221: * outbound initiator: input from the client
222: * Manage input e.g. JAXB beans and associated with parts of the SOAP message
223: * inbound invoker: invoke the service
224: * Inkoke SEI, e.g. EJB or SEI in servlet.
225: * </pre>
226: *
227: * @see AbstractPipeImpl
228: * @see AbstractFilterPipeImpl
229: * @deprecated
230: * Use {@link Tube}.
231: */
232: public interface Pipe {
233: /**
234: * Sends a {@link Packet} and returns a response {@link Packet} to it.
235: *
236: * @throws WebServiceException
237: * On the server side, this signals an error condition where
238: * a fault reply is in order (or the exception gets eaten by
239: * the top-most transport {@link Pipe} if it's one-way.)
240: * This frees each {@link Pipe} from try/catching a
241: * {@link WebServiceException} in every layer.
242: *
243: * Note that this method is also allowed to return a {@link Packet}
244: * that has a fault as the payload.
245: *
246: * <p>
247: * On the client side, the {@link WebServiceException} thrown
248: * will be propagated all the way back to the calling client
249: * applications. (The consequence of that is that if you are
250: * a filtering {@link Pipe}, you must not catch the exception
251: * that your next {@link Pipe} threw.
252: *
253: * @throws RuntimeException
254: * Other runtime exception thrown by this method must
255: * be treated as a bug in the pipe implementation,
256: * and therefore should not be converted into a fault.
257: * (Otherwise it becomes very difficult to debug implementation
258: * problems.)
259: *
260: * <p>
261: * On the server side, this exception should be most likely
262: * just logged. On the client-side it gets propagated to the
263: * client application.
264: *
265: * <p>
266: * The consequence of this is that if a pipe calls
267: * into an user application (such as {@link SOAPHandler}
268: * or {@link LogicalHandler}), where a {@link RuntimeException}
269: * is *not* a bug in the JAX-WS implementation, it must be catched
270: * and wrapped into a {@link WebServiceException}.
271: *
272: * @param request
273: * The packet that represents a request message. Must not be null.
274: * If the packet has a non-null message, it must be a valid
275: * unconsumed {@link Message}. This message represents the
276: * SOAP message to be sent as a request.
277: * <p>
278: * The packet is also allowed to carry no message, which indicates
279: * that this is an output-only request.
280: * (that's called "solicit", right? - KK)
281: *
282: * @return
283: * The packet that represents a response message. Must not be null.
284: * If the packet has a non-null message, it must be
285: * a valid unconsumed {@link Message}. This message represents
286: * a response to the request message passed as a parameter.
287: * <p>
288: * The packet is also allowed to carry no message, which indicates
289: * that there was no response. This is used for things like
290: * one-way message and/or one-way transports.
291: */
292: Packet process(Packet request);
293:
294: /**
295: * Invoked before the last copy of the pipeline is about to be discarded,
296: * to give {@link Pipe}s a chance to clean up any resources.
297: *
298: * <p>
299: * This can be used to invoke {@link PreDestroy} lifecycle methods
300: * on user handler. The invocation of it is optional on the client side,
301: * but mandatory on the server side.
302: *
303: * <p>
304: * When multiple copies of pipelines are created, this method is called
305: * only on one of them.
306: *
307: * @throws WebServiceException
308: * If the clean up fails, {@link WebServiceException} can be thrown.
309: * This exception will be propagated to users (if this is client),
310: * or recorded (if this is server.)
311: */
312: void preDestroy();
313:
314: /**
315: * Creates an identical clone of this {@link Pipe}.
316: *
317: * <p>
318: * This method creates an identical pipeline that can be used
319: * concurrently with this pipeline. When the caller of a pipeline
320: * is multi-threaded and need concurrent use of the same pipeline,
321: * it can do so by creating copies through this method.
322: *
323: * <h3>Implementation Note</h3>
324: * <p>
325: * It is the implementation's responsibility to call
326: * {@link PipeCloner#add(Pipe,Pipe)} to register the copied pipe
327: * with the original. This is required before you start copying
328: * the other {@link Pipe} references you have, or else there's a
329: * risk of infinite recursion.
330: * <p>
331: * For most {@link Pipe} implementations that delegate to another
332: * {@link Pipe}, this method requires that you also copy the {@link Pipe}
333: * that you delegate to.
334: * <p>
335: * For limited number of {@link Pipe}s that do not maintain any
336: * thread unsafe resource, it is allowed to simply return <tt>this</tt>
337: * from this method (notice that even if you are stateless, if you
338: * got a delegating {@link Pipe} and that one isn't stateless, you
339: * still have to copy yourself.)
340: *
341: * <p>
342: * Note that this method might be invoked by one thread while another
343: * thread is executing the {@link #process(Packet)} method. See
344: * the {@link Codec#copy()} for more discussion about this.
345: *
346: * @param cloner
347: * Use this object (in particular its {@link PipeCloner#copy(Pipe)} method
348: * to clone other pipe references you have
349: * in your pipe. See {@link PipeCloner} for more discussion
350: * about why.
351: *
352: * @return
353: * always non-null {@link Pipe}.
354: * @param cloner
355: */
356: Pipe copy(PipeCloner cloner);
357: }
|