1/* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.xml.internal.ws.api.server; 27 28import com.oracle.webservices.internal.api.message.PropertySet; 29import com.sun.istack.internal.NotNull; 30import com.sun.istack.internal.Nullable; 31import com.sun.xml.internal.ws.api.message.Message; 32import com.sun.xml.internal.ws.api.message.Packet; 33import com.sun.xml.internal.ws.api.pipe.Codec; 34import com.sun.xml.internal.ws.util.Pool; 35 36import java.io.IOException; 37 38 39/** 40 * Partial server side async transport implementation. It manages pooling of 41 * {@link Codec} and other details. 42 * 43 * @author Jitendra Kotamraju 44 */ 45public abstract class AbstractServerAsyncTransport<T> { 46 47 private final WSEndpoint endpoint; 48 private final CodecPool codecPool; 49 50 /** 51 * {@link WSEndpoint#setExecutor} should be called before creating the 52 * transport 53 * 54 * @param endpoint webservices requests are directed towards this endpoint 55 */ 56 public AbstractServerAsyncTransport(WSEndpoint endpoint) { 57 this.endpoint = endpoint; 58 codecPool = new CodecPool(endpoint); 59 } 60 61 /** 62 * decodes the transport data to Packet 63 * 64 * @param connection that carries the web service request 65 * @param codec for encoding/decoding {@link Message} 66 * @return decoded {@link Packet} 67 * @throws IOException if an i/o error happens while encoding/decoding 68 */ 69 protected Packet decodePacket(T connection, @NotNull Codec codec) throws IOException { 70 Packet packet = new Packet(); 71 packet.acceptableMimeTypes = getAcceptableMimeTypes(connection); 72 packet.addSatellite(getPropertySet(connection)); 73 packet.transportBackChannel = getTransportBackChannel(connection); 74 return packet; 75 } 76 77 /** 78 * Encodes the {@link Packet} to infoset and writes on the connection. 79 * 80 * @param connection that carries the web service request 81 * @param packet that needs to encoded to infoset 82 * @param codec that does the encoding of Packet 83 * @throws IOException if an i/o error happens while encoding/decoding 84 */ 85 protected abstract void encodePacket(T connection, @NotNull Packet packet, @NotNull Codec codec) throws IOException; 86 87 /** 88 * If the request has Accept header, return that value 89 * 90 * @param connection that carries the web service request 91 * @return Accept MIME types 92 */ 93 protected abstract @Nullable String getAcceptableMimeTypes(T connection); 94 95 /** 96 * {@link TransportBackChannel} used by jax-ws runtime to close the connection 97 * while the processing of the request is still continuing. In oneway HTTP case, a 98 * response code needs to be sent before invoking the endpoint. 99 * 100 * @param connection that carries the web service request 101 * @return TransportBackChannel instance using the connection 102 */ 103 protected abstract @Nullable TransportBackChannel getTransportBackChannel(T connection); 104 105 /** 106 * If there are any properties associated with the connection, those will 107 * be added to {@link Packet} 108 * 109 * @param connection that carries the web service request 110 * @return {@link PropertySet} for the connection 111 */ 112 protected abstract @NotNull PropertySet getPropertySet(T connection); 113 114 /** 115 * Return a {@link WebServiceContextDelegate} using the underlying connection. 116 * 117 * @param connection that carries the web service request 118 * @return non-null WebServiceContextDelegate instance 119 */ 120 protected abstract @NotNull WebServiceContextDelegate getWebServiceContextDelegate(T connection); 121 122 /** 123 * Reads and decodes infoset from the connection and invokes the endpoints. The 124 * response is encoded and written to the connection. The response could be 125 * written using a different thread. 126 * 127 * @param connection that carries the web service request 128 * @throws IOException if an i/o error happens while encoding/decoding 129 */ 130 protected void handle(final T connection) throws IOException { 131 final Codec codec = codecPool.take(); 132 Packet request = decodePacket(connection, codec); 133 if (!request.getMessage().isFault()) { 134 endpoint.schedule(request, new WSEndpoint.CompletionCallback() { 135 public void onCompletion(@NotNull Packet response) { 136 try { 137 encodePacket(connection, response, codec); 138 } catch(IOException ioe) { 139 ioe.printStackTrace(); 140 } 141 codecPool.recycle(codec); 142 } 143 }); 144 } 145 } 146 147 private static final class CodecPool extends Pool<Codec> { 148 WSEndpoint endpoint; 149 150 CodecPool(WSEndpoint endpoint) { 151 this. endpoint = endpoint; 152 } 153 154 protected Codec create() { 155 return endpoint.createCodec(); 156 } 157 } 158 159} 160