Annotation of java/classes/org/w3c/jigsaw/servlet/JigsawHttpServletRequest.java, revision 1.62

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

Webmaster