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.transport.tcp.server;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.xml.ws.api.message.Packet;
041: import com.sun.xml.ws.api.pipe.Codec;
042: import com.sun.xml.ws.api.server.Adapter;
043: import com.sun.xml.ws.transport.http.DeploymentDescriptorParser.AdapterFactory;
044: import com.sun.xml.ws.api.server.TransportBackChannel;
045: import com.sun.xml.ws.api.server.WSEndpoint;
046: import com.sun.xml.ws.transport.tcp.resources.MessagesMessages;
047: import com.sun.xml.ws.transport.tcp.util.ChannelContext;
048: import com.sun.xml.ws.transport.tcp.util.TCPConstants;
049: import com.sun.xml.ws.transport.tcp.util.WSTCPError;
050: import com.sun.xml.ws.transport.tcp.util.WSTCPException;
051: import java.io.IOException;
052: import java.io.InputStream;
053: import java.util.logging.Level;
054: import java.util.logging.Logger;
055:
056: /**
057: * @author Alexey Stashok
058: */
059: public class TCPAdapter extends Adapter<TCPAdapter.TCPToolkit> {
060: private static final Logger logger = Logger
061: .getLogger(com.sun.xml.ws.transport.tcp.util.TCPConstants.LoggingDomain
062: + ".server");
063:
064: final String name;
065: final String urlPattern;
066:
067: public TCPAdapter(@NotNull
068: final String name, @NotNull
069: final String urlPattern, @NotNull
070: final WSEndpoint endpoint) {
071: super (endpoint);
072: this .name = name;
073: this .urlPattern = urlPattern;
074: }
075:
076: public void handle(@NotNull
077: final ChannelContext channelContext) throws IOException,
078: WSTCPException {
079: final TCPConnectionImpl connection = new TCPConnectionImpl(
080: channelContext);
081:
082: final TCPToolkit tk = pool.take();
083: try {
084: tk.handle(connection);
085: connection.flush();
086: } finally {
087: pool.recycle(tk);
088: connection.close();
089: }
090: }
091:
092: protected TCPAdapter.TCPToolkit createToolkit() {
093: return new TCPToolkit();
094: }
095:
096: /**
097: * Returns the "/abc/def/ghi" portion if
098: * the URL pattern is "/abc/def/ghi/*".
099: */
100: public String getValidPath() {
101: if (urlPattern.endsWith("/*")) {
102: return urlPattern.substring(0, urlPattern.length() - 2);
103: } else {
104: return urlPattern;
105: }
106: }
107:
108: public static void sendErrorResponse(@NotNull
109: final ChannelContext channelContext, final WSTCPError message)
110: throws IOException, WSTCPException {
111: final TCPConnectionImpl connection = new TCPConnectionImpl(
112: channelContext);
113: connection.sendErrorMessage(message);
114: }
115:
116: public class TCPToolkit extends Adapter.Toolkit implements
117: TransportBackChannel {
118: protected TCPConnectionImpl connection;
119: private boolean isClosed;
120:
121: protected void handle(@NotNull
122: final TCPConnectionImpl con) throws IOException, WSTCPException {
123: connection = con;
124: isClosed = false;
125:
126: final InputStream in = connection.openInput();
127: final Codec codec = getCodec(connection.getChannelContext());
128:
129: String ct = connection.getContentType();
130: if (logger.isLoggable(Level.FINE)) {
131: logger.log(Level.FINE, MessagesMessages
132: .WSTCP_1090_TCP_ADAPTER_REQ_CONTENT_TYPE(ct));
133: }
134:
135: Packet packet = new Packet();
136: codec.decode(in, ct, packet);
137: if (logger.isLoggable(Level.FINE)) {
138: logger.log(Level.FINE, MessagesMessages
139: .WSTCP_1091_TCP_ADAPTER_DECODED());
140: }
141: addCustomPacketSattellites(packet);
142: packet = head.process(packet, connection, this );
143:
144: if (isClosed) {
145: return;
146: }
147:
148: ct = codec.getStaticContentType(packet).getContentType();
149: if (logger.isLoggable(Level.FINE)) {
150: logger.log(Level.FINE, MessagesMessages
151: .WSTCP_1092_TCP_ADAPTER_RPL_CONTENT_TYPE(ct));
152: }
153: if (ct == null) {
154: throw new UnsupportedOperationException(
155: MessagesMessages
156: .WSTCP_0021_TCP_ADAPTER_UNSUPPORTER_OPERATION());
157: } else {
158: connection.setContentType(ct);
159: if (packet.getMessage() == null) {
160: if (logger.isLoggable(Level.FINE)) {
161: logger.log(Level.FINE, MessagesMessages
162: .WSTCP_1093_TCP_ADAPTER_ONE_WAY());
163: }
164: connection.setStatus(TCPConstants.ONE_WAY);
165: } else {
166: codec.encode(packet, connection.openOutput());
167: }
168: }
169: }
170:
171: // Taking Codec from virtual connection's ChannelContext
172: protected @NotNull
173: Codec getCodec(@NotNull
174: final ChannelContext context) {
175: return context.getCodec();
176: }
177:
178: /**
179: * Method could be overwritten by children to add some extra Satellites to Packet
180: */
181: public void addCustomPacketSattellites(@NotNull
182: final Packet packet) {
183: }
184:
185: public void close() {
186: if (logger.isLoggable(Level.FINE)) {
187: logger.log(Level.FINE, MessagesMessages
188: .WSTCP_1094_TCP_ADAPTER_CLOSE());
189: }
190: connection.setStatus(TCPConstants.ONE_WAY);
191: isClosed = true;
192: }
193: };
194:
195: public static final AdapterFactory<TCPAdapter> FACTORY = new TCPAdapterList();
196: }
|