001: /*
002: * Portions Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.ws.transport.local.client;
027:
028: import java.io.ByteArrayInputStream;
029: import java.io.ByteArrayOutputStream;
030: import java.io.OutputStream;
031: import com.sun.xml.internal.ws.client.ClientTransportException;
032: import com.sun.xml.internal.ws.handler.MessageContextImpl;
033: import com.sun.xml.internal.ws.server.RuntimeEndpointInfo;
034: import com.sun.xml.internal.ws.server.Tie;
035: import com.sun.xml.internal.ws.spi.runtime.WSConnection;
036: import com.sun.xml.internal.ws.spi.runtime.WebServiceContext;
037: import com.sun.xml.internal.ws.transport.WSConnectionImpl;
038: import com.sun.xml.internal.ws.util.localization.Localizable;
039: import com.sun.xml.internal.ws.util.ByteArrayBuffer;
040:
041: import java.io.InputStream;
042: import java.util.List;
043: import java.util.Map;
044: import java.util.Set;
045: import java.util.HashSet;
046: import java.net.HttpURLConnection;
047: import java.net.ProtocolException;
048:
049: import com.sun.xml.internal.ws.transport.local.server.LocalConnectionImpl;
050: import com.sun.xml.internal.ws.transport.local.LocalMessage;
051:
052: import static com.sun.xml.internal.ws.developer.JAXWSProperties.CONTENT_NEGOTIATION_PROPERTY;
053:
054: import javax.xml.ws.http.HTTPException;
055:
056: /**
057: * @author WS Development Team
058: */
059: public class LocalClientTransport extends WSConnectionImpl {
060:
061: private RuntimeEndpointInfo endpointInfo;
062: private Tie tie = new Tie();
063: LocalMessage lm = new LocalMessage();
064:
065: //this class is used primarily for debugging purposes
066: public LocalClientTransport(RuntimeEndpointInfo endpointInfo) {
067: this (endpointInfo, null);
068: }
069:
070: public LocalClientTransport(RuntimeEndpointInfo endpointInfo,
071: OutputStream logStream) {
072: this .endpointInfo = endpointInfo;
073: debugStream = logStream;
074: }
075:
076: @Override
077: public OutputStream getOutput() {
078: try {
079: lm.setOutput(new ByteArrayBuffer());
080: return lm.getOutput();
081: } catch (Exception ex) {
082: throw new ClientTransportException("local.client.failed",
083: ex);
084: }
085: }
086:
087: private static void checkMessageContentType(WSConnection con,
088: boolean response) {
089: String negotiation = System.getProperty(
090: CONTENT_NEGOTIATION_PROPERTY, "none").intern();
091: String contentType = con.getHeaders().get("Content-Type")
092: .get(0);
093:
094: // Use indexOf() to handle Multipart/related types
095: if (negotiation == "none") {
096: // OK only if XML
097: if (contentType.indexOf("text/xml") < 0
098: && contentType.indexOf("application/soap+xml") < 0
099: && contentType.indexOf("application/xop+xml") < 0) {
100: throw new RuntimeException("Invalid content type '"
101: + contentType
102: + "' with content negotiation set to '"
103: + negotiation + "'.");
104: }
105: } else if (negotiation == "optimistic") {
106: // OK only if FI
107: if (contentType.indexOf("application/fastinfoset") < 0
108: && contentType
109: .indexOf("application/soap+fastinfoset") < 0) {
110: throw new RuntimeException("Invalid content type '"
111: + contentType
112: + "' with content negotiation set to '"
113: + negotiation + "'.");
114: }
115: } else if (negotiation == "pessimistic") {
116: // OK if FI request is anything and response is FI
117: if (response
118: && contentType.indexOf("application/fastinfoset") < 0
119: && contentType
120: .indexOf("application/soap+fastinfoset") < 0) {
121: throw new RuntimeException("Invalid content type '"
122: + contentType
123: + "' with content negotiation set to '"
124: + negotiation + "'.");
125: }
126: }
127: }
128:
129: @Override
130: public void closeOutput() {
131: super .closeOutput();
132: WSConnection con = new LocalConnectionImpl(lm);
133:
134: // Copy headers for content negotiation
135: con.setHeaders(getHeaders());
136:
137: // Check request content type based on negotiation property
138: checkMessageContentType(this , false);
139:
140: try {
141: // Set a MessageContext per invocation
142: WebServiceContext wsContext = endpointInfo
143: .getWebServiceContext();
144: wsContext.setMessageContext(new MessageContextImpl());
145: tie.handle(con, endpointInfo);
146:
147: checkMessageContentType(con, true);
148: } catch (Exception ex) {
149: new ProtocolException("Server side Exception:" + ex);
150: }
151: }
152:
153: @Override
154: public InputStream getInput() {
155: try {
156: return lm.getOutput().newInputStream();
157: } catch (Exception ex) {
158: throw new ClientTransportException("local.client.failed",
159: ex);
160: }
161: }
162:
163: @Override
164: public void setHeaders(Map<String, List<String>> headers) {
165: lm.setHeaders(headers);
166: }
167:
168: @Override
169: public Map<String, List<String>> getHeaders() {
170: return lm.getHeaders();
171: }
172:
173: }
|