001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: ServletHttpPresentationRequest.java,v 1.3 2007-10-19 10:05:39 sinisa Exp $
022: */
023:
024: package com.lutris.appserver.server.httpPresentation.servlet;
025:
026: import java.io.File;
027: import java.io.IOException;
028: import java.util.Enumeration;
029: import java.util.Stack;
030: import java.util.StringTokenizer;
031:
032: import javax.servlet.http.Cookie;
033: import javax.servlet.http.HttpServletRequest;
034:
035: import com.lutris.appserver.server.httpPresentation.HttpPresentationException;
036: import com.lutris.appserver.server.httpPresentation.HttpPresentationIOException;
037: import com.lutris.appserver.server.httpPresentation.HttpPresentationInputStream;
038: import com.lutris.appserver.server.httpPresentation.HttpPresentationRequest;
039:
040: /**
041: * Servlet implementation of the object passed to Presentation objects that
042: * is used to access HTTP request data.
043: */
044: public class ServletHttpPresentationRequest implements
045: HttpPresentationRequest { //SV , DebugRequest
046:
047: /*
048: * Servlet objects.
049: */
050: private HttpServletRequest request;
051: private HttpPresentationInputStream inputStream = null; // Lazy allocation.
052: private String presentationPath;
053: private String presentationPathInfo;
054:
055: /*
056: * Indicates if sessionId is found in a request cookie
057: */
058: private boolean isRequestedSessionIdFromCookie = false;
059:
060: /*
061: * Indicates if sessionId is found in a request url
062: */
063: private boolean isRequestedSessionIdFromUrl = false;
064:
065: /**
066: * Construct an object associated with a servlet request.
067: * @param request Servlet request object that this object will front-end.
068: */
069: protected ServletHttpPresentationRequest(HttpServletRequest request) {
070: this .request = request;
071: StringBuffer presPath = new StringBuffer();
072: StringBuffer presPathInfo = new StringBuffer();
073:
074: /*
075: * Split the request URI into the presentation path and path info.
076: */
077: StringTokenizer tokens = new StringTokenizer(request
078: .getRequestURI().trim(), "/\\", false);
079:
080: while (tokens.hasMoreTokens()) {
081: String name = tokens.nextToken();
082: // A presentation object is found if a token ends with *.po or
083: // *.po; where the session id would follow the semi-colon
084: if (name.endsWith(".po")) {
085: presPath.append("/");
086: presPath.append(name);
087: break;
088: } else if (name.indexOf(".po;") != -1) {
089: presPath.append("/");
090: presPath.append(name.substring(0, name.indexOf(";")));
091: presPathInfo.append(name.substring(name.indexOf(";")));
092: break;
093: } else {
094: presPath.append("/");
095: presPath.append(name);
096: }
097: }
098: if (presPath.length() == 0) {
099: presPath.append("/");
100: }
101:
102: if (tokens.hasMoreTokens()) {
103: //presPathInfo = new StringBuffer();
104: while (tokens.hasMoreTokens()) {
105: presPathInfo.append("/");
106: presPathInfo.append(tokens.nextToken());
107: }
108: }
109: presentationPath = presPath.toString();
110: presentationPathInfo = presPathInfo.toString();
111:
112: }
113:
114: /**
115: * Returns the original HttpServletRequest.
116: */
117: public HttpServletRequest getHttpServletRequest() {
118: return this .request;
119: }
120:
121: /**
122: * Returns the size of the request entity data, or -1 if not known. Same
123: * as the CGI variable CONTENT_LENGTH.
124: */
125: public int getContentLength() throws HttpPresentationException {
126: return request.getContentLength();
127: }
128:
129: /*
130: * Returns the Internet Media Type of the request entity data, or null if
131: * not known. Same as the CGI variable CONTENT_TYPE.
132: */
133: public String getContentType() throws HttpPresentationException {
134: return request.getContentType();
135: }
136:
137: /**
138: * Returns the protocol and version of the request as a string of
139: * the form <code><protocol>/<major version>.<minor
140: * version></code>. Same as the CGI variable SERVER_PROTOCOL.
141: */
142: public String getProtocol() throws HttpPresentationException {
143: return request.getProtocol();
144: }
145:
146: /**
147: * Returns the scheme of the URL used in this request, for example
148: * "http", "https", or "ftp". Different schemes have different
149: * rules for constructing URLs, as noted in RFC 1738. The URL used
150: * to create a request may be reconstructed using this scheme, the
151: * server name and port, and additional information such as URIs.
152: */
153: public String getScheme() {
154: return request.getScheme();
155: }
156:
157: /**
158: * Returns the host name of the server that received the request.
159: * Same as the CGI variable SERVER_NAME.
160: */
161: public String getServerName() {
162: return request.getServerName();
163: }
164:
165: /**
166: * Returns the port number on which this request was received.
167: * Same as the CGI variable SERVER_PORT.
168: */
169: public int getServerPort() {
170: return request.getServerPort();
171: }
172:
173: /**
174: * Returns the IP address of the agent that sent the request. Same as the
175: * CGI variable REMOTE_ADDR.
176: */
177: public String getRemoteAddr() throws HttpPresentationException {
178: return request.getRemoteAddr();
179: }
180:
181: /**
182: * Returns the fully qualified host name of the agent that sent the
183: * request. Same as the CGI variable REMOTE_HOST.
184: */
185: public String getRemoteHost() throws HttpPresentationException {
186: return request.getRemoteHost();
187: }
188:
189: /**
190: * Applies alias rules to the specified virtual path and returns the
191: * corresponding real path, or null if the translation can not be
192: * performed for any reason. This resolves the path using the virtual
193: * docroot, if virtual hosting is enabled, and with the default docroot
194: * otherwise. Calling this method with the string "/" as an argument
195: * returns the document root.
196: *
197: * @param path the virtual path to be translated to a real path
198: */
199: /*
200: public String getRealPath(String path) throws HttpPresentationException {
201: return request.getRealPath(path);
202: }
203: */
204:
205: /**
206: * Returns an input stream for reading the request body.
207: */
208: public HttpPresentationInputStream getInputStream()
209: throws HttpPresentationException {
210: if (inputStream == null) {
211: try {
212: inputStream = new ServletHttpPresentationInputStream(
213: request.getInputStream());
214: } catch (IOException except) {
215: // Want to throw a HttpPresentationIOException to record the fact that
216: // the client disconnected, but want to maintain the HttpPresentationException
217: // API.
218: throw new HttpPresentationException(
219: new HttpPresentationIOException(except));
220: }
221: }
222: return inputStream;
223: }
224:
225: /**
226: * Returns a string containing the lone value of the specified query
227: * parameter, or null if the parameter does not exist. Presentation
228: * writers should use this method only when they are sure that there is
229: * only one value for the parameter. If the parameter has (or could have)
230: * multiple values, then use getParameterValues. If a multiple valued
231: * parameter name is passed as an argument, the return value is
232: * implementation dependent.
233: *
234: * @param name the name of the parameter whose value is required.
235: * @see HttpPresentationRequest#getParameterValues
236: */
237: public String getParameter(String name)
238: throws HttpPresentationException {
239: return request.getParameter(name);
240: }
241:
242: /**
243: * Returns the values of the specified query parameter for the request as
244: * an array of strings, or a 0 length array if the named parameter does
245: * not exist.
246: *
247: * @param name the name of the parameter whose value is required.
248: */
249: public String[] getParameterValues(String name)
250: throws HttpPresentationException {
251: Object values = request.getParameterValues(name);
252: if (values == null) {
253: return new String[0];
254: }/* Alex
255: if (values instanceof String) {
256: String[] valArray = new String[1];
257: valArray[0] = (String)values;
258: return valArray;
259: }*/
260: return (String[]) values;
261: }
262:
263: /**
264: * Returns the parameter names for this request as an enumeration
265: * of strings, or an empty enumeration if there are no parameters.
266: */
267: public Enumeration getParameterNames()
268: throws HttpPresentationException {
269: return request.getParameterNames();
270: }
271:
272: /**
273: * Returns the method with which the request was made. The returned
274: * value can be "GET", "HEAD", "POST", or an extension method. Same
275: * as the CGI variable REQUEST_METHOD.
276: */
277: public String getMethod() throws HttpPresentationException {
278: return request.getMethod();
279: }
280:
281: /**
282: * Returns the request URI.
283: */
284: public String getRequestURI() throws HttpPresentationException {
285: return request.getRequestURI();
286: }
287:
288: /**
289: * Returns the presentation URI.
290: */
291: public String getPresentationURI() throws HttpPresentationException {
292: return request.getRequestURI();
293: }
294:
295: /**
296: * Returns the part of the request URI that refers to the application
297: * object being invoked. Analogous to the CGI variable SCRIPT_NAME.
298: *
299: * @deprecated This method was named in a confusing manner; it
300: * returns the application, not presentation object path. Use
301: * <A HREF="getApplicationPath.html">getApplicationPath()</A>.
302: */
303: public String getPresentationPath()
304: throws HttpPresentationException {
305: //return request.getServletPath();
306: return request.getContextPath();
307: }
308:
309: /**
310: * Returns the part of the request URI that refers to the presentation
311: * object being invoked.
312: */
313: public String getPresentationObjectPath()
314: throws HttpPresentationException {
315: return presentationPath;
316: }
317:
318: /**
319: * Returns the part of the request URI after the presentation
320: * manager servlet, upto and including the presentation object .po,
321: * but not any path info.
322: *
323: * Includes bug fix submitted by Ben Warren
324: */
325: public String getPresentationObjectRelativePath()
326: throws HttpPresentationException {
327: String reqPathInfo = request.getPathInfo();
328: String poPathInfo = getPathInfo();
329:
330: // Return the relative path less path information.
331: if (poPathInfo == null) {
332: return "/";
333: }
334: if (poPathInfo.endsWith("/")) {
335: poPathInfo = poPathInfo.substring(0,
336: poPathInfo.length() - 1);
337: }
338: if (reqPathInfo == null) {
339: return poPathInfo;
340: }
341: if (!reqPathInfo.startsWith("/")) {
342: reqPathInfo = "/" + reqPathInfo;
343: }
344: if (reqPathInfo.endsWith("/")) {
345: reqPathInfo = reqPathInfo.substring(0,
346: reqPathInfo.length() - 1);
347: }
348:
349: int pos;
350:
351: //If the semicolon is the last char leave it. It is not
352: //followed by a session ID.
353: if ((pos = reqPathInfo.indexOf(';')) < 0
354: || reqPathInfo.endsWith(";")) { //FIX
355: return reqPathInfo;
356: } else {
357: return reqPathInfo.substring(0, pos);
358: }
359: }
360:
361: /**
362: * Returns the part of the request URI that refers to the application.
363: * Analogous to the CGI variable SCRIPT_NAME.
364: */
365: public String getApplicationPath() throws HttpPresentationException {
366: String contextPath = request.getContextPath();
367: //patch 25.06.2002.
368: String servletPath = request.getServletPath();
369: if (contextPath == null) {
370: contextPath = "/";
371: }
372: // else if (!contextPath.endsWith("/")) {
373: else if (!contextPath.endsWith("/")
374: && !servletPath.startsWith("/")) {
375: contextPath += "/";
376: }
377: // return contextPath + request.getServletPath();
378: return contextPath + servletPath;
379:
380: }
381:
382: /**
383: * Returns optional extra path information following the presentation
384: * path, but immediately preceding the query string. Returns null if
385: * not specified. Same as the CGI variable PATH_INFO.
386: */
387: public String getPathInfo() throws HttpPresentationException {
388: if (presentationPathInfo == null) {
389: return null;
390: } else {
391: return presentationPathInfo;
392: }
393: }
394:
395: /**
396: * Returns extra path information translated to a real path. Returns
397: * null if no extra path information specified. Same as the CGI variable
398: * PATH_TRANSLATED.
399: */
400: public String getPathTranslated() throws HttpPresentationException {
401: return request.getPathTranslated();
402: }
403:
404: /**
405: * Returns the query string part of the presentation URI, or null if none.
406: * Same as the CGI variable QUERY_STRING.
407: */
408: public String getQueryString() throws HttpPresentationException {
409: return request.getQueryString();
410: }
411:
412: /**
413: * Returns the name of the user making this request, or null if not
414: * known. The user name is set with HTTP authentication. Whether
415: * the user name will continue to be sent with each subsequent
416: * communication is browser-dependent. Same as the CGI variable
417: * REMOTE_USER.
418: */
419: public String getRemoteUser() throws HttpPresentationException {
420: return request.getRemoteUser();
421: }
422:
423: /**
424: * Returns the authentication scheme of the request, or null if none.
425: * Same as the CGI variable AUTH_TYPE.
426: */
427: public String getAuthType() throws HttpPresentationException {
428: return request.getAuthType();
429: }
430:
431: /**
432: * Gets the array of cookies found in this request.
433: *
434: * @return The array of cookies found in this request.
435: */
436: public Cookie[] getCookies() throws HttpPresentationException {
437: return request.getCookies();
438: }
439:
440: /*
441: * set the flag indicating whether the sessionId came from a cookie
442: *@param isFromCookie boolean indicating whether sessionId came from cookie
443: */
444: public void setRequestedSessionIdFromCookie(boolean isFromCookie)
445: throws HttpPresentationException {
446: isRequestedSessionIdFromCookie = isFromCookie;
447: }
448:
449: /**
450: * Indicates whether client submitted their session id through a cookie
451: * @return true if client submitted their sessionId via a cookie,
452: * false otherwise
453: */
454: public boolean isRequestedSessionIdFromCookie()
455: throws HttpPresentationException {
456: return isRequestedSessionIdFromCookie;
457: }
458:
459: /*
460: * set the flag indicating whether the sessionId came from a url
461: * @param isFromUrl boolean indicating whether sessionId came from url
462: */
463: public void setRequestedSessionIdFromUrl(boolean isFromUrl)
464: throws HttpPresentationException {
465: isRequestedSessionIdFromUrl = isFromUrl;
466: }
467:
468: /**
469: * Indicates whether client submitted their sessionId through a
470: * rewritten url
471: * @return true if client submitted their sessionId via a rewritten url
472: */
473: public boolean isRequestedSessionIdFromUrl()
474: throws HttpPresentationException {
475: return isRequestedSessionIdFromUrl;
476: }
477:
478: /**
479: * Returns the value of a header field, or null if not known.
480: * The case of the header field name is ignored.
481: * @param name the case-insensitive header field name
482: */
483: public String getHeader(String name)
484: throws HttpPresentationException {
485: return request.getHeader(name);
486: }
487:
488: /**
489: * Returns the value of an integer header field, or -1 if not found.
490: * The case of the header field name is ignored.
491: * @param name the case-insensitive header field name
492: */
493: public int getIntHeader(String name)
494: throws HttpPresentationException {
495: return request.getIntHeader(name);
496: }
497:
498: /**
499: * Returns the value of a date header field, or -1 if not found.
500: * The case of the header field name is ignored.
501: * @param name the case-insensitive header field name
502: */
503: public long getDateHeader(String name)
504: throws HttpPresentationException {
505: return request.getDateHeader(name);
506: }
507:
508: /**
509: * Returns an enumeration of strings representing the header names
510: * for this request. Some server implementations do not allow headers
511: * to be accessed in this way, in which case this method will return null.
512: */
513: public Enumeration getHeaderNames()
514: throws HttpPresentationException {
515: return request.getHeaderNames();
516: }
517:
518: /**
519: * Get the URI path for a file in the application. This converts a path
520: * to the file part of the URL. It adds in the reference to application
521: * servlet.
522: *
523: * @param file File with in the application. Currently this must
524: * be a path relative to the presentation prefix.
525: * @return The file path portion of the URL, starting with
526: * a <CODE>/</CODE>.
527: */
528: public String getAppFileURIPath(String file)
529: throws HttpPresentationException {
530:
531: StringBuffer uriPath;
532: String presPath = getApplicationPath();
533:
534: if (presPath.charAt(presPath.length() - 1) == '/') {
535: uriPath = new StringBuffer(presPath.substring(0, presPath
536: .length() - 1));
537: } else {
538: uriPath = new StringBuffer(presPath);
539: }
540:
541: // Convert system dependent file path into a URL file path.
542: Stack names = new Stack();
543: File fparse = new File(file);
544: String parent;
545: while ((parent = fparse.getParent()) != null) {
546: names.push(fparse.getName());
547: fparse = new File(parent);
548: }
549: names.push(fparse.getName());
550:
551: while (!names.empty()) {
552: uriPath.append('/');
553: uriPath.append((String) names.pop());
554: }
555: return uriPath.toString();
556: }
557:
558: /**
559: * Returns the total number of bytes processed as part of this request.
560: * This is not supported for Jolt Presentations and is necessary
561: * to support the DebugRequest interface.
562: *
563: * @see com.lutris.http.debug.DebugRequest
564: */
565: public int getTotalBytes() {
566: // FIX: When we have our own servlet implementation, we can
567: // FIX: support this.
568: return -1;
569: }
570:
571: /**
572: * Returns the part of the request URI that refers to the presentation
573: * object being invoked. This is the same as getPresentationPath(),
574: * but is necessary to support the DebugRequest interface.
575: *
576: * @see com.lutris.http.debug.DebugRequest
577: */
578: public String getPath() throws HttpPresentationException {
579: return getPresentationPath();
580: }
581: }
|