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.transport.http;
037:
038: import com.sun.istack.NotNull;
039: import com.sun.istack.Nullable;
040: import com.sun.xml.ws.api.PropertySet;
041: import com.sun.xml.ws.api.message.Packet;
042: import com.sun.xml.ws.api.server.WebServiceContextDelegate;
043:
044: import javax.xml.ws.WebServiceContext;
045: import java.io.IOException;
046: import java.io.InputStream;
047: import java.io.OutputStream;
048: import java.net.HttpURLConnection;
049: import java.util.List;
050: import java.util.Map;
051:
052: /**
053: * The view of an HTTP exchange from the point of view of JAX-WS.
054: *
055: * <p>
056: * Different HTTP server layer uses different implementations of this class
057: * so that JAX-WS can be shielded from individuality of such layers.
058: * This is an interface implemented as an abstract class, so that
059: * future versions of the JAX-WS RI can add new methods.
060: *
061: * <p>
062: * This class extends {@link PropertySet} so that a transport can
063: * expose its properties to the appliation and pipes. (This object
064: * will be added to {@link Packet#addSatellite(PropertySet)}.)
065: *
066: * @author Jitendra Kotamraju
067: */
068: public abstract class WSHTTPConnection extends PropertySet {
069:
070: public static final int OK = 200;
071: public static final int ONEWAY = 202;
072: public static final int UNSUPPORTED_MEDIA = 415;
073: public static final int MALFORMED_XML = 400;
074: public static final int INTERNAL_ERR = 500;
075:
076: /**
077: * Overwrites all the HTTP response headers written thus far.
078: *
079: * <p>
080: * The implementation should copy the contents of the {@link Map},
081: * rather than retaining a reference. The {@link Map} passed as a
082: * parameter may change after this method is invoked.
083: *
084: * <p>
085: * This method may be called repeatedly, although in normal use
086: * case that's rare (so the implementation is encourage to take
087: * advantage of this usage pattern to improve performance, if possible.)
088: *
089: * <p>
090: * Initially, no header is set.
091: *
092: * <p>
093: * This parameter is usually exposed to {@link WebServiceContext}
094: * as {@link Packet#OUTBOUND_TRANSPORT_HEADERS}, and thus it
095: * should ignore <tt>Content-Type</tt> and <tt>Content-Length</tt> headers.
096: *
097: * @param headers
098: * See {@link HttpURLConnection#getHeaderFields()} for the format.
099: * This parameter may not be null, but since the user application
100: * code may invoke this method, a graceful error checking with
101: * an helpful error message should be provided if it's actually null.
102: * @see #setContentTypeResponseHeader(String)
103: */
104: public abstract void setResponseHeaders(@NotNull
105: Map<String, List<String>> headers);
106:
107: /**
108: * Sets the <tt>"Content-Type"</tt> header.
109: *
110: * <p>
111: * If the Content-Type header has already been set, this method will overwrite
112: * the previously set value. If not, this method adds it.
113: *
114: * <p>
115: * Note that this method and {@link #setResponseHeaders(Map<String,List<String>>)}
116: * may be invoked in any arbitrary order.
117: *
118: * @param value
119: * strings like <tt>"application/xml; charset=UTF-8"</tt> or
120: * <tt>"image/jpeg"</tt>.
121: */
122: public abstract void setContentTypeResponseHeader(@NotNull
123: String value);
124:
125: /**
126: * Sets the HTTP response code like {@link #OK}.
127: *
128: * <p>
129: * While JAX-WS processes a {@link WSHTTPConnection}, it
130: * will at least call this method once to set a valid HTTP response code.
131: * Note that this method may be invoked multiple times (from user code),
132: * so do not consider the value to be final until {@link #getOutput()}
133: * is invoked.
134: */
135:
136: public abstract void setStatus(int status);
137:
138: /**
139: * Gets the last value set by {@link #setStatus(int)}.
140: *
141: * @return
142: * if {@link #setStatus(int)} has not been invoked yet,
143: * return 0.
144: */
145: // I know this is ugly method!
146: public abstract int getStatus();
147:
148: /**
149: * Transport's underlying input stream.
150: *
151: * <p>
152: * This method will be invoked at most once by the JAX-WS RI to
153: * read the request body. If there's no request body, this method
154: * should return an empty {@link InputStream}.
155: *
156: * @return
157: * the stream from which the request body will be read.
158: */
159: public abstract @NotNull
160: InputStream getInput() throws IOException;
161:
162: /**
163: * Transport's underlying output stream
164: *
165: * <p>
166: * This method will be invoked exactly once by the JAX-WS RI
167: * to start writing the response body (unless the processing aborts abnormally.)
168: * Even if there's no response body to write, this method will
169: * still be invoked only to be closed immediately.
170: *
171: * <p>
172: * Once this method is called, the status code and response
173: * headers will never change (IOW {@link #setStatus(int)},
174: * {@link #setResponseHeaders}, and {@link #setContentTypeResponseHeader(String)}
175: * will never be invoked.
176: */
177: public abstract @NotNull
178: OutputStream getOutput() throws IOException;
179:
180: /**
181: * Returns the {@link WebServiceContextDelegate} for this connection.
182: */
183: public abstract @NotNull
184: WebServiceContextDelegate getWebServiceContextDelegate();
185:
186: /**
187: * HTTP request method, such as "GET" or "POST".
188: */
189: public abstract @NotNull
190: String getRequestMethod();
191:
192: /**
193: * HTTP request headers.
194: *
195: * @deprecated
196: * This is a potentially expensive operation.
197: * Programs that want to access HTTP headers should consider using
198: * other methods such as {@link #getRequestHeader(String)}.
199: *
200: * @return
201: * can be empty but never null.
202: */
203: public abstract @NotNull
204: Map<String, List<String>> getRequestHeaders();
205:
206: /**
207: * @return
208: * HTTP response headers.
209: */
210: public abstract Map<String, List<String>> getResponseHeaders();
211:
212: /**
213: * Gets an HTTP request header.
214: *
215: * <p>
216: * if multiple headers are present, this method returns one of them.
217: * (The implementation is free to choose which one it returns.)
218: *
219: * @return
220: * null if no header exists.
221: */
222: public abstract @Nullable
223: String getRequestHeader(@NotNull
224: String headerName);
225:
226: /**
227: * HTTP Query string, such as "foo=bar", or null if none exists.
228: */
229: public abstract @Nullable
230: String getQueryString();
231:
232: /**
233: * Requested path. A string like "/foo/bar/baz"
234: */
235: public abstract @Nullable
236: String getPathInfo();
237:
238: /**
239: * Gets the absolute URL up to the context path.
240: * @return
241: * String like "http://myhost/myapp"
242: * @since 2.1.2
243: */
244: public @NotNull
245: String getBaseAddress() {
246: throw new UnsupportedOperationException();
247: }
248:
249: /**
250: * Whether connection is HTTPS or not
251: *
252: * @return if the received request is on HTTPS, return true
253: * else false
254: */
255: public abstract boolean isSecure();
256:
257: private boolean closed;
258:
259: /**
260: * Close the connection
261: */
262: public void close() {
263: this .closed = true;
264: }
265:
266: /**
267: * Retuns whether connection is closed or not.
268: */
269: public boolean isClosed() {
270: return closed;
271: }
272:
273: /**
274: * Subclasses are expected to override
275: *
276: * @return
277: */
278: public String getProtocol() {
279: return "HTTP/1.1";
280: }
281:
282: /**
283: * Subclasses are expected to override
284: *
285: * @return
286: */
287: public void setContentLengthResponseHeader(int value) {
288: }
289:
290: }
|