001: /*
002: * Copyright 2005-2007 Noelios Consulting.
003: *
004: * The contents of this file are subject to the terms of the Common Development
005: * and Distribution License (the "License"). You may not use this file except in
006: * compliance with the License.
007: *
008: * You can obtain a copy of the license at
009: * http://www.opensource.org/licenses/cddl1.txt See the License for the specific
010: * language governing permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL HEADER in each file and
013: * include the License file at http://www.opensource.org/licenses/cddl1.txt If
014: * applicable, add the following below this CDDL HEADER, with the fields
015: * enclosed by brackets "[]" replaced with your own identifying information:
016: * Portions Copyright [yyyy] [name of copyright owner]
017: */
018:
019: package com.noelios.restlet.ext.servlet;
020:
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.nio.channels.ReadableByteChannel;
025: import java.nio.channels.WritableByteChannel;
026: import java.util.Enumeration;
027: import java.util.Iterator;
028: import java.util.logging.Level;
029: import java.util.logging.Logger;
030:
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033:
034: import org.restlet.Server;
035: import org.restlet.data.Form;
036: import org.restlet.data.Parameter;
037: import org.restlet.data.Protocol;
038: import org.restlet.data.Response;
039: import org.restlet.data.Status;
040: import org.restlet.util.Series;
041:
042: import com.noelios.restlet.http.HttpServerCall;
043:
044: /**
045: * Call that is used by the Servlet HTTP server connector.
046: *
047: * @author Jerome Louvel (contact@noelios.com)
048: */
049: public class ServletCall extends HttpServerCall {
050: /** The HTTP Servlet request to wrap. */
051: private HttpServletRequest request;
052:
053: /** The HTTP Servlet response to wrap. */
054: private HttpServletResponse response;
055:
056: /** The request headers. */
057: private Series<Parameter> requestHeaders;
058:
059: /**
060: * Constructor.
061: *
062: * @param server
063: * The parent server.
064: * @param request
065: * The HTTP Servlet request to wrap.
066: * @param response
067: * The HTTP Servlet response to wrap.
068: */
069: public ServletCall(Server server, HttpServletRequest request,
070: HttpServletResponse response) {
071: super (server);
072: this .request = request;
073: this .response = response;
074: }
075:
076: /**
077: * Constructor.
078: *
079: * @param logger
080: * The logger.
081: * @param serverAddress
082: * The server IP address.
083: * @param serverPort
084: * The server port.
085: */
086: public ServletCall(Logger logger, String serverAddress,
087: int serverPort, HttpServletRequest request,
088: HttpServletResponse response) {
089: super (logger, serverAddress, serverPort);
090: this .request = request;
091: this .response = response;
092: }
093:
094: @Override
095: public String getClientAddress() {
096: return getRequest().getRemoteAddr();
097: }
098:
099: @Override
100: public int getClientPort() {
101: return getRequest().getRemotePort();
102: }
103:
104: /**
105: * Returns the server domain name.
106: *
107: * @return The server domain name.
108: */
109: public String getHostDomain() {
110: return getRequest().getServerName();
111: }
112:
113: /**
114: * Returns the request method.
115: *
116: * @return The request method.
117: */
118: public String getMethod() {
119: return getRequest().getMethod();
120: }
121:
122: /**
123: * Returns the server protocol.
124: *
125: * @return The server protocol.
126: */
127: public Protocol getProtocol() {
128: return Protocol.valueOf(getRequest().getScheme());
129: }
130:
131: /**
132: * Returns the HTTP Servlet request.
133: *
134: * @return The HTTP Servlet request.
135: */
136: public HttpServletRequest getRequest() {
137: return this .request;
138: }
139:
140: /**
141: * Returns the request entity channel if it exists.
142: *
143: * @return The request entity channel if it exists.
144: */
145: public ReadableByteChannel getRequestChannel() {
146: // Can't do anything
147: return null;
148: }
149:
150: /**
151: * Returns the list of request headers.
152: *
153: * @return The list of request headers.
154: */
155: @SuppressWarnings("unchecked")
156: public Series<Parameter> getRequestHeaders() {
157: if (this .requestHeaders == null) {
158: this .requestHeaders = new Form();
159:
160: // Copy the headers from the request object
161: String headerName;
162: String headerValue;
163: for (Enumeration<String> names = getRequest()
164: .getHeaderNames(); names.hasMoreElements();) {
165: headerName = (String) names.nextElement();
166: for (Enumeration<String> values = getRequest()
167: .getHeaders(headerName); values
168: .hasMoreElements();) {
169: headerValue = (String) values.nextElement();
170: this .requestHeaders.add(new Parameter(headerName,
171: headerValue));
172: }
173: }
174: }
175:
176: return this .requestHeaders;
177: }
178:
179: /**
180: * Returns the request entity stream if it exists.
181: *
182: * @return The request entity stream if it exists.
183: */
184: public InputStream getRequestStream() {
185: try {
186: return getRequest().getInputStream();
187: } catch (IOException e) {
188: return null;
189: }
190: }
191:
192: /**
193: * Returns the full request URI.
194: *
195: * @return The full request URI.
196: */
197: public String getRequestUri() {
198: String queryString = getRequest().getQueryString();
199:
200: if ((queryString == null) || (queryString.equals(""))) {
201: return getRequest().getRequestURI();
202: } else {
203: return getRequest().getRequestURI() + '?' + queryString;
204: }
205: }
206:
207: /**
208: * Returns the HTTP Servlet response.
209: *
210: * @return The HTTP Servlet response.
211: */
212: public HttpServletResponse getResponse() {
213: return this .response;
214: }
215:
216: /**
217: * Returns the response channel if it exists.
218: *
219: * @return The response channel if it exists.
220: */
221: public WritableByteChannel getResponseChannel() {
222: // Can't do anything
223: return null;
224: }
225:
226: /**
227: * Returns the response stream if it exists.
228: *
229: * @return The response stream if it exists.
230: */
231: public OutputStream getResponseStream() {
232: try {
233: return getResponse().getOutputStream();
234: } catch (IOException e) {
235: return null;
236: }
237: }
238:
239: /**
240: * Returns the response address.<br/> Corresponds to the IP address of the
241: * responding server.
242: *
243: * @return The response address.
244: */
245: public String getServerAddress() {
246: return getRequest().getLocalAddr();
247: }
248:
249: /**
250: * Returns the server port.
251: *
252: * @return The server port.
253: */
254: public int getServerPort() {
255: return getRequest().getServerPort();
256: }
257:
258: @Override
259: public String getVersion() {
260: String result = null;
261: int index = getRequest().getProtocol().indexOf('/');
262:
263: if (index != -1) {
264: result = getRequest().getProtocol().substring(index + 1);
265: }
266:
267: return result;
268: }
269:
270: /**
271: * Indicates if the request was made using a confidential mean.<br/>
272: *
273: * @return True if the request was made using a confidential mean.<br/>
274: */
275: public boolean isConfidential() {
276: return getRequest().isSecure();
277: }
278:
279: /**
280: * Sends the response back to the client. Commits the status, headers and
281: * optional entity and send them on the network.
282: *
283: * @param response
284: * The high-level response.
285: */
286: public void sendResponse(Response response) throws IOException {
287: // Add the response headers
288: Parameter header;
289: for (Iterator<Parameter> iter = getResponseHeaders().iterator(); iter
290: .hasNext();) {
291: header = iter.next();
292: getResponse()
293: .addHeader(header.getName(), header.getValue());
294: }
295:
296: // Set the status code in the response. We do this after adding the
297: // headers because when we have to rely on the 'sendError' method,
298: // the Servlet containers are expected to commit their response.
299: if (Status.isError(getStatusCode()) && (response == null)) {
300: try {
301: getResponse().sendError(getStatusCode(),
302: getReasonPhrase());
303: } catch (IOException ioe) {
304: getLogger().log(Level.WARNING,
305: "Unable to set the response error status", ioe);
306: }
307: } else {
308: // Send the response entity
309: getResponse().setStatus(getStatusCode());
310: super.sendResponse(response);
311: }
312: }
313:
314: }
|