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.server;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.istack.Nullable;
041: import com.sun.xml.ws.api.PropertySet;
042: import com.sun.xml.ws.api.message.Message;
043: import com.sun.xml.ws.api.message.Packet;
044: import com.sun.xml.ws.api.pipe.Codec;
045: import com.sun.xml.ws.api.pipe.Fiber;
046: import com.sun.xml.ws.util.Pool;
047:
048: import java.io.IOException;
049:
050: /**
051: * Partial server side async transport implementation. It manages pooling of
052: * {@link Codec} and other details.
053: *
054: * @author Jitendra Kotamraju
055: */
056: public abstract class AbstractServerAsyncTransport<T> {
057:
058: private final WSEndpoint endpoint;
059: private final CodecPool codecPool;
060:
061: /**
062: * {@link WSEndpoint#setExecutor} should be called before creating the
063: * transport
064: *
065: * @param endpoint webservices requests are directed towards this endpoint
066: */
067: public AbstractServerAsyncTransport(WSEndpoint endpoint) {
068: this .endpoint = endpoint;
069: codecPool = new CodecPool(endpoint);
070: }
071:
072: /**
073: * decodes the transport data to Packet
074: *
075: * @param connection that carries the web service request
076: * @param codec for encoding/decoding {@link Message}
077: * @return decoded {@link Packet}
078: * @throws IOException if an i/o error happens while encoding/decoding
079: */
080: protected Packet decodePacket(T connection, @NotNull
081: Codec codec) throws IOException {
082: Packet packet = new Packet();
083: packet.acceptableMimeTypes = getAcceptableMimeTypes(connection);
084: packet.addSatellite(getPropertySet(connection));
085: packet.transportBackChannel = getTransportBackChannel(connection);
086: return packet;
087: }
088:
089: /**
090: * Encodes the {@link Packet} to infoset and writes on the connection.
091: *
092: * @param connection that carries the web service request
093: * @param packet that needs to encoded to infoset
094: * @param codec that does the encoding of Packet
095: * @throws IOException if an i/o error happens while encoding/decoding
096: */
097: protected abstract void encodePacket(T connection, @NotNull
098: Packet packet, @NotNull
099: Codec codec) throws IOException;
100:
101: /**
102: * If the request has Accept header, return that value
103: *
104: * @param connection that carries the web service request
105: * @return Accept MIME types
106: */
107: protected abstract @Nullable
108: String getAcceptableMimeTypes(T connection);
109:
110: /**
111: * {@link TransportBackChannel} used by jax-ws runtime to close the connection
112: * while the processing of the request is still continuing. In oneway HTTP case, a
113: * response code needs to be sent before invoking the endpoint.
114: *
115: * @param connection that carries the web service request
116: * @return TransportBackChannel instance using the connection
117: */
118: protected abstract @Nullable
119: TransportBackChannel getTransportBackChannel(T connection);
120:
121: /**
122: * If there are any properties associated with the connection, those will
123: * be added to {@link Packet}
124: *
125: * @param connection that carries the web service request
126: * @return {@link PropertySet} for the connection
127: */
128: protected abstract @NotNull
129: PropertySet getPropertySet(T connection);
130:
131: /**
132: * Return a {@link WebServiceContextDelegate} using the underlying connection.
133: *
134: * @param connection that carries the web service request
135: * @return non-null WebServiceContextDelegate instance
136: */
137: protected abstract @NotNull
138: WebServiceContextDelegate getWebServiceContextDelegate(T connection);
139:
140: /**
141: * Reads and decodes infoset from the connection and invokes the endpoints. The
142: * response is encoded and written to the connection. The response could be
143: * written using a different thread.
144: *
145: * @param connection that carries the web service request
146: * @throws IOException if an i/o error happens while encoding/decoding
147: */
148: protected void handle(final T connection) throws IOException {
149: final Codec codec = codecPool.take();
150: Packet request = decodePacket(connection, codec);
151: if (!request.getMessage().isFault()) {
152: endpoint.schedule(request,
153: new WSEndpoint.CompletionCallback() {
154: public void onCompletion(@NotNull
155: Packet response) {
156: try {
157: encodePacket(connection, response,
158: codec);
159: } catch (IOException ioe) {
160: ioe.printStackTrace();
161: }
162: codecPool.recycle(codec);
163: }
164: });
165: }
166: }
167:
168: private static final class CodecPool extends Pool<Codec> {
169: WSEndpoint endpoint;
170:
171: CodecPool(WSEndpoint endpoint) {
172: this .endpoint = endpoint;
173: }
174:
175: protected Codec create() {
176: return endpoint.createCodec();
177: }
178: }
179:
180: }
|