HttpServletRequestCompat.java

  1. /*
  2.  * $Source$
  3.  * $Revision$
  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. package org.melati.util;

  46. import java.util.Map;
  47. import java.util.Enumeration;
  48. import java.util.Locale;
  49. import javax.servlet.RequestDispatcher;
  50. import javax.servlet.http.HttpSession;
  51. import javax.servlet.http.HttpServletRequest;
  52. import javax.servlet.http.Cookie;
  53. import java.lang.reflect.Method;
  54. import java.lang.reflect.InvocationTargetException;

  55. /**
  56.  * NOTE This is no longer used, but it is so cool it is still around to marvel at
  57.  *
  58.  * The <code>HttpServletRequestCompat</code> class enables Melati to compile,
  59.  * without warnings, with the Servlet API versions 2.0 to 2.5.
  60.  *
  61.  * The core methods are those present in the 2.0 API all methods added since
  62.  * are established as static members.
  63.  * These are then available to be invoked if present or a RuntimeException is thrown
  64.  * otherwise.
  65.  *
  66.  * However, if you use a method which is not in your version of the API then you
  67.  * will get a runtime exception.
  68.  *
  69.  * @see org.melati.util.DelegatedHttpServletRequest
  70.  */

  71. public final class HttpServletRequestCompat {

  72.   private HttpServletRequestCompat() {
  73.   }

  74.   /** Deprecated in Servlet 2.1 API. */
  75.   private static Method isRequestedSessionIdFromUrl, getRealPath;

  76.   /** New in Servlet 2.2 API. */
  77.   private static Method getUserPrincipal, getContextPath, getHeaders,
  78.       getSession, isRequestedSessionIdFromURL, isUserInRole, getAttributeNames,
  79.       getLocale, getLocales, getRequestDispatcher, isSecure, removeAttribute,
  80.       setAttribute;
  81.   /** New in Servlet 2.3 API. */
  82.   private static Method getRequestURL, setCharacterEncoding, getParameterMap;
  83.   /** New in Servlet 2.4 API. */
  84.   private static Method getLocalAddr, getLocalName, getLocalPort, getRemotePort;
  85.  
  86.   private static Method methodOrNull(Class<?> c, String n, String[] pn) {
  87.     try {
  88.       Class<?>[] p = new Class[pn.length];
  89.       for (int i = 0; i < pn.length; ++i)
  90.         p[i] = Class.forName(pn[i]);
  91.       return c.getMethod(n, p);
  92.     } catch (NoSuchMethodException e) {
  93.       return null;
  94.     } catch (ClassNotFoundException e) {
  95.       return null;
  96.     }
  97.   }

  98.   static {
  99.     try {
  100.       String[] noparams = {};

  101.       Class<?> hsr = Class.forName("javax.servlet.http.HttpServletRequest");
  102.       getUserPrincipal = methodOrNull(hsr, "getUserPrincipal", noparams);
  103.       getContextPath = methodOrNull(hsr, "getContextPath", noparams);
  104.       getHeaders = methodOrNull(hsr, "getHeaders",
  105.           new String[] { "java.lang.String" });
  106.       getSession = methodOrNull(hsr, "getSession", noparams);
  107.       isRequestedSessionIdFromURL = methodOrNull(hsr,
  108.           "isRequestedSessionIdFromURL", noparams);
  109.       isUserInRole = methodOrNull(hsr, "isUserInRole",
  110.           new String[] { "java.lang.String" });
  111.       getAttributeNames = methodOrNull(hsr, "getAttributeNames", noparams);
  112.       getLocale = methodOrNull(hsr, "getLocale", noparams);
  113.       getLocales = methodOrNull(hsr, "getLocales", noparams);
  114.       getRequestDispatcher = methodOrNull(hsr, "getRequestDispatcher",
  115.           new String[] { "java.lang.String" });
  116.       isSecure = methodOrNull(hsr, "isSecure", noparams);
  117.       removeAttribute = methodOrNull(hsr, "removeAttribute",
  118.           new String[] { "java.lang.String" });
  119.       setAttribute = methodOrNull(hsr, "setAttribute", new String[] {
  120.           "java.lang.String", "java.lang.Object" });
  121.      
  122.       getLocalAddr = methodOrNull(hsr, "getLocalAddr", noparams);
  123.       getLocalName = methodOrNull(hsr, "getLocalName", noparams);
  124.       getLocalPort = methodOrNull(hsr, "getLocalPort", noparams);
  125.       getRemotePort = methodOrNull(hsr, "getRemotePort", noparams);
  126.      
  127.     } catch (Exception e) {
  128.       e.printStackTrace();
  129.       throw new Error("org.melati.util.servletcompat.HttpServletRequestCompat"
  130.           + "failed to initialize; contact the Melati developers");
  131.     }
  132.   }
  133.   //
  134.   // ================================
  135.   // Original Servlet API 2.0 methods
  136.   // ================================
  137.   //

  138.   /**
  139.    * Returns the name of the authentication scheme used to protect the servlet,
  140.    * for example, "BASIC" or "SSL," or <code>null</code> if the servlet was
  141.    * not protected. <p>Same as the value of the CGI variable AUTH_TYPE.
  142.    *
  143.    * @param it
  144.    *        the HttpServletRequest
  145.    * @return a <code>String</code> specifying the name of the authentication
  146.    *         scheme, or <code>null</code> if the request was not authenticated
  147.    * @see javax.servlet.http.HttpServletRequest#getAuthType()
  148.    * @since 2.0
  149.    */
  150.   public static String getAuthType(HttpServletRequest it) {
  151.     return it.getAuthType();
  152.   }

  153.   /**
  154.    * Returns an array containing all of the <code>Cookie</code> objects the
  155.    * client sent with this request. This method returns <code>null</code> if
  156.    * no cookies were sent.
  157.    *
  158.    * @param it
  159.    *        the HttpServletRequest
  160.    * @return an array of all the <code>Cookies</code> included with this
  161.    *         request, or <code>null</code> if the request has no cookies
  162.    * @see javax.servlet.http.HttpServletRequest#getCookies()
  163.    * @since 2.0
  164.    */
  165.   public static Cookie[] getCookies(HttpServletRequest it) {
  166.     return it.getCookies();
  167.   }

  168.   /**
  169.    * Returns the value of the specified request header as a <code>long</code>
  170.    * value that represents a <code>Date</code> object. Use this method with
  171.    * headers that contain dates, such as <code>If-Modified-Since</code>. <p>The
  172.    * date is returned as the number of milliseconds since January 1, 1970 GMT.
  173.    * The header name is case insensitive. <p>If the request did not have a
  174.    * header of the specified name, this method returns -1. If the header can't
  175.    * be converted to a date, the method throws an
  176.    * <code>IllegalArgumentException</code>.
  177.    *
  178.    * @param it
  179.    *        the HttpServletRequest
  180.    * @return a <code>long</code> value representing the date specified in the
  181.    *         header expressed as the number of milliseconds since January 1,
  182.    *         1970 GMT, or -1 if the named header was not included with the
  183.    *         request
  184.    * @see javax.servlet.http.HttpServletRequest#getDateHeader(String)
  185.    * @since 2.0
  186.    */
  187.   public static long getDateHeader(HttpServletRequest it, String a) {
  188.     return it.getDateHeader(a);
  189.   }

  190.   /**
  191.    * Returns the value of the specified request header as a <code>String</code>.
  192.    * If the request did not include a header of the specified name, this method
  193.    * returns <code>null</code>. The header name is case insensitive. You can
  194.    * use this method with any request header.
  195.    *
  196.    * @param it
  197.    *        the HttpServletRequest
  198.    * @return a <code>String</code> containing the value of the requested
  199.    *         header, or <code>null</code> if the request does not have a
  200.    *         header of that name
  201.    * @see javax.servlet.http.HttpServletRequest#getHeader(String)
  202.    * @since 2.0
  203.    */
  204.   public static String getHeader(HttpServletRequest it, String a) {
  205.     return it.getHeader(a);
  206.   }

  207.   /**
  208.    * Returns an enumeration of all the header names this request contains. If
  209.    * the request has no headers, this method returns an empty enumeration. <p>Some
  210.    * servlet containers do not allow do not allow servlets to access headers
  211.    * using this method, in which case this method returns <code>null</code>
  212.    *
  213.    * @param it
  214.    *        the HttpServletRequest
  215.    * @return an enumeration of all the header names sent with this request; if
  216.    *         the request has no headers, an empty enumeration; if the servlet
  217.    *         container does not allow servlets to use this method,
  218.    *         <code>null</code>
  219.    * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
  220.    * @since 2.0
  221.    */
  222.   @SuppressWarnings("unchecked")
  223.   public static Enumeration<String> getHeaderNames(HttpServletRequest it) {
  224.     return it.getHeaderNames();
  225.   }

  226.   /**
  227.    * Returns the value of the specified request header as an <code>int</code>.
  228.    * If the request does not have a header of the specified name, this method
  229.    * returns -1. If the header cannot be converted to an integer, this method
  230.    * throws a <code>NumberFormatException</code>. <p>The header name is case
  231.    * insensitive.
  232.    *
  233.    * @param it
  234.    *        the HttpServletRequest
  235.    * @return an integer expressing the value of the request header or -1 if the
  236.    *         request doesn't have a header of this name
  237.    * @see javax.servlet.http.HttpServletRequest#getIntHeader(String)
  238.    * @since 2.0
  239.    */
  240.   public static int getIntHeader(HttpServletRequest it, String a) {
  241.     return it.getIntHeader(a);
  242.   }

  243.   /**
  244.    * @param it the HttpServletRequest
  245.    * @return      a <code>String</code>
  246.    *        specifying the name
  247.    *        of the method with which
  248.    *        this request was made
  249.    * @see javax.servlet.http.HttpServletRequest#getMethod()
  250.    * @since 2.0
  251.    */
  252.   public static String getMethod(HttpServletRequest it) {
  253.     return it.getMethod();
  254.   }

  255.   /**
  256.    * @param it
  257.    *        the HttpServletRequest
  258.    * @return    a <code>String</code> specifying
  259.    *      extra path information that comes
  260.    *      after the servlet path but before
  261.    *      the query string in the request URL;
  262.    *      or <code>null</code> if the URL does not have
  263.    *      any extra path information
  264.    * @see javax.servlet.http.HttpServletRequest#getPathInfo()
  265.    * @since 2.0
  266.    */
  267.   public static String getPathInfo(HttpServletRequest it) {
  268.     return it.getPathInfo();
  269.   }

  270.   /**
  271.    * @param it
  272.    *        the HttpServletRequest
  273.    * @return    a <code>String</code> specifying the
  274.    *      real path, or <code>null</code> if
  275.    *      the URL does not have any extra path
  276.    *      information
  277.    * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
  278.    * @since 2.0
  279.    */
  280.   public static String getPathTranslated(HttpServletRequest it) {
  281.     return it.getPathTranslated();
  282.   }

  283.   /**
  284.    * @param it
  285.    *        the HttpServletRequest
  286.    * @return    a <code>String</code> containing the query
  287.    *      string or <code>null</code> if the URL
  288.    *      contains no query string
  289.    * @see javax.servlet.http.HttpServletRequest#getQueryString()
  290.    * @since 2.0
  291.    */
  292.   public static String getQueryString(HttpServletRequest it) {
  293.     return it.getQueryString();
  294.   }

  295.   /**
  296.    * @param it
  297.    *        the HttpServletRequest
  298.    * @return    a <code>String</code> specifying the login
  299.    *      of the user making this request, or <code>null</code>
  300.    *      if the user login is not known
  301.    * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
  302.    * @since 2.0
  303.    */
  304.   public static String getRemoteUser(HttpServletRequest it) {
  305.     return it.getRemoteUser();
  306.   }

  307.   /**
  308.    * @param it
  309.    *        the HttpServletRequest
  310.    * @return    a <code>String</code> containing
  311.    *      the part of the URL from the
  312.    *      protocol name up to the query string
  313.    * @see javax.servlet.http.HttpServletRequest#getRequestURI()
  314.    * @since 2.0
  315.    */
  316.   public static String getRequestURI(HttpServletRequest it) {
  317.     return it.getRequestURI();
  318.   }

  319.   /**
  320.    * @param it
  321.    *        the HttpServletRequest
  322.    * @return    a <code>String</code> specifying the session
  323.    *      ID, or <code>null</code> if the request did
  324.    *      not specify a session ID
  325.    * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
  326.    * @since 2.0
  327.    */
  328.   public static String getRequestedSessionId(HttpServletRequest it) {
  329.     return it.getRequestedSessionId();
  330.   }

  331.   /**
  332.    * @param it
  333.    *        the HttpServletRequest
  334.    * @return    a <code>String</code> containing
  335.    *      the name or path of the servlet being
  336.    *      called, as specified in the request URL
  337.    * @see javax.servlet.http.HttpServletRequest#getServletPath()
  338.    * @since 2.0
  339.    */
  340.   public static String getServletPath(HttpServletRequest it) {
  341.     return it.getServletPath();
  342.   }

  343.   /**
  344.    * @param it
  345.    *        the HttpServletRequest
  346.    * @param a
  347.    * @return    the <code>HttpSession</code> associated
  348.    *      with this request
  349.    * @see javax.servlet.http.HttpServletRequest#getSession()
  350.    * @since 2.0
  351.    */
  352.   public static HttpSession getSession(HttpServletRequest it, boolean a) {
  353.     return it.getSession(a);
  354.   }

  355.   /**
  356.    * @param it
  357.    *        the HttpServletRequest
  358.    * @return      <code>true</code> if this
  359.    *        request has an id for a valid session
  360.    *        in the current session context;
  361.    *        <code>false</code> otherwise
  362.    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
  363.    * @since 2.0
  364.    */
  365.   public static boolean isRequestedSessionIdValid(HttpServletRequest it) {
  366.     return it.isRequestedSessionIdValid();
  367.   }

  368.   /**
  369.    * @param it
  370.    *        the HttpServletRequest
  371.    * @return      <code>true</code> if the session ID
  372.    *        came in as a
  373.    *        cookie; otherwise, <code>false</code>
  374.    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
  375.    * @since 2.0
  376.    */
  377.   public static boolean isRequestedSessionIdFromCookie(HttpServletRequest it) {
  378.     return it.isRequestedSessionIdFromCookie();
  379.   }
  380.  
  381.   //======================
  382.   // Invocation machinery
  383.   //======================
  384.  
  385.   /**
  386.    * Thrown when a method that is not available is invoked.
  387.    */
  388.   public static class MissingMethodError extends NoSuchMethodError {
  389.     private static final long serialVersionUID = 1L;

  390.     /**
  391.      * {@inheritDoc}
  392.      *
  393.      * @see java.lang.Throwable#getMessage()
  394.      */
  395.     public String getMessage() {
  396.       return "The application tried to use a method from the "
  397.           + "Servlet API which is not present in the version it running against.";
  398.     }
  399.   }

  400.   private static Object invoke(Method method, HttpServletRequest it,
  401.       Object[] args) {
  402.     if (method == null)
  403.       throw new MissingMethodError();
  404.     else {
  405.       try {
  406.         return method.invoke(it, args);
  407.       } catch (InvocationTargetException e) {
  408.         Throwable f = e.getTargetException();
  409.         if (f instanceof RuntimeException) // they all should be
  410.           throw (RuntimeException)f;
  411.         else if (f instanceof Exception)
  412.           throw new RuntimeException("while invoking a Servlet API method",
  413.                                      f);
  414.         else if (f instanceof Error)
  415.           throw (Error)f;
  416.         else {
  417.           f.printStackTrace();
  418.           throw new Error("totally unexpected kind of throwable in "
  419.               + "org.melati.util.servletcompat.HttpServletRequestCompat");
  420.         }
  421.       } catch (IllegalAccessException e) {
  422.         e.printStackTrace();
  423.         throw new Error(
  424.                         "org.melati.util.servletcompat.HttpServletRequestCompat"
  425.                             + "got an unexpected IllegalAccessException trying to "
  426.                             + "invoke a method; contact the Melati developers");
  427.       }
  428.     }
  429.   }

  430.   private static final Object[] noargs = {};

  431.   //
  432.   // ============================
  433.   // Servlet API 2.1 deprecatons
  434.   // ============================
  435.   //

  436.   /**
  437.    * @param it
  438.    *        the HttpServletRequest
  439.    * @param arg
  440.    *        url String
  441.    * @return the real path
  442.    * @deprecated Servlet API 2.1
  443.    * @see javax.servlet.ServletRequest#getRealPath(String)
  444.    * @since 2.0
  445.    */
  446.   public static String getRealPath(HttpServletRequest it, String arg) {
  447.     return (String)invoke(getRealPath, it, new Object[] { arg });
  448.   }

  449.   /**
  450.    * @param it
  451.    *        the HttpServletRequest
  452.    * @return whether id is from url
  453.    * @deprecated Servlet API 2.1
  454.    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
  455.    * @since 2.0
  456.    */
  457.   public static boolean isRequestedSessionIdFromUrl(HttpServletRequest it) {
  458.     return ((Boolean)invoke(isRequestedSessionIdFromUrl, it, noargs))
  459.         .booleanValue();
  460.   }

  461.   //
  462.   // ============================
  463.   // Servlet API 2.1 extensions
  464.   // ============================
  465.   //

  466.   /**
  467.    * Returns the empty string when run against 2.0 API.
  468.    *
  469.    * @param it
  470.    *        the HttpServletRequest
  471.    * @return the Context path or empty string
  472.    * @see javax.servlet.http.HttpServletRequest#getContextPath()
  473.    * @since 2.1
  474.    */
  475.   public static String getContextPath(HttpServletRequest it) {
  476.     if (getContextPath == null)
  477.       return "";
  478.     else
  479.       return (String)invoke(getContextPath, it, noargs);
  480.   }

  481.   /**
  482.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
  483.    *
  484.    * @param it
  485.    *        the HttpServletRequest
  486.    * @return    a <code>java.security.Principal</code> containing
  487.    *      the name of the user making this request;
  488.    *      <code>null</code> if the user has not been
  489.    *      authenticated
  490.    * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
  491.    * @since 2.1
  492.    */
  493.   public static java.security.Principal getUserPrincipal(HttpServletRequest it) {
  494.     return (java.security.Principal)invoke(getUserPrincipal, it, noargs);
  495.   }

  496.   /**
  497.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
  498.    *
  499.    * @param it
  500.    *        the HttpServletRequest
  501.    * @param arg
  502.    * @return      a <code>Enumeration</code> containing the
  503.    *        values of the requested
  504.    *        header, or <code>null</code>
  505.    *        if the request does not
  506.    *        have any headers of that name
  507.    * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
  508.    * @since 2.1
  509.    */
  510.   @SuppressWarnings("unchecked")
  511.   public static Enumeration<String> getHeaders(HttpServletRequest it, String arg) {
  512.     return (Enumeration<String>)invoke(getHeaders, it, new Object[] { arg });
  513.   }

  514.   /**
  515.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API,
  516.    * introduced in 2.1.
  517.    *
  518.    * @param it
  519.    *        the HttpServletRequest
  520.    * @return    the <code>HttpSession</code> associated
  521.    *      with this request
  522.    * @see javax.servlet.http.HttpServletRequest#getSession()
  523.    * @since 2.1
  524.    */
  525.   public static HttpSession getSession(HttpServletRequest it) {
  526.     return (HttpSession)invoke(getSession, it, noargs);
  527.   }

  528.   /**
  529.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API,
  530.    * introduced in 2.1.
  531.    *
  532.    * @param it
  533.    *        the HttpServletRequest
  534.    * @return      <code>true</code> if the session ID
  535.    *        came in as part of a URL; otherwise,
  536.    *        <code>false</code>
  537.    * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
  538.    * @since 2.1
  539.    */
  540.   public static boolean isRequestedSessionIdFromURL(HttpServletRequest it) {
  541.     return ((Boolean)invoke(isRequestedSessionIdFromURL, it, noargs))
  542.         .booleanValue();
  543.   }

  544.   //
  545.   // ============================
  546.   // Servlet API 2.2 extensions
  547.   // ============================
  548.   //

  549.   /**
  550.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API.
  551.    *
  552.    * @param it
  553.    *        the HttpServletRequest
  554.    * @param arg
  555.    * @return    a <code>boolean</code> indicating whether
  556.    *      the user making this request belongs to a given role;
  557.    *      <code>false</code> if the user has not been
  558.    *      authenticated
  559.    * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
  560.    * @since 2.2
  561.    */
  562.   public static boolean isUserInRole(HttpServletRequest it, String arg) {
  563.     return ((Boolean)invoke(isUserInRole, it, new Object[] { arg }))
  564.         .booleanValue();
  565.   }

  566.   /**
  567.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns an
  568.    * <code>Enumeration</code> containing the names of the attributes available
  569.    * to this request. This method returns an empty <code>Enumeration</code> if
  570.    * the request has no attributes available to it.
  571.    *
  572.    * @param it
  573.    *        the HttpServletRequest
  574.    * @return an <code>Enumeration</code> of strings containing the names of
  575.    *         the request's attributes
  576.    * @see javax.servlet.http.HttpServletRequest#getAttributeNames()
  577.    * @since 2.2
  578.    */
  579.   @SuppressWarnings("unchecked")
  580. public static Enumeration<String> getAttributeNames(HttpServletRequest it) {
  581.     return (Enumeration<String>)invoke(getAttributeNames, it, noargs);
  582.   }

  583.   /**
  584.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns the
  585.    * preferred <code>Locale</code> that the client will accept content in,
  586.    * based on the Accept-Language header. If the client request doesn't provide
  587.    * an Accept-Language header, this method returns the default locale for the
  588.    * server.
  589.    *
  590.    * @param it
  591.    *        the HttpServletRequest
  592.    * @return the preferred <code>Locale</code> for the client
  593.    * @see javax.servlet.http.HttpServletRequest#getLocale()
  594.    * @since 2.2
  595.    */
  596.   public static Locale getLocale(HttpServletRequest it) {
  597.     return (Locale)invoke(getLocale, it, noargs);
  598.   }

  599.   /**
  600.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns an
  601.    * <code>Enumeration</code> of <code>Locale</code> objects indicating, in
  602.    * decreasing order starting with the preferred locale, the locales that are
  603.    * acceptable to the client based on the Accept-Language header. If the client
  604.    * request doesn't provide an Accept-Language header, this method returns an
  605.    * <code>Enumeration</code> containing one <code>Locale</code>, the
  606.    * default locale for the server.
  607.    *
  608.    * @param it
  609.    *        the HttpServletRequest
  610.    * @return an <code>Enumeration</code> of preferred <code>Locale</code>
  611.    *         objects for the client
  612.    * @see javax.servlet.http.HttpServletRequest#getLocales()
  613.    * @since 2.2
  614.    */
  615.   @SuppressWarnings("unchecked")
  616.   public static Enumeration<String> getLocales(HttpServletRequest it) {
  617.     return (Enumeration<String>)invoke(getLocales, it, noargs);
  618.   }

  619.   /**
  620.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. If you get
  621.    * compile errors for this method, it's probably because (a) you are compiling
  622.    * against the 2.0 servlet API.
  623.    *
  624.    * Returns a {@link RequestDispatcher} object that acts as a wrapper for the
  625.    * resource located at the given path. A <code>RequestDispatcher</code>
  626.    * object can be used to forward a request to the resource or to include the
  627.    * resource in a response. The resource can be dynamic or static.
  628.    *
  629.    * The
  630.    * pathname specified may be relative, although it cannot extend outside the
  631.    * current servlet context. If the path begins with a "/" it is interpreted as
  632.    * relative to the current context root. This method returns <code>null</code>
  633.    * if the servlet container cannot return a <code>RequestDispatcher</code>.
  634.    *
  635.    * The difference between this method and
  636.    * {@link javax.servlet.ServletContext#getRequestDispatcher} is that this method can take a
  637.    * relative path.
  638.    *
  639.    * @param it
  640.    *        the HttpServletRequest
  641.    * @param arg
  642.    *        a <code>String</code> specifying the pathname to the resource
  643.    * @return a <code>RequestDispatcher</code> object that acts as a wrapper
  644.    *         for the resource at the specified path
  645.    * @see RequestDispatcher
  646.    * @see javax.servlet.http.HttpServletRequest#getRequestDispatcher(String)
  647.    * @since 2.2
  648.    */
  649.   public static RequestDispatcher getRequestDispatcher(HttpServletRequest it,
  650.       String arg) {
  651.     return (RequestDispatcher)invoke(getRequestDispatcher, it,
  652.         new Object[] { arg });
  653.   }

  654.   /**
  655.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Returns a
  656.    * boolean indicating whether this request was made using a secure channel,
  657.    * such as HTTPS.
  658.    *
  659.    * @param it
  660.    *        the HttpServletRequest
  661.    * @return a boolean indicating if the request was made using a secure channel
  662.    * @see javax.servlet.http.HttpServletRequest#isSecure()
  663.    * @since 2.2
  664.    */
  665.   public static boolean isSecure(HttpServletRequest it) {
  666.     return ((Boolean)invoke(isSecure, it, noargs)).booleanValue();
  667.   }

  668.   /**
  669.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Removes an
  670.    * attribute from this request. This method is not generally needed as
  671.    * attributes only persist as long as the request is being handled. <p>Attribute
  672.    * names should follow the same conventions as package names. Names beginning
  673.    * with <code>java.*</code>, <code>javax.*</code>, and
  674.    * <code>com.sun.*</code>, are reserved for use by Sun Microsystems.
  675.    *
  676.    * @param it
  677.    *        the HttpServletRequest
  678.    * @param arg
  679.    *        a <code>String</code> specifying the name of the attribute to
  680.    *        remove
  681.    * @see javax.servlet.http.HttpServletRequest#removeAttribute
  682.    * @since 2.2
  683.    */
  684.   public static void removeAttribute(HttpServletRequest it, String arg) {
  685.     invoke(removeAttribute, it, new Object[] { arg });
  686.   }

  687.   /**
  688.    * Throws <TT>MissingMethodError</TT> when run against 2.0 API. Stores an
  689.    * attribute in this request. Attributes are reset between requests. This
  690.    * method is most often used in conjunction with {@link RequestDispatcher}.
  691.    * <p>Attribute names should follow the same conventions as package names.
  692.    * Names beginning with <code>java.*</code>, <code>javax.*</code>, and
  693.    * <code>com.sun.*</code>, are reserved for use by Sun Microsystems.
  694.    *
  695.    * @param it
  696.    *        the HttpServletRequest
  697.    * @param arg1
  698.    *        a <code>String</code> specifying the name of the attribute
  699.    * @param arg2
  700.    *        the <code>Object</code> to be stored
  701.    * @see javax.servlet.http.HttpServletRequest#setAttribute
  702.    * @since 2.2
  703.    */
  704.   public static void setAttribute(HttpServletRequest it, String arg1,
  705.       Object arg2) {
  706.     invoke(setAttribute, it, new Object[] { arg1, arg2 });
  707.   }

  708.   //
  709.   // ============================
  710.   // Servlet API 2.3 extensions
  711.   // ============================
  712.   //

  713.   /**
  714.    * Throws <TT>MissingMethodError</TT> when run against 2.2 API.
  715.    *
  716.    * @param it
  717.    *        the HttpServletRequest
  718.    * @return request url as a String buffer
  719.    * @see javax.servlet.http.HttpServletRequest#getRequestURL()
  720.    * @since 2.3
  721.    */
  722.   public static StringBuffer getRequestURL(HttpServletRequest it) {
  723.     return (StringBuffer)invoke(getRequestURL, it, noargs);
  724.   }

  725.   /**
  726.    * Throws <TT>MissingMethodError</TT> when run against 2.2 API.
  727.    *
  728.    * @param it
  729.    *        the HttpServletRequest
  730.    * @param arg
  731.    *        encoding name
  732.    * @see javax.servlet.http.HttpServletRequest#setCharacterEncoding(String)
  733.    * @since 2.3
  734.    */
  735.   public static void setCharacterEncoding(HttpServletRequest it, String arg) {
  736.     invoke(setCharacterEncoding, it, new Object[] { arg });
  737.   }

  738.   /**
  739.    * @param it
  740.    *        the HttpServletRequest
  741.    * @return map of parameters
  742.    * @see javax.servlet.http.HttpServletRequest#getParameterMap()
  743.    * @since 2.3
  744.    */
  745.   @SuppressWarnings("unchecked")
  746.   public static Map<String, String[]> getParameterMap(HttpServletRequest it) {
  747.     return (Map<String, String[]>)invoke(getParameterMap, it, noargs);
  748.   }


  749.   //
  750.   // ============================
  751.   // Servlet API 2.4 extensions
  752.   // ============================
  753.   //

  754.   /**
  755.    * @param it
  756.    *        the HttpServletRequest
  757.    * @return the remote address
  758.    * @see javax.servlet.http.HttpServletRequest#getRemotePort()
  759.    */
  760.   public static int getRemotePort(HttpServletRequest it) {
  761.     return ((Integer)invoke(getRemotePort, it, noargs)).intValue();
  762.   }

  763.   /**
  764.    * @param it
  765.    *        the HttpServletRequest
  766.    * @return the receiving local port
  767.    * @see javax.servlet.http.HttpServletRequest#getLocalPort()
  768.    */
  769.   public static int getLocalPort(HttpServletRequest it) {
  770.     return ((Integer)invoke(getLocalPort, it, noargs)).intValue();
  771.   }

  772.   /**
  773.    * @param it
  774.    *        the HttpServletRequest
  775.    * @return the local host name
  776.    * @see javax.servlet.http.HttpServletRequest#getLocalName()
  777.    */
  778.   public static String getLocalName(HttpServletRequest it) {
  779.     return (String)invoke(getLocalName, it, noargs);    
  780.   }

  781.   /**
  782.    * @param it
  783.    *        the HttpServletRequest
  784.    * @return the receiving, local, IP address
  785.    * @see javax.servlet.http.HttpServletRequest#getLocalAddr()
  786.    */
  787.   public static String getLocalAddr(HttpServletRequest it) {
  788.     return (String)invoke(getLocalAddr, it, noargs);
  789.   }

  790. }