View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/util/HttpServletRequestCompat.java,v $
3    * $Revision: 1.13 $
4    *
5    * Copyright (C) 2001 William Chesters
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     William Chesters <williamc At paneris.org>
42   *     http://paneris.org/~williamc
43   *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44   */
45  
46  package org.melati.util;
47  
48  import java.util.Map;
49  import java.util.Enumeration;
50  import java.util.Locale;
51  import javax.servlet.RequestDispatcher;
52  import javax.servlet.http.HttpSession;
53  import javax.servlet.http.HttpServletRequest;
54  import javax.servlet.http.Cookie;
55  import java.lang.reflect.Method;
56  import java.lang.reflect.InvocationTargetException;
57  
58  /**
59   * NOTE This is no longer used, but it is so cool it is still around to marvel at
60   * 
61   * The <code>HttpServletRequestCompat</code> class enables Melati to compile,
62   * without warnings, with the Servlet API versions 2.0 to 2.5.
63   * 
64   * The core methods are those present in the 2.0 API all methods added since 
65   * are established as static members. 
66   * These are then available to be invoked if present or a RuntimeException is thrown
67   * otherwise.
68   * 
69   * However, if you use a method which is not in your version of the API then you
70   * will get a runtime exception.
71   * 
72   * @see org.melati.util.DelegatedHttpServletRequest
73   */
74  
75  public final class HttpServletRequestCompat {
76    private static final long serialVersionUID = 1L;
77  
78    private HttpServletRequestCompat() {
79    }
80  
81    /** Deprecated in Servlet 2.1 API. */
82    private static Method isRequestedSessionIdFromUrl, getRealPath;
83  
84    /** New in Servlet 2.2 API. */
85    private static Method getUserPrincipal, getContextPath, getHeaders,
86        getSession, isRequestedSessionIdFromURL, isUserInRole, getAttributeNames,
87        getLocale, getLocales, getRequestDispatcher, isSecure, removeAttribute,
88        setAttribute;
89    /** New in Servlet 2.3 API. */
90    private static Method getRequestURL, setCharacterEncoding, getParameterMap;
91    /** New in Servlet 2.4 API. */
92    private static Method getLocalAddr, getLocalName, getLocalPort, getRemotePort;
93    
94    private static Method methodOrNull(Class<?> c, String n, String[] pn) {
95      try {
96        Class<?>[] p = new Class[pn.length];
97        for (int i = 0; i < pn.length; ++i)
98          p[i] = Class.forName(pn[i]);
99        return c.getMethod(n, p);
100     } catch (NoSuchMethodException e) {
101       return null;
102     } catch (ClassNotFoundException e) {
103       return null;
104     }
105   }
106 
107   static {
108     try {
109       String[] noparams = {};
110 
111       Class<?> hsr = Class.forName("javax.servlet.http.HttpServletRequest");
112       getUserPrincipal = methodOrNull(hsr, "getUserPrincipal", noparams);
113       getContextPath = methodOrNull(hsr, "getContextPath", noparams);
114       getHeaders = methodOrNull(hsr, "getHeaders",
115           new String[] { "java.lang.String" });
116       getSession = methodOrNull(hsr, "getSession", noparams);
117       isRequestedSessionIdFromURL = methodOrNull(hsr,
118           "isRequestedSessionIdFromURL", noparams);
119       isUserInRole = methodOrNull(hsr, "isUserInRole",
120           new String[] { "java.lang.String" });
121       getAttributeNames = methodOrNull(hsr, "getAttributeNames", noparams);
122       getLocale = methodOrNull(hsr, "getLocale", noparams);
123       getLocales = methodOrNull(hsr, "getLocales", noparams);
124       getRequestDispatcher = methodOrNull(hsr, "getRequestDispatcher",
125           new String[] { "java.lang.String" });
126       isSecure = methodOrNull(hsr, "isSecure", noparams);
127       removeAttribute = methodOrNull(hsr, "removeAttribute",
128           new String[] { "java.lang.String" });
129       setAttribute = methodOrNull(hsr, "setAttribute", new String[] {
130           "java.lang.String", "java.lang.Object" });
131       
132       getLocalAddr = methodOrNull(hsr, "getLocalAddr", noparams);
133       getLocalName = methodOrNull(hsr, "getLocalName", noparams);
134       getLocalPort = methodOrNull(hsr, "getLocalPort", noparams);
135       getRemotePort = methodOrNull(hsr, "getRemotePort", noparams);
136       
137     } catch (Exception e) {
138       e.printStackTrace();
139       throw new Error("org.melati.util.servletcompat.HttpServletRequestCompat"
140           + "failed to initialize; contact the Melati developers");
141     }
142   }
143   // 
144   // ================================
145   // Original Servlet API 2.0 methods 
146   // ================================
147   // 
148 
149   /**
150    * Returns the name of the authentication scheme used to protect the servlet,
151    * for example, "BASIC" or "SSL," or <code>null</code> if the servlet was
152    * not protected. <p>Same as the value of the CGI variable AUTH_TYPE.
153    * 
154    * @param it
155    *        the HttpServletRequest
156    * @return a <code>String</code> specifying the name of the authentication
157    *         scheme, or <code>null</code> if the request was not authenticated
158    * @see javax.servlet.http.HttpServletRequest#getAuthType()
159    * @since 2.0
160    */
161   public static String getAuthType(HttpServletRequest it) {
162     return it.getAuthType();
163   }
164 
165   /**
166    * Returns an array containing all of the <code>Cookie</code> objects the
167    * client sent with this request. This method returns <code>null</code> if
168    * no cookies were sent.
169    * 
170    * @param it
171    *        the HttpServletRequest
172    * @return an array of all the <code>Cookies</code> included with this
173    *         request, or <code>null</code> if the request has no cookies
174    * @see javax.servlet.http.HttpServletRequest#getCookies()
175    * @since 2.0
176    */
177   public static Cookie[] getCookies(HttpServletRequest it) {
178     return it.getCookies();
179   }
180 
181   /**
182    * Returns the value of the specified request header as a <code>long</code>
183    * value that represents a <code>Date</code> object. Use this method with
184    * headers that contain dates, such as <code>If-Modified-Since</code>. <p>The
185    * date is returned as the number of milliseconds since January 1, 1970 GMT.
186    * The header name is case insensitive. <p>If the request did not have a
187    * header of the specified name, this method returns -1. If the header can't
188    * be converted to a date, the method throws an
189    * <code>IllegalArgumentException</code>.
190    * 
191    * @param it
192    *        the HttpServletRequest
193    * @return a <code>long</code> value representing the date specified in the
194    *         header expressed as the number of milliseconds since January 1,
195    *         1970 GMT, or -1 if the named header was not included with the
196    *         request
197    * @see javax.servlet.http.HttpServletRequest#getDateHeader(String)
198    * @since 2.0
199    */
200   public static long getDateHeader(HttpServletRequest it, String a) {
201     return it.getDateHeader(a);
202   }
203 
204   /**
205    * Returns the value of the specified request header as a <code>String</code>.
206    * If the request did not include a header of the specified name, this method
207    * returns <code>null</code>. The header name is case insensitive. You can
208    * use this method with any request header.
209    * 
210    * @param it
211    *        the HttpServletRequest
212    * @return a <code>String</code> containing the value of the requested
213    *         header, or <code>null</code> if the request does not have a
214    *         header of that name
215    * @see javax.servlet.http.HttpServletRequest#getHeader(String)
216    * @since 2.0
217    */
218   public static String getHeader(HttpServletRequest it, String a) {
219     return it.getHeader(a);
220   }
221 
222   /**
223    * Returns an enumeration of all the header names this request contains. If
224    * the request has no headers, this method returns an empty enumeration. <p>Some
225    * servlet containers do not allow do not allow servlets to access headers
226    * using this method, in which case this method returns <code>null</code>
227    * 
228    * @param it
229    *        the HttpServletRequest
230    * @return an enumeration of all the header names sent with this request; if
231    *         the request has no headers, an empty enumeration; if the servlet
232    *         container does not allow servlets to use this method,
233    *         <code>null</code>
234    * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
235    * @since 2.0
236    */
237   @SuppressWarnings("unchecked")
238   public static Enumeration<String> getHeaderNames(HttpServletRequest it) {
239     return it.getHeaderNames();
240   }
241 
242   /**
243    * Returns the value of the specified request header as an <code>int</code>.
244    * If the request does not have a header of the specified name, this method
245    * returns -1. If the header cannot be converted to an integer, this method
246    * throws a <code>NumberFormatException</code>. <p>The header name is case
247    * insensitive.
248    * 
249    * @param it
250    *        the HttpServletRequest
251    * @return an integer expressing the value of the request header or -1 if the
252    *         request doesn't have a header of this name
253    * @see javax.servlet.http.HttpServletRequest#getIntHeader(String)
254    * @since 2.0
255    */
256   public static int getIntHeader(HttpServletRequest it, String a) {
257     return it.getIntHeader(a);
258   }
259 
260   /**
261    * @param it the HttpServletRequest
262    * @return      a <code>String</code> 
263    *        specifying the name
264    *        of the method with which
265    *        this request was made
266    * @see javax.servlet.http.HttpServletRequest#getMethod()
267    * @since 2.0
268    */
269   public static String getMethod(HttpServletRequest it) {
270     return it.getMethod();
271   }
272 
273   /**
274    * @param it
275    *        the HttpServletRequest
276    * @return    a <code>String</code> specifying 
277    *      extra path information that comes
278    *      after the servlet path but before
279    *      the query string in the request URL;
280    *      or <code>null</code> if the URL does not have
281    *      any extra path information
282    * @see javax.servlet.http.HttpServletRequest#getPathInfo()
283    * @since 2.0
284    */
285   public static String getPathInfo(HttpServletRequest it) {
286     return it.getPathInfo();
287   }
288 
289   /**
290    * @param it
291    *        the HttpServletRequest
292    * @return    a <code>String</code> specifying the
293    *      real path, or <code>null</code> if
294    *      the URL does not have any extra path
295    *      information
296    * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
297    * @since 2.0
298    */
299   public static String getPathTranslated(HttpServletRequest it) {
300     return it.getPathTranslated();
301   }
302 
303   /**
304    * @param it
305    *        the HttpServletRequest
306    * @return    a <code>String</code> containing the query
307    *      string or <code>null</code> if the URL 
308    *      contains no query string
309    * @see javax.servlet.http.HttpServletRequest#getQueryString()
310    * @since 2.0
311    */
312   public static String getQueryString(HttpServletRequest it) {
313     return it.getQueryString();
314   }
315 
316   /**
317    * @param it
318    *        the HttpServletRequest
319    * @return    a <code>String</code> specifying the login
320    *      of the user making this request, or <code>null</code>
321    *      if the user login is not known
322    * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
323    * @since 2.0
324    */
325   public static String getRemoteUser(HttpServletRequest it) {
326     return it.getRemoteUser();
327   }
328 
329   /**
330    * @param it
331    *        the HttpServletRequest
332    * @return    a <code>String</code> containing
333    *      the part of the URL from the 
334    *      protocol name up to the query string
335    * @see javax.servlet.http.HttpServletRequest#getRequestURI()
336    * @since 2.0
337    */
338   public static String getRequestURI(HttpServletRequest it) {
339     return it.getRequestURI();
340   }
341 
342   /**
343    * @param it
344    *        the HttpServletRequest
345    * @return    a <code>String</code> specifying the session
346    *      ID, or <code>null</code> if the request did
347    *      not specify a session ID
348    * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
349    * @since 2.0
350    */
351   public static String getRequestedSessionId(HttpServletRequest it) {
352     return it.getRequestedSessionId();
353   }
354 
355   /**
356    * @param it
357    *        the HttpServletRequest
358    * @return    a <code>String</code> containing
359    *      the name or path of the servlet being
360    *      called, as specified in the request URL 
361    * @see javax.servlet.http.HttpServletRequest#getServletPath()
362    * @since 2.0
363    */
364   public static String getServletPath(HttpServletRequest it) {
365     return it.getServletPath();
366   }
367 
368   /**
369    * @param it
370    *        the HttpServletRequest
371    * @param a
372    * @return    the <code>HttpSession</code> associated
373    *      with this request
374    * @see javax.servlet.http.HttpServletRequest#getSession()
375    * @since 2.0
376    */
377   public static HttpSession getSession(HttpServletRequest it, boolean a) {
378     return it.getSession(a);
379   }
380 
381   /**
382    * @param it
383    *        the HttpServletRequest
384    * @return      <code>true</code> if this
385    *        request has an id for a valid session
386    *        in the current session context;
387    *        <code>false</code> otherwise
388    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
389    * @since 2.0
390    */
391   public static boolean isRequestedSessionIdValid(HttpServletRequest it) {
392     return it.isRequestedSessionIdValid();
393   }
394 
395   /**
396    * @param it
397    *        the HttpServletRequest
398    * @return      <code>true</code> if the session ID
399    *        came in as a
400    *        cookie; otherwise, <code>false</code>
401    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
402    * @since 2.0
403    */
404   public static boolean isRequestedSessionIdFromCookie(HttpServletRequest it) {
405     return it.isRequestedSessionIdFromCookie();
406   }
407   
408   //======================
409   // Invocation machinery
410   //======================
411   
412   /**
413    * Thrown when a method that is not available is invoked.
414    */
415   public static class MissingMethodError extends NoSuchMethodError {
416     private static final long serialVersionUID = 1L;
417 
418     /**
419      * {@inheritDoc}
420      * 
421      * @see java.lang.Throwable#getMessage()
422      */
423     public String getMessage() {
424       return "The application tried to use a method from the "
425           + "Servlet API which is not present in the version it running against.";
426     }
427   }
428 
429   private static Object invoke(Method method, HttpServletRequest it,
430       Object[] args) {
431     if (method == null)
432       throw new MissingMethodError();
433     else {
434       try {
435         return method.invoke(it, args);
436       } catch (InvocationTargetException e) {
437         Throwable f = e.getTargetException();
438         if (f instanceof RuntimeException) // they all should be
439           throw (RuntimeException)f;
440         else if (f instanceof Exception)
441           throw new RuntimeException("while invoking a Servlet API method",
442                                      f);
443         else if (f instanceof Error)
444           throw (Error)f;
445         else {
446           f.printStackTrace();
447           throw new Error("totally unexpected kind of throwable in "
448               + "org.melati.util.servletcompat.HttpServletRequestCompat");
449         }
450       } catch (IllegalAccessException e) {
451         e.printStackTrace();
452         throw new Error(
453                         "org.melati.util.servletcompat.HttpServletRequestCompat"
454                             + "got an unexpected IllegalAccessException trying to "
455                             + "invoke a method; contact the Melati developers");
456       }
457     }
458   }
459 
460   private static final Object[] noargs = {};
461 
462   // 
463   // ============================
464   // Servlet API 2.1 deprecatons
465   // ============================
466   // 
467 
468   /**
469    * @param it
470    *        the HttpServletRequest
471    * @param arg
472    *        url String
473    * @return the real path
474    * @deprecated Servlet API 2.1
475    * @see javax.servlet.ServletRequest#getRealPath(String)
476    * @since 2.0
477    */
478   public static String getRealPath(HttpServletRequest it, String arg) {
479     return (String)invoke(getRealPath, it, new Object[] { arg });
480   }
481 
482   /**
483    * @param it
484    *        the HttpServletRequest
485    * @return whether id is from url
486    * @deprecated Servlet API 2.1 
487    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
488    * @since 2.0
489    */
490   public static boolean isRequestedSessionIdFromUrl(HttpServletRequest it) {
491     return ((Boolean)invoke(isRequestedSessionIdFromUrl, it, noargs))
492         .booleanValue();
493   }
494 
495   // 
496   // ============================
497   // Servlet API 2.1 extensions
498   // ============================
499   // 
500 
501   /**
502    * Returns the empty string when run against 2.0 API.
503    * 
504    * @param it
505    *        the HttpServletRequest
506    * @return the Context path or empty string
507    * @see javax.servlet.http.HttpServletRequest#getContextPath()
508    * @since 2.1
509    */
510   public static String getContextPath(HttpServletRequest it) {
511     if (getContextPath == null)
512       return "";
513     else
514       return (String)invoke(getContextPath, it, noargs);
515   }
516 
517   /**
518    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
519    * 
520    * @param it
521    *        the HttpServletRequest
522    * @return    a <code>java.security.Principal</code> containing
523    *      the name of the user making this request;
524    *      <code>null</code> if the user has not been 
525    *      authenticated
526    * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
527    * @since 2.1
528    */
529   public static java.security.Principal getUserPrincipal(HttpServletRequest it) {
530     return (java.security.Principal)invoke(getUserPrincipal, it, noargs);
531   }
532 
533   /**
534    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
535    * 
536    * @param it
537    *        the HttpServletRequest
538    * @param arg
539    * @return      a <code>Enumeration</code> containing the
540    *        values of the requested
541    *        header, or <code>null</code>
542    *        if the request does not
543    *        have any headers of that name
544    * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
545    * @since 2.1
546    */
547   @SuppressWarnings("unchecked")
548   public static Enumeration getHeaders(HttpServletRequest it, String arg) {
549     return (Enumeration)invoke(getHeaders, it, new Object[] { arg });
550   }
551 
552   /**
553    * Throws <TT>MissingMethodError</TT> when run against 2.0 API, 
554    * introduced in 2.1.
555    * 
556    * @param it
557    *        the HttpServletRequest
558    * @return    the <code>HttpSession</code> associated
559    *      with this request
560    * @see javax.servlet.http.HttpServletRequest#getSession()
561    * @since 2.1
562    */
563   public static HttpSession getSession(HttpServletRequest it) {
564     return (HttpSession)invoke(getSession, it, noargs);
565   }
566 
567   /**
568    * Throws <TT>MissingMethodError</TT> when run against 2.0 API, 
569    * introduced in 2.1.
570    * 
571    * @param it
572    *        the HttpServletRequest
573    * @return      <code>true</code> if the session ID
574    *        came in as part of a URL; otherwise,
575    *        <code>false</code>
576    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
577    * @since 2.1
578    */
579   public static boolean isRequestedSessionIdFromURL(HttpServletRequest it) {
580     return ((Boolean)invoke(isRequestedSessionIdFromURL, it, noargs))
581         .booleanValue();
582   }
583 
584   // 
585   // ============================
586   // Servlet API 2.2 extensions
587   // ============================
588   // 
589 
590   /**
591    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
592    * 
593    * @param it
594    *        the HttpServletRequest
595    * @param arg
596    * @return    a <code>boolean</code> indicating whether
597    *      the user making this request belongs to a given role;
598    *      <code>false</code> if the user has not been 
599    *      authenticated
600    * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
601    * @since 2.2
602    */
603   public static boolean isUserInRole(HttpServletRequest it, String arg) {
604     return ((Boolean)invoke(isUserInRole, it, new Object[] { arg }))
605         .booleanValue();
606   }
607 
608   /**
609    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns an
610    * <code>Enumeration</code> containing the names of the attributes available
611    * to this request. This method returns an empty <code>Enumeration</code> if
612    * the request has no attributes available to it.
613    * 
614    * @param it
615    *        the HttpServletRequest
616    * @return an <code>Enumeration</code> of strings containing the names of
617    *         the request's attributes
618    * @see javax.servlet.http.HttpServletRequest#getAttributeNames()
619    * @since 2.2
620    */
621   @SuppressWarnings("unchecked")
622   public static Enumeration getAttributeNames(HttpServletRequest it) {
623     return (Enumeration)invoke(getAttributeNames, it, noargs);
624   }
625 
626   /**
627    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns the
628    * preferred <code>Locale</code> that the client will accept content in,
629    * based on the Accept-Language header. If the client request doesn't provide
630    * an Accept-Language header, this method returns the default locale for the
631    * server.
632    * 
633    * @param it
634    *        the HttpServletRequest
635    * @return the preferred <code>Locale</code> for the client
636    * @see javax.servlet.http.HttpServletRequest#getLocale()
637    * @since 2.2
638    */
639   public static Locale getLocale(HttpServletRequest it) {
640     return (Locale)invoke(getLocale, it, noargs);
641   }
642 
643   /**
644    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns an
645    * <code>Enumeration</code> of <code>Locale</code> objects indicating, in
646    * decreasing order starting with the preferred locale, the locales that are
647    * acceptable to the client based on the Accept-Language header. If the client
648    * request doesn't provide an Accept-Language header, this method returns an
649    * <code>Enumeration</code> containing one <code>Locale</code>, the
650    * default locale for the server.
651    * 
652    * @param it
653    *        the HttpServletRequest
654    * @return an <code>Enumeration</code> of preferred <code>Locale</code>
655    *         objects for the client
656    * @see javax.servlet.http.HttpServletRequest#getLocales()
657    * @since 2.2
658    */
659   @SuppressWarnings("unchecked")
660   public static Enumeration getLocales(HttpServletRequest it) {
661     return (Enumeration)invoke(getLocales, it, noargs);
662   }
663 
664   /**
665    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. If you get
666    * compile errors for this method, it's probably because (a) you are compiling
667    * against the 2.0 servlet API.
668    * 
669    * Returns a {@link RequestDispatcher} object that acts as a wrapper for the
670    * resource located at the given path. A <code>RequestDispatcher</code>
671    * object can be used to forward a request to the resource or to include the
672    * resource in a response. The resource can be dynamic or static. 
673    * 
674    * The
675    * pathname specified may be relative, although it cannot extend outside the
676    * current servlet context. If the path begins with a "/" it is interpreted as
677    * relative to the current context root. This method returns <code>null</code>
678    * if the servlet container cannot return a <code>RequestDispatcher</code>.
679    * 
680    * The difference between this method and 
681    * {@link ServletContext#getRequestDispatcher} is that this method can take a
682    * relative path.
683    * 
684    * @param it
685    *        the HttpServletRequest
686    * @param arg
687    *        a <code>String</code> specifying the pathname to the resource
688    * @return a <code>RequestDispatcher</code> object that acts as a wrapper
689    *         for the resource at the specified path
690    * @see RequestDispatcher
691    * @see javax.servlet.http.HttpServletRequest#getRequestDispatcher(String)
692    * @since 2.2
693    */
694   public static RequestDispatcher getRequestDispatcher(HttpServletRequest it,
695       String arg) {
696     return (RequestDispatcher)invoke(getRequestDispatcher, it,
697         new Object[] { arg });
698   }
699 
700   /**
701    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns a
702    * boolean indicating whether this request was made using a secure channel,
703    * such as HTTPS.
704    * 
705    * @param it
706    *        the HttpServletRequest
707    * @return a boolean indicating if the request was made using a secure channel
708    * @see javax.servlet.http.HttpServletRequest#isSecure()
709    * @since 2.2
710    */
711   public static boolean isSecure(HttpServletRequest it) {
712     return ((Boolean)invoke(isSecure, it, noargs)).booleanValue();
713   }
714 
715   /**
716    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Removes an
717    * attribute from this request. This method is not generally needed as
718    * attributes only persist as long as the request is being handled. <p>Attribute
719    * names should follow the same conventions as package names. Names beginning
720    * with <code>java.*</code>, <code>javax.*</code>, and
721    * <code>com.sun.*</code>, are reserved for use by Sun Microsystems.
722    * 
723    * @param it
724    *        the HttpServletRequest
725    * @param arg
726    *        a <code>String</code> specifying the name of the attribute to
727    *        remove
728    * @see javax.servlet.http.HttpServletRequest#removeAttribute()
729    * @since 2.2
730    */
731   public static void removeAttribute(HttpServletRequest it, String arg) {
732     invoke(removeAttribute, it, new Object[] { arg });
733   }
734 
735   /**
736    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Stores an
737    * attribute in this request. Attributes are reset between requests. This
738    * method is most often used in conjunction with {@link RequestDispatcher}.
739    * <p>Attribute names should follow the same conventions as package names.
740    * Names beginning with <code>java.*</code>, <code>javax.*</code>, and
741    * <code>com.sun.*</code>, are reserved for use by Sun Microsystems.
742    * 
743    * @param it
744    *        the HttpServletRequest
745    * @param arg1
746    *        a <code>String</code> specifying the name of the attribute
747    * @param arg2
748    *        the <code>Object</code> to be stored
749    * @see javax.servlet.http.HttpServletRequest#setAttribute
750    * @since 2.2
751    */
752   public static void setAttribute(HttpServletRequest it, String arg1,
753       Object arg2) {
754     invoke(setAttribute, it, new Object[] { arg1, arg2 });
755   }
756 
757   // 
758   // ============================
759   // Servlet API 2.3 extensions
760   // ============================
761   // 
762 
763   /**
764    * Throws <TT>MissingMethodError</TT> when run against 2.2 API.
765    * 
766    * @param it
767    *        the HttpServletRequest
768    * @return request url as a String buffer
769    * @see javax.servlet.http.HttpServletRequest#getRequestURL()
770    * @since 2.3
771    */
772   public static StringBuffer getRequestURL(HttpServletRequest it) {
773     return (StringBuffer)invoke(getRequestURL, it, noargs);
774   }
775 
776   /**
777    * Throws <TT>MissingMethodError</TT> when run against 2.2 API.
778    * 
779    * @param it
780    *        the HttpServletRequest
781    * @param arg
782    *        encoding name
783    * @see javax.servlet.http.HttpServletRequest#setCharacterEncoding(String)
784    * @since 2.3
785    */
786   public static void setCharacterEncoding(HttpServletRequest it, String arg) {
787     invoke(setCharacterEncoding, it, new Object[] { arg });
788   }
789 
790   /**
791    * @param it
792    *        the HttpServletRequest
793    * @return map of parameters
794    * @see javax.servlet.http.HttpServletRequest#getParameterMap()
795    * @since 2.3
796    */
797   @SuppressWarnings("unchecked")
798   public static Map getParameterMap(HttpServletRequest it) {
799     return (Map)invoke(getParameterMap, it, noargs);
800   }
801 
802 
803   // 
804   // ============================
805   // Servlet API 2.4 extensions
806   // ============================
807   // 
808 
809   /**
810    * @param it
811    *        the HttpServletRequest
812    * @return the remote address
813    * @see javax.servlet.http.HttpServletRequest#getRemotePort()
814    */
815   public static int getRemotePort(HttpServletRequest it) {
816     return ((Integer)invoke(getRemotePort, it, noargs)).intValue();
817   }
818 
819   /**
820    * @param it
821    *        the HttpServletRequest
822    * @return the receiving local port
823    * @see javax.servlet.http.HttpServletRequest#getLocalPort()
824    */
825   public static int getLocalPort(HttpServletRequest it) {
826     return ((Integer)invoke(getLocalPort, it, noargs)).intValue();
827   }
828 
829   /**
830    * @param it
831    *        the HttpServletRequest
832    * @return the local host name
833    * @see javax.servlet.http.HttpServletRequest#getLocalName()
834    */
835   public static String getLocalName(HttpServletRequest it) {
836     return (String)invoke(getLocalName, it, noargs);    
837   }
838 
839   /**
840    * @param it
841    *        the HttpServletRequest
842    * @return the receiving, local, IP address
843    * @see javax.servlet.http.HttpServletRequest#getLocalAddr()
844    */
845   public static String getLocalAddr(HttpServletRequest it) {
846     return (String)invoke(getLocalAddr, it, noargs);
847   }
848 
849 }