Annotation of java/classes/org/w3c/jigsaw/servlet/JigsawHttpServletRequest.java, revision 1.49
1.1 abaird 1: // JigsawHttpServletRequest.java
1.49 ! bmahe 2: // $Id: JigsawHttpServletRequest.java,v 1.48 2000/02/11 16:21:45 bmahe Exp $
1.1 abaird 3: // (c) COPYRIGHT MIT and INRIA, 1996.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5:
1.16 bmahe 6: package org.w3c.jigsaw.servlet;
1.1 abaird 7:
8: import java.io.*;
9: import java.util.*;
1.47 bmahe 10: import java.security.Principal;
1.1 abaird 11:
1.8 bmahe 12: import javax.servlet.*;
13: import javax.servlet.http.*;
1.1 abaird 14:
1.16 bmahe 15: import org.w3c.util.*;
16: import org.w3c.jigsaw.http.*;
17: import org.w3c.jigsaw.forms.URLDecoder;
18: import org.w3c.jigsaw.forms.URLDecoderException;
1.46 bmahe 19: import org.w3c.jigsaw.resources.VirtualHostResource;
1.16 bmahe 20: import org.w3c.www.http.*;
21: import org.w3c.www.mime.*;
22: import org.w3c.jigsaw.auth.AuthFilter; // for auth infos access
1.2 abaird 23:
1.16 bmahe 24: import org.w3c.tools.resources.*;
1.14 bmahe 25:
1.6 abaird 26: class HeaderNames implements Enumeration {
1.18 bmahe 27: // The HeaderDescription enumeration
28: Enumeration e = null;
1.6 abaird 29:
1.18 bmahe 30: public boolean hasMoreElements() {
31: return e.hasMoreElements();
32: }
33:
34: public Object nextElement() {
35: HeaderDescription d = (HeaderDescription) e.nextElement();
36: return d.getName();
37: }
38:
39: HeaderNames(Enumeration e) {
40: this.e = e ;
41: }
1.6 abaird 42:
43: }
44:
1.2 abaird 45: /**
46: * @author Alexandre Rafalovitch <alex@access.com.au>
47: * @author Anselm Baird-Smith <abaird@w3.org>
1.12 bmahe 48: * @author Benoit Mahe <bmahe@sophia.inria.fr>
1.2 abaird 49: */
1.1 abaird 50:
51: public class JigsawHttpServletRequest implements HttpServletRequest {
1.9 bmahe 52:
1.25 bmahe 53: /**
54: * The InputStream state codes.
55: */
56:
57: /**
58: * The initial state of the request InputStream
59: */
1.18 bmahe 60: private final static int STREAM_STATE_INITIAL = 0;
1.25 bmahe 61:
62: /**
63: * One reader has been created and is probably used.
64: */
1.18 bmahe 65: private final static int STREAM_READER_USED = 1;
1.25 bmahe 66:
67: /**
68: * The input stream is used
69: */
1.18 bmahe 70: private final static int INPUT_STREAM_USED = 2;
71:
1.25 bmahe 72: /**
73: * The inputstream state
74: */
1.18 bmahe 75: private int stream_state = STREAM_STATE_INITIAL;
76:
77: public final static
78: String STATE_PARAMETERS = "org.w3c.jigsaw.servlet.stateParam";
79:
80: private static MimeType type = MimeType.APPLICATION_X_WWW_FORM_URLENCODED ;
81: /**
82: * The initial request.
83: */
84: private Request request = null;
85: /**
86: * The attached servlet.
87: */
88: private Servlet servlet = null;
89: /**
90: * The lazyly computed queryParameters hashtable.
91: */
92: private Hashtable queryParameters = null;
93:
1.25 bmahe 94: protected JigsawHttpServletResponse response = null;
95:
96: protected JigsawHttpSession httpSession = null;
97:
1.29 bmahe 98: protected JigsawHttpSessionContext sessionContext = null;
1.25 bmahe 99:
100: protected String requestedSessionID = null;
101:
1.45 bmahe 102: private Hashtable mergeParameters(Hashtable source, Hashtable dest) {
103: if (source == null)
104: return dest;
105: if (dest != null) {
106: Enumeration e = source.keys();
107: while (e.hasMoreElements()) {
108: String name = (String)e.nextElement();
109: Object value = dest.get(name);
110: if (value == null)
111: dest.put(name, source.get(name));
112: else if (value instanceof String[]) {
113: String oldValues [] = (String[])value;
114: String newValues [] = new String[oldValues.length+1];
115: System.arraycopy(oldValues,0,newValues,0,
116: oldValues.length);
117: newValues[oldValues.length] = (String)source.get(name);
118: dest.put(name,newValues);
119: } else {
120: String newValues [] = new String[2];
121: newValues[0] = (String)source.get(name);
122: newValues[1] = (String)value;
123: dest.put(name,newValues);
124: }
125: }
126: return dest;
127: } else {
128: return source;
129: }
130: }
131:
132: private synchronized void prepareQueryParameters() {
1.18 bmahe 133: if( queryParameters != null )
134: return;
1.45 bmahe 135: Hashtable postParameters = null;
1.18 bmahe 136: // What kinf of parameters are we expecting ?
137: if ( request.getMethod().equals("POST") ) {
1.45 bmahe 138: postParameters = new Hashtable(2);
1.18 bmahe 139: // POSTed parameters, check content type:
140: if ((! request.hasContentType())
141: || (type.match(request.getContentType()) < 0) )
142: return;
143: // Get and decode the request entity:
144: URLDecoder dec = null;
145: try {
146: InputStream in = request.getInputStream() ;
147: // Notify the client that we are willing to continue
148: Client client = request.getClient();
149: if ( client != null )
150: client.sendContinue();
151: dec = new URLDecoder (in, false);
1.45 bmahe 152: postParameters = dec.parse () ;
1.18 bmahe 153: } catch (URLDecoderException e) {
1.45 bmahe 154: postParameters = null;
1.18 bmahe 155: } catch (IOException ex) {
1.45 bmahe 156: postParameters = null;
1.18 bmahe 157: }
1.45 bmahe 158: }
159: // URL encoded parameters:
160: String query = request.getQueryString();
161: if (query != null) {
162: Reader qis = new StringReader(query);
163: try {
164: queryParameters = new URLDecoder(qis, false).parse();
165: } catch (Exception ex) {
166: throw new RuntimeException("Java implementation bug.");
1.18 bmahe 167: }
168: }
1.45 bmahe 169: queryParameters = mergeParameters(postParameters, queryParameters);
1.18 bmahe 170: // state parameters
171: Hashtable param = (Hashtable)request.getState(STATE_PARAMETERS);
1.45 bmahe 172: queryParameters = mergeParameters(param, queryParameters);
1.18 bmahe 173: }
174:
1.31 bmahe 175: protected String getURLParameter(String name) {
176: Hashtable urlParameters = null;
177: String query = request.getQueryString();
178: if (query != null) {
1.42 bmahe 179: Reader qis = new StringReader(query);
1.31 bmahe 180: try {
181: urlParameters = new URLDecoder(qis, false).parse();
182: return (String) urlParameters.get(name);
183: } catch (Exception ex) {
184: throw new RuntimeException("Java implementation bug.");
185: }
186: }
187: return null;
188: }
1.18 bmahe 189:
190: /**
191: * Return the Charset parameter of content type
192: * @return A String instance
193: */
194: public String getCharacterEncoding() {
195: org.w3c.www.mime.MimeType type = request.getContentType();
196: if ((type != null) && (type.hasParameter("charset"))) {
197: return type.getParameterValue("charset");
198: }
1.19 bmahe 199: return "ISO-8859-1";
1.18 bmahe 200: }
201:
202: /**
203: * ServletRequest implementation - Get the length of request data.
204: * @return An int, or <strong>-1</strong>.
205: */
206:
207: public int getContentLength()
208: {
209: return request.getContentLength();
210: }
211:
212: /**
213: * ServletRequest implementation - Get the type of the request's body.
214: * @return A String encoded mime type, or <strong>null</strong>.
215: */
216:
217: public String getContentType()
218: {
219: org.w3c.www.mime.MimeType t = request.getContentType();
220: return (t == null) ? null : t.toString();
221: }
222:
223: /**
224: * ServletRequest implementation - Get the protocol of that request.
225: * @return A String encoded version of the protocol.
226: */
227:
228: public String getProtocol()
229: {
230: return request.getVersion();
231: }
232:
1.47 bmahe 233: protected httpd getServer() {
234: return request.getClient().getServer();
235: }
236:
1.18 bmahe 237: /**
238: * ServletRequest implementation - Get the name of queried server.
239: * @return Name of server, as a String.
240: */
241:
242: public String getServerName()
243: {
1.39 bmahe 244: if (request.isProxy()) {
245: String host = request.getHost();
246: if (host != null)
247: return host.substring(0, host.lastIndexOf(':'));
248: }
1.47 bmahe 249: return getServer().getHost();
1.18 bmahe 250: }
251:
252: /**
253: * ServletRequest implementation - Get the port of queried server.
254: * @return A port number (int).
255: */
256:
257: public int getServerPort()
258: {
1.39 bmahe 259: if (request.isProxy()) {
260: String host = request.getHost();
261: if (host != null) {
262: int idx = host.lastIndexOf(':');
263: if (idx == -1)
264: return 80;
265: return Integer.parseInt(host.substring(idx+1));
266: }
267: }
1.47 bmahe 268: return getServer().getLocalPort();
1.18 bmahe 269: }
270:
271: /**
272: * ServletRequest implementation - Get the IP address of requests's sender.
273: * @return Numeric IP address, as a String.
274: */
275:
276: public String getRemoteAddr()
277: {
278: return request.getClient().getInetAddress().getHostAddress();
279: }
280:
281: /**
282: * ServletRequest implementation - FQDN of request's sender.
283: * @return Name of client's machine (FQDN).
284: */
285:
286: public String getRemoteHost()
287: {
288: return request.getClient().getInetAddress().getHostName();
289: }
290:
291: /**
292: * ServletRequest implementation - Get real path.
293: * Jigsaw realy has no notion of <em>translation</em> stricto
294: * sensu (it has much better in fact ;-). This is a pain here.
1.46 bmahe 295: * @return the real path.
1.42 bmahe 296: * @deprecated since jsdk1.2
1.18 bmahe 297: */
298:
299: public String getRealPath(String name) {
1.47 bmahe 300: httpd server = getServer();
1.46 bmahe 301: ResourceReference rr_root = server.getRootReference();
1.49 ! bmahe 302: File dir =
! 303: JigsawServletContext.getRootDirectory(rr_root,
! 304: request.getTargetResource());
! 305: if (dir == null) {
! 306: String message = "Error: unable to compute root directory";
! 307: throw new RuntimeException(message);
1.46 bmahe 308: }
1.49 ! bmahe 309: return new File(dir, name).getAbsolutePath();
1.18 bmahe 310: }
311:
1.32 bmahe 312: protected ServletInputStream is = null;
313:
1.18 bmahe 314: /**
1.32 bmahe 315: * Returns an input stream for reading binary data in the request body.
316: * @exception IllegalStateException if getReader has been called on
317: * this same request.
318: * @exception IOException on other I/O related errors.
1.41 ylafon 319: * @see JigsawHttpServletRequest#getReader
1.32 bmahe 320: */
1.18 bmahe 321: public ServletInputStream getInputStream()
322: throws IOException
323: {
324: if (stream_state == STREAM_READER_USED)
325: throw new IllegalStateException("Reader used");
326: stream_state = INPUT_STREAM_USED;
327: return getJigsawInputStream();
328: }
329:
1.37 bmahe 330: /**
1.38 bmahe 331: * @exception IOException if an IO error occurs
1.37 bmahe 332: */
1.18 bmahe 333: protected ServletInputStream getJigsawInputStream()
334: throws IOException
335: {
336: // If alredy computed return:
337: if ( is != null )
338: return is;
339: // Built it:
340: InputStream stream = null;
341: if ((stream = request.getInputStream()) == null)
342: stream = new ContentLengthInputStream(null, 0);
343: return is = new JigsawServletInputStream(stream);
344: }
345:
346: /**
347: * ServletRequest implementation - Get a parameter value.
348: * @return The String encoded value for the parameter.
349: */
350:
351: public String getParameter(String name)
352: {
353: prepareQueryParameters();
354: if ( queryParameters != null ) {
355: Object value = queryParameters.get(name);
356: if (value instanceof String[])
357: return ((String[])value)[0];
358: else return (String)value;
359: }
360: else
361: return null;
362: }
363:
364: /**
365: * ServletRequest implementation - Get the parameters value.
366: * @return The String array encoded value for the parameter.
367: */
368:
369: public String[] getParameterValues(String parameter) {
370: Vector V = new Vector(23);
371: prepareQueryParameters();
372: if (queryParameters == null)
373: return null;
374: Object value = queryParameters.get(parameter);
375: if (value == null) return null;
376: if (value instanceof String[])
377: return (String[])value;
378: else {
379: String [] parameterValues = new String[1];
380: parameterValues[0] = (String)value;
381: return parameterValues;
382: }
383: }
384:
385: /**
386: * ServletRequest implementation - List available parameters.
387: * @return An enumeration of parameter names.
388: */
389:
390: public Enumeration getParameterNames()
391: {
392: prepareQueryParameters();
393: return ((queryParameters == null)
394: ? new EmptyEnumeration()
395: : queryParameters.keys());
396: }
397:
398: /**
399: * ServletRequest implementation - Get an attribute of the request.
400: * This closely match Jigsaw's notion of request state.
401: * @param name The name of the attribute.
402: * @return An object that gives the value of the attribute.
403: */
404:
405: public Object getAttribute(String name) {
406: return request.getState(name);
407: }
408:
1.42 bmahe 409: public void setAttribute(String name, Object object) {
410: request.setState(name, object);
411: }
412:
1.47 bmahe 413: /**
414: * Removes an attribute from this request. This method is not
415: * generally needed as attributes only persist as long as the request
416: * is being handled.
417: *
418: * <p>Attribute names should follow the same conventions as
419: * package names. Names beginning with <code>java.*</code>,
420: * <code>javax.*</code>, and <code>com.sun.*</code>, are
421: * reserved for use by Sun Microsystems.
422: *
423: * @param name a <code>String</code> specifying
424: * the name of the attribute to remove
425: */
426: public void removeAttribute(String name) {
427: request.delState(name);
428: }
429:
1.42 bmahe 430: public Enumeration getAttributeNames() {
431: return request.getStateNames();
432: }
433:
1.18 bmahe 434: /**
1.47 bmahe 435: * Returns the preferred <code>Locale</code> that the client will
436: * accept content in, based on the Accept-Language header.
437: * If the client request doesn't provide an Accept-Language header,
438: * this method returns the default locale for the server.
439: *
440: * @return the preferred <code>Locale</code> for the client
441: */
442: public Locale getLocale() {
443: return (Locale)getLocales().nextElement();
444: }
445:
446: /**
447: * Returns an <code>Enumeration</code> of <code>Locale</code> objects
448: * indicating, in decreasing order starting with the preferred locale, the
449: * locales that are acceptable to the client based on the Accept-Language
450: * header.
451: * If the client request doesn't provide an Accept-Language header,
452: * this method returns an <code>Enumeration</code> containing one
453: * <code>Locale</code>, the default locale for the server.
454: *
455: * @return an <code>Enumeration</code> of preferred
456: * <code>Locale</code> objects for the client
457: */
458: public Enumeration getLocales() {
459: HttpAcceptLanguage languages[] = request.getAcceptLanguage();
460: if (languages == null) {
461: Vector def = new Vector();
462: def.addElement(Locale.getDefault());
463: return def.elements();
464: }
465:
1.48 bmahe 466: //LinkedList is better, but we must be JDK1.1 compliant
467: Vector locales = new Vector();
1.47 bmahe 468:
469: for (int i = 0 ; i < languages.length ; i++) {
470: HttpAcceptLanguage language = languages[i];
471: double quality = language.getQuality();
472: String lang = language.getLanguage();
473: String country = "";
474: int idx = lang.indexOf('-');
475: if (idx > -1) {
476: country = lang.substring(idx + 1).trim();
477: lang = lang.substring(0, idx).trim();
478: }
479: // insert the Locale in ordered list
1.48 bmahe 480: int qidx = 0;
481: int size = locales.size();
482: if (size > 0) {
483: QLocale ql = (QLocale) locales.firstElement();
484: while ((qidx < size) && (ql.getLanguageQuality() >= quality)) {
485: try {
486: ql = (QLocale) locales.elementAt(++qidx);
487: } catch (ArrayIndexOutOfBoundsException ex) {
488: //end of vector, so append
489: }
490: }
491: locales.insertElementAt(new QLocale(lang, country, quality),
492: qidx);
493: } else {
494: locales.addElement(new QLocale(lang, country, quality));
1.47 bmahe 495: }
496: }
497: // because Locale is final :(
498: int size = locales.size();
499: Vector vlocale = new Vector(size);
500: for (int i = 0 ; i < size ; i ++) {
1.48 bmahe 501: vlocale.addElement(((QLocale)locales.elementAt(i)).getLocale());
1.47 bmahe 502: }
503: return vlocale.elements();
504: }
505:
506: /**
507: * Returns a boolean indicating whether this request was made using a
508: * secure channel, such as HTTPS.
509: *
510: * @return a boolean indicating if the request was made using a
511: * secure channel
512: */
513:
514: public boolean isSecure() {
515: // only https secure?
516: return (request.getURL().getProtocol().equalsIgnoreCase("https"));
517: }
518:
519: /**
1.18 bmahe 520: * HttpServletRequest implementation - Get the request's method.
521: * @return A String instance.
522: */
523:
524: public String getMethod()
525: {
526: return request.getMethod();
527: }
528:
529: /**
530: * HttpServletRequest implementation - Get the request's path info.
531: * @return A String instance or <strong>null</strong>.
532: */
533:
534: public String getPathInfo()
535: {
536: return (String) request.getState(ServletWrapperFrame.STATE_EXTRA_PATH);
537: }
538:
539: /**
540: * HttpServletRequest implementation - Get the request's path translated.
541: * @return A String instance or <strong>null</strong>.
542: */
543:
544: public String getPathTranslated()
545: {
546: String pathinfo = getPathInfo();
1.46 bmahe 547: if ( pathinfo != null )
548: return getRealPath(pathinfo);
1.18 bmahe 549: return null;
550: }
551:
552: /**
1.47 bmahe 553: * Returns the portion of the request URI that indicates the context
554: * of the request. The context path always comes first in a request
555: * URI. The path starts with a "/" character but does not end with a "/"
556: * character. For servlets in the default (root) context, this method
557: * returns "".
558: * @return a <code>String</code> specifying the portion of the request
559: * URI that indicates the context of the request
560: */
561: public String getContextPath() {
562: throw new RuntimeException("Not Yet Implemented");
563: }
564:
565: /**
1.18 bmahe 566: * HttpServletRequest implementation - Get the request's query string.
567: * @return A String instance or <strong>null</strong>.
568: */
569:
570: public String getQueryString()
571: {
572: return request.getQueryString();
573: }
574:
575: /**
576: * HttpServletRequest implementation - Get the request's user (if any).
577: * @return A String instance or <strong>null</strong>.
578: */
579:
580: public String getRemoteUser()
581: {
582: return (String) request.getState(AuthFilter.STATE_AUTHUSER);
583: }
584:
585: /**
1.47 bmahe 586: * Returns a boolean indicating whether the authenticated user is included
587: * in the specified logical "role". Roles and role membership can be
588: * defined using deployment descriptors. If the user has not been
589: * authenticated, the method returns <code>false</code>.
590: *
591: * @param role a <code>String</code> specifying the name of the role
592: * @return a <code>boolean</code> indicating whether the user making this
593: * request belongs to a given role; <code>false</code> if the user has not
594: * been authenticated
595: */
596:
597: public boolean isUserInRole(String role) {
598: throw new RuntimeException("Not Yet Implemented");
599: }
600:
601: /**
602: * Returns a <code>java.security.Principal</code> object containing
603: * the name of the current authenticated user. If the user has not been
604: * authenticated, the method returns <code>null</code>.
605: *
606: * @return a <code>java.security.Principal</code> containing
607: * the name of the user making this request; <code>null</code> if the
608: * user has not been authenticated
609: */
610: public Principal getUserPrincipal() {
611: return new PrincipalImpl(getRemoteUser());
612: }
613:
614: /**
1.18 bmahe 615: * HttpServletRequest implementation - Get the request's auth method.
616: * @return A String instance or <strong>null</strong>.
617: */
618:
619: public String getAuthType() {
620: return (String) request.getState(AuthFilter.STATE_AUTHTYPE);
621: }
622:
623: /**
624: * HttpServletRequest implementation - Get a request header as a String.
625: * @return A String instance or <strong>null</strong>.
626: */
627:
628: public String getHeader(String name) {
629: return request.getValue(name);
630: }
631:
632: /**
1.47 bmahe 633: * Returns all the values of the specified request header
634: * as an <code>Enumeration</code> of <code>String</code> objects.
635: *
636: * <p>Some headers, such as <code>Accept-Language</code> can be sent
637: * by clients as several headers each with a different value rather than
638: * sending the header as a comma separated list.
639: *
640: * <p>WARNING, this can't happen with Jigsaw, all multiple values are
641: * grouped in one, and only one, header. So, this method always return
642: * ONE header value.
643: *
644: * <p>If the request did not include any headers
645: * of the specified name, this method returns an empty
646: * <code>Enumeration</code>.
647: * The header name is case insensitive. You can use
648: * this method with any request header.
649: *
650: * @param name a <code>String</code> specifying the header name
651: * @return a <code>Enumeration</code> containing the values of the
652: * requested header, or <code>null</code> if the request does not
653: * have any headers of that name
654: */
655:
656: public Enumeration getHeaders(String name) {
657: String value = getHeader(name);
658: String array[] = { value };
659: return new ArrayEnumeration(array);
660: }
661:
662: /**
1.18 bmahe 663: * HttpServletRequest implementation - Get a request header as an int.
664: * @return An int, or <strong>-1</strong>.
665: */
666:
667: public int getIntHeader(String name) {
668: HeaderValue v = request.getHeaderValue(name);
669: if ( v != null ) {
670: Object o = v.getValue();
671: if ((o != null) && (o instanceof Integer))
672: return ((Integer) o).intValue();
1.1 abaird 673: }
1.18 bmahe 674: return -1;
1.1 abaird 675: }
1.18 bmahe 676:
677: /**
678: * HttpServletRequest implementation - Get a request header as an date.
679: * @return An long (as a number of milliseconds), or <strong>-1</strong>.
680: */
681:
682: public long getDateHeader(String name) {
683: HeaderValue v = request.getHeaderValue(name, null);
684: if ( v != null ) {
685: Object o = v.getValue();
686: if ((o != null) && (o instanceof Long))
687: return ((Long) o).longValue();
1.10 bmahe 688: }
1.18 bmahe 689: return (long) -1;
1.1 abaird 690: }
1.8 bmahe 691:
1.18 bmahe 692: /**
693: * HttpServletRequest implementation - Get a all header names.
694: * @return An enumeration.
695: */
696:
697: public Enumeration getHeaderNames() {
698: return new HeaderNames(request.enumerateHeaderDescriptions());
699: }
1.16 bmahe 700:
1.25 bmahe 701: /**
702: * Gets, from the first line of the HTTP request,
703: * the part of this request's URI that is to the left of any query string.
704: */
1.18 bmahe 705: public String getRequestURI()
706: {
1.39 bmahe 707: String uri = null;
708: //fixme test
709: if (request.isProxy()) {
710: uri = request.getURL().toExternalForm();
711: } else {
712: uri = request.getURLPath();
713: }
714: if (request.hasQueryString()) {
715: String query = request.getQueryString();
716: int idx = uri.lastIndexOf(query);
717: uri = uri.substring(0, idx-1);
718: }
719: return uri;
1.18 bmahe 720: }
721:
1.25 bmahe 722: /**
1.47 bmahe 723: * Returns a {@link RequestDispatcher} object that acts as a wrapper for
724: * the resource located at the given path.
725: * A <code>RequestDispatcher</code> object can be used to forward
726: * a request to the resource or to include the resource in a response.
727: * The resource can be dynamic or static.
728: *
729: * <p>The pathname specified may be relative, although it cannot extend
730: * outside the current servlet context. If the path begins with
731: * a "/" it is interpreted as relative to the current context root.
732: * This method returns <code>null</code> if the servlet container
733: * cannot return a <code>RequestDispatcher</code>.
734: *
735: * <p>The difference between this method and {@link
736: * ServletContext#getRequestDispatcher} is that this method can take a
737: * relative path.
738: *
739: * @param path a <code>String</code> specifying the pathname
740: * to the resource
741: * @return a <code>RequestDispatcher</code> object that acts as a
742: * wrapper for the resource at the specified path
743: * @see RequestDispatcher
744: * @see ServletContext#getRequestDispatcher
745: */
746: public RequestDispatcher getRequestDispatcher(String path) {
747: if (path == null) {
748: throw new IllegalArgumentException("null");
749: }
750: ResourceReference rr = request.getTargetResource();
751: String uri = null;
752: try {
753: ResourceReference rrp = rr.lock().getParent();
754: try {
755: Resource r = rrp.lock();
756: uri = r.getURLPath();
757: } catch (InvalidResourceException irex) {
758: return null;
759: } finally {
760: rrp.unlock();
761: }
762: } catch (InvalidResourceException ex) {
763: return null;
764: } finally {
765: rr.unlock();
766: }
767: String urlpath = ( uri.endsWith("/") ? uri+path : uri+"/"+path );
768: return JigsawRequestDispatcher.getRequestDispatcher(urlpath,
769: getServer());
770: }
771:
772: /**
1.25 bmahe 773: * Gets the part of this request's URI that refers to the servlet
774: * being invoked. Analogous to the CGI variable SCRIPT_NAME.
775: */
1.47 bmahe 776: public String getServletPath()
1.18 bmahe 777: {
778: ResourceReference rr = request.getTargetResource();
1.16 bmahe 779: try {
1.18 bmahe 780: return rr.lock().getURLPath();
1.16 bmahe 781: } catch (InvalidResourceException ex) {
1.18 bmahe 782: return null;
1.16 bmahe 783: } finally {
1.18 bmahe 784: rr.unlock();
1.16 bmahe 785: }
1.18 bmahe 786: }
787:
1.25 bmahe 788: /**
789: * @return the scheme of the URL used in this request, for example "http",
790: * "https", or "ftp". Different schemes have different rules
791: * for constructing URLs, as noted in RFC 1738. The URL used to create
792: * a request may be reconstructed using this scheme, the server name
793: * and port, and additional information such as URIs.
794: */
1.18 bmahe 795: public String getScheme() {
796: return request.getURL().getProtocol();
797: }
1.16 bmahe 798:
1.25 bmahe 799: /**
800: * Gets the array of cookies found in this request.
1.36 bmahe 801: * @return the array of cookies found in this request or
802: * <strong>null</strong> if there is no cookie.
1.25 bmahe 803: */
1.18 bmahe 804: public Cookie[] getCookies() {
1.19 bmahe 805: HttpCookieList cookielist = request.getCookie();
1.36 bmahe 806: Cookie[] Scookies = null;
807: if (cookielist != null) {
808: HttpCookie[] cookies = cookielist.getCookies();
809: Scookies = new Cookie[cookies.length];
810: for (int i = 0 ; i < cookies.length ; i++ ) {
811: Scookies[i] = convertCookie(cookies[i]);
812: }
1.19 bmahe 813: }
814: return Scookies;
815: }
816:
817: protected Cookie convertCookie(HttpCookie httpCookie) {
818: Cookie cookie = new Cookie(httpCookie.getName(),
819: httpCookie.getValue());
1.40 bmahe 820: String val = null;
821: if ((val = httpCookie.getDomain()) != null)
822: cookie.setDomain(val);
823: if ((val = httpCookie.getPath()) != null)
824: cookie.setPath(val);
1.19 bmahe 825: cookie.setVersion(httpCookie.getVersion());
826: return cookie;
827: }
828:
829: protected String getRequestedSessionIdFromCookie() {
830: HttpCookieList cookielist = request.getCookie();
831: if (cookielist != null) {
832: HttpCookie httpCookie =
1.28 bmahe 833: request.getCookie().getCookie(getCookieName());
1.19 bmahe 834: if (httpCookie != null)
835: return httpCookie.getValue();
836: }
1.18 bmahe 837: return null;
838: }
1.19 bmahe 839:
1.31 bmahe 840: protected String getRequestedSessionIdFromURL() {
841: return getURLParameter(getCookieName());
842: }
843:
1.25 bmahe 844: /**
845: * Gets the session id specified with this request. This may differ
846: * from the actual session id. For example, if the request specified an
847: * id for an invalid session, then this will get a new session with a
848: * new id.
849: * @return the session id specified by this request, or null if the
850: * request did not specify a session id.
851: */
1.18 bmahe 852: public String getRequestedSessionId() {
1.31 bmahe 853: if (requestedSessionID == null) {
1.27 bmahe 854: requestedSessionID = getRequestedSessionIdFromCookie();
1.31 bmahe 855: if (requestedSessionID == null)
856: requestedSessionID = getRequestedSessionIdFromURL();
857: }
1.19 bmahe 858: return requestedSessionID;
859: }
860:
861: protected synchronized JigsawHttpSessionContext getSessionContext() {
862: return sessionContext;
1.15 benoit 863: }
1.14 bmahe 864:
1.25 bmahe 865: /**
866: * Gets the current valid session associated with this request, if create
867: * is false or, if necessary, creates a new session for the request, if
868: * create is true.
869: * @return the session associated with this request or null if create
870: * was false and no valid session is associated with this request.
871: */
1.18 bmahe 872: public HttpSession getSession(boolean create) {
1.19 bmahe 873: if (httpSession == null) {
1.27 bmahe 874: httpSession = (JigsawHttpSession)
875: getSession(getRequestedSessionId());
1.29 bmahe 876: if (httpSession != null) // the client join the session
877: httpSession.setNoMoreNew();
1.27 bmahe 878: }
879: if (httpSession == null & create) {
880: httpSession = new JigsawHttpSession(getSessionContext(),
881: createCookie());
882: response.addCookie(httpSession.getCookie());
883: } else if (httpSession != null) {
884: httpSession.setLastAccessedTime();
885: if (! httpSession.isValid()) {
1.19 bmahe 886: httpSession = new JigsawHttpSession(getSessionContext(),
887: createCookie());
888: response.addCookie(httpSession.getCookie());
889: }
890: }
891: return httpSession;
892: }
893:
1.42 bmahe 894: /**
895: * Gets the current valid session associated with this request.
896: * @return the session associated with this request.
897: */
898: public HttpSession getSession() {
899: return getSession(true);
900: }
901:
1.33 bmahe 902: protected String getCookieName() {
903: ObservableProperties props =
904: request.getClient().getServer().getProperties();
905: return props.getString(ServletProps.SERVLET_COOKIE_NAME,
906: ServletProps.DEFAULT_COOKIE_NAME);
907: }
908:
909:
1.19 bmahe 910: protected Cookie createCookie() {
1.33 bmahe 911: ObservableProperties props =
912: request.getClient().getServer().getProperties();
1.34 bmahe 913: String name = props.getString(ServletProps.SERVLET_COOKIE_NAME,
914: ServletProps.DEFAULT_COOKIE_NAME);
915: String path = props.getString(ServletProps.SERVLET_COOKIE_PATH,
916: "/");
917: String domain = props.getString(ServletProps.SERVLET_COOKIE_DOMAIN,
1.35 bmahe 918: null);
1.34 bmahe 919: String comment = props.getString(ServletProps.SERVLET_COOKIE_COMMENT,
920: null);
921: int maxage = props.getInteger(ServletProps.SERVLET_COOKIE_MAXAGE,
922: 86400);
923: boolean secure = props.getBoolean(ServletProps.SERVLET_COOKIE_SECURE,
924: false);
1.33 bmahe 925:
926: Cookie cookie = new Cookie(name, null);
927: cookie.setPath(path);
928: cookie.setMaxAge(maxage);
929: if ((comment != null) && (comment.length() > 0))
930: cookie.setComment(comment);
931: if ((domain != null) && (domain.length() > 0))
932: cookie.setDomain(domain);
933: cookie.setSecure(secure);
1.19 bmahe 934: return cookie;
935: }
936:
937: protected HttpSession getSession(String sessionId) {
938: if (sessionId != null)
939: return getSessionContext().getSession(sessionId);
1.18 bmahe 940: return null;
941: }
1.17 bmahe 942:
1.25 bmahe 943: /**
944: * Checks whether this request is associated with a session that is valid
945: * in the current session context. If it is not valid, the requested
946: * session will never be returned from the getSession method.
947: * @return true if this request is assocated with a session that is valid
948: * in the current session context.
949: */
1.18 bmahe 950: public boolean isRequestedSessionIdValid() {
1.27 bmahe 951: JigsawHttpSession session = (JigsawHttpSession)
952: getSession(getRequestedSessionId());
1.19 bmahe 953: if (session == null)
954: return false;
955: return (session.isValid());
1.18 bmahe 956: }
957:
1.25 bmahe 958: /**
959: * Checks whether the session id specified by this request came in as
960: * a cookie. (The requested session may not be one returned by the
961: * getSession method.)
962: * @return true if the session id specified by this request came
963: * in as a cookie; false otherwise
964: */
1.18 bmahe 965: public boolean isRequestedSessionIdFromCookie() {
1.29 bmahe 966: return (getRequestedSessionIdFromCookie() != null);
1.18 bmahe 967: }
968:
1.25 bmahe 969: /**
970: * Checks whether the session id specified by this request came in as
971: * part of the URL. (The requested session may not be the one returned
972: * by the getSession method.)
973: * @return true if the session id specified by the request for this
974: * session came in as part of the URL; false otherwise
1.42 bmahe 975: * @deprecated since jsdk2.1
1.25 bmahe 976: */
1.18 bmahe 977: public boolean isRequestedSessionIdFromUrl() {
1.31 bmahe 978: return (getRequestedSessionIdFromURL() != null);
1.18 bmahe 979: }
980:
1.42 bmahe 981: /**
982: * Checks whether the session id specified by this request came in as
983: * part of the URL. (The requested session may not be the one returned
984: * by the getSession method.)
985: * @return true if the session id specified by the request for this
986: * session came in as part of the URL; false otherwise
987: */
988: public boolean isRequestedSessionIdFromURL() {
989: return (getRequestedSessionIdFromURL() != null);
990: }
991:
1.18 bmahe 992: protected BufferedReader reader = null;
1.25 bmahe 993:
994: /**
1.32 bmahe 995: * Returns a buffered reader for reading text in the request body.
1.25 bmahe 996: * This translates character set encodings as appropriate.
1.32 bmahe 997: * @exception UnsupportedEncodingException if the character set encoding
998: * is unsupported, so the text can't be correctly decoded.
999: * @exception IllegalStateException if getInputStream has been called on
1000: * this same request.
1001: * @exception IOException on other I/O related errors.
1.41 ylafon 1002: * @see JigsawHttpServletRequest#getInputStream
1.25 bmahe 1003: */
1.18 bmahe 1004: public BufferedReader getReader()
1005: throws IOException
1006: {
1007: if (stream_state == INPUT_STREAM_USED)
1008: throw new IllegalStateException("Input Stream used");
1009: stream_state = STREAM_READER_USED;
1010: if (reader == null) {
1.43 ylafon 1011: String enc[] = request.getContentEncoding();
1.44 ylafon 1012: InputStream is = getJigsawInputStream();
1.43 ylafon 1013: if (enc != null) {
1014: InputStreamReader isr = null;
1015: for (int i=0; i < enc.length; i++) {
1016: try {
1017: isr = new InputStreamReader(is, enc[i]);
1018: break;
1019: } catch (UnsupportedEncodingException ex) {
1020: // not a valid encoding, skip it
1021: isr = null;
1022: }
1023: }
1024: if (isr != null)
1025: reader = new BufferedReader(isr);
1026: else
1027: reader = new BufferedReader(new InputStreamReader(is));
1028: } else {
1029: reader = new BufferedReader(new InputStreamReader(is));
1030: }
1.18 bmahe 1031: }
1032: return reader;
1.42 bmahe 1033: }
1034:
1035: /**
1.47 bmahe 1036: * Get the wrapped Jigsaw Request.
1037: * @return the request
1.42 bmahe 1038: */
1039: protected Request getRequest() {
1040: return request;
1.19 bmahe 1041: }
1042:
1043: JigsawHttpServletRequest(Servlet servlet,
1044: Request request,
1.29 bmahe 1045: JigsawHttpServletResponse response,
1046: JigsawHttpSessionContext sessionContext) {
1047: this.servlet = servlet;
1048: this.request = request;
1049: this.response = response;
1050: this.sessionContext = sessionContext;
1.17 bmahe 1051: }
1052:
1.1 abaird 1053: }
Webmaster