Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » core » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   
   19   package org.apache.catalina.core;
   20   
   21   
   22   import java.io.IOException;
   23   import java.util.ArrayList;
   24   import java.util.Enumeration;
   25   import java.util.HashMap;
   26   import java.util.Iterator;
   27   import java.util.Map;
   28   import java.util.NoSuchElementException;
   29   
   30   import javax.servlet.RequestDispatcher;
   31   import javax.servlet.http.HttpServletRequest;
   32   import javax.servlet.http.HttpServletRequestWrapper;
   33   import javax.servlet.http.HttpSession;
   34   
   35   import org.apache.catalina.Context;
   36   import org.apache.catalina.Globals;
   37   import org.apache.catalina.Session;
   38   import org.apache.catalina.Manager;
   39   import org.apache.catalina.util.Enumerator;
   40   import org.apache.catalina.util.RequestUtil;
   41   import org.apache.catalina.util.StringManager;
   42   
   43   
   44   /**
   45    * Wrapper around a <code>javax.servlet.http.HttpServletRequest</code>
   46    * that transforms an application request object (which might be the original
   47    * one passed to a servlet, or might be based on the 2.3
   48    * <code>javax.servlet.http.HttpServletRequestWrapper</code> class)
   49    * back into an internal <code>org.apache.catalina.HttpRequest</code>.
   50    * <p>
   51    * <strong>WARNING</strong>:  Due to Java's lack of support for multiple
   52    * inheritance, all of the logic in <code>ApplicationRequest</code> is
   53    * duplicated in <code>ApplicationHttpRequest</code>.  Make sure that you
   54    * keep these two classes in synchronization when making changes!
   55    *
   56    * @author Craig R. McClanahan
   57    * @author Remy Maucherat
   58    * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
   59    */
   60   
   61   class ApplicationHttpRequest extends HttpServletRequestWrapper {
   62   
   63   
   64       // ------------------------------------------------------- Static Variables
   65   
   66   
   67       /**
   68        * The set of attribute names that are special for request dispatchers.
   69        */
   70       protected static final String specials[] =
   71       { Globals.INCLUDE_REQUEST_URI_ATTR, Globals.INCLUDE_CONTEXT_PATH_ATTR,
   72         Globals.INCLUDE_SERVLET_PATH_ATTR, Globals.INCLUDE_PATH_INFO_ATTR,
   73         Globals.INCLUDE_QUERY_STRING_ATTR, Globals.FORWARD_REQUEST_URI_ATTR, 
   74         Globals.FORWARD_CONTEXT_PATH_ATTR, Globals.FORWARD_SERVLET_PATH_ATTR, 
   75         Globals.FORWARD_PATH_INFO_ATTR, Globals.FORWARD_QUERY_STRING_ATTR };
   76   
   77   
   78       /**
   79        * The string manager for this package.
   80        */
   81       protected static StringManager sm =
   82           StringManager.getManager(Constants.Package);
   83   
   84   
   85       // ----------------------------------------------------------- Constructors
   86   
   87   
   88       /**
   89        * Construct a new wrapped request around the specified servlet request.
   90        *
   91        * @param request The servlet request being wrapped
   92        */
   93       public ApplicationHttpRequest(HttpServletRequest request, Context context,
   94                                     boolean crossContext) {
   95   
   96           super(request);
   97           this.context = context;
   98           this.crossContext = crossContext;
   99           setRequest(request);
  100   
  101       }
  102   
  103   
  104       // ----------------------------------------------------- Instance Variables
  105   
  106   
  107       /**
  108        * The context for this request.
  109        */
  110       protected Context context = null;
  111   
  112   
  113       /**
  114        * The context path for this request.
  115        */
  116       protected String contextPath = null;
  117   
  118   
  119       /**
  120        * If this request is cross context, since this changes session accesss
  121        * behavior.
  122        */
  123       protected boolean crossContext = false;
  124   
  125   
  126       /**
  127        * The current dispatcher type.
  128        */
  129       protected Object dispatcherType = null;
  130   
  131   
  132       /**
  133        * Descriptive information about this implementation.
  134        */
  135       protected static final String info =
  136           "org.apache.catalina.core.ApplicationHttpRequest/1.0";
  137   
  138   
  139       /**
  140        * The request parameters for this request.  This is initialized from the
  141        * wrapped request, but updates are allowed.
  142        */
  143       protected Map parameters = null;
  144   
  145   
  146       /**
  147        * Have the parameters for this request already been parsed?
  148        */
  149       private boolean parsedParams = false;
  150   
  151   
  152       /**
  153        * The path information for this request.
  154        */
  155       protected String pathInfo = null;
  156   
  157   
  158       /**
  159        * The query parameters for the current request.
  160        */
  161       private String queryParamString = null;
  162   
  163   
  164       /**
  165        * The query string for this request.
  166        */
  167       protected String queryString = null;
  168   
  169   
  170       /**
  171        * The current request dispatcher path.
  172        */
  173       protected Object requestDispatcherPath = null;
  174   
  175   
  176       /**
  177        * The request URI for this request.
  178        */
  179       protected String requestURI = null;
  180   
  181   
  182       /**
  183        * The servlet path for this request.
  184        */
  185       protected String servletPath = null;
  186   
  187   
  188       /**
  189        * The currently active session for this request.
  190        */
  191       protected Session session = null;
  192   
  193   
  194       /**
  195        * Special attributes.
  196        */
  197       protected Object[] specialAttributes = new Object[specials.length];
  198   
  199   
  200       // ------------------------------------------------- ServletRequest Methods
  201   
  202   
  203       /**
  204        * Override the <code>getAttribute()</code> method of the wrapped request.
  205        *
  206        * @param name Name of the attribute to retrieve
  207        */
  208       public Object getAttribute(String name) {
  209   
  210           if (name.equals(Globals.DISPATCHER_TYPE_ATTR)) {
  211               return dispatcherType;
  212           } else if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
  213               if ( requestDispatcherPath != null ){
  214                   return requestDispatcherPath.toString();
  215               } else {
  216                   return null;   
  217               }
  218           }
  219   
  220           int pos = getSpecial(name);
  221           if (pos == -1) {
  222               return getRequest().getAttribute(name);
  223           } else {
  224               if ((specialAttributes[pos] == null) 
  225                   && (specialAttributes[5] == null) && (pos >= 5)) {
  226                   // If it's a forward special attribute, and null, it means this
  227                   // is an include, so we check the wrapped request since 
  228                   // the request could have been forwarded before the include
  229                   return getRequest().getAttribute(name);
  230               } else {
  231                   return specialAttributes[pos];
  232               }
  233           }
  234   
  235       }
  236   
  237   
  238       /**
  239        * Override the <code>getAttributeNames()</code> method of the wrapped
  240        * request.
  241        */
  242       public Enumeration getAttributeNames() {
  243           return (new AttributeNamesEnumerator());
  244       }
  245   
  246   
  247       /**
  248        * Override the <code>removeAttribute()</code> method of the
  249        * wrapped request.
  250        *
  251        * @param name Name of the attribute to remove
  252        */
  253       public void removeAttribute(String name) {
  254   
  255           if (!removeSpecial(name))
  256               getRequest().removeAttribute(name);
  257   
  258       }
  259   
  260   
  261       /**
  262        * Override the <code>setAttribute()</code> method of the
  263        * wrapped request.
  264        *
  265        * @param name Name of the attribute to set
  266        * @param value Value of the attribute to set
  267        */
  268       public void setAttribute(String name, Object value) {
  269   
  270           if (name.equals(Globals.DISPATCHER_TYPE_ATTR)) {
  271               dispatcherType = value;
  272               return;
  273           } else if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
  274               requestDispatcherPath = value;
  275               return;
  276           }
  277   
  278           if (!setSpecial(name, value)) {
  279               getRequest().setAttribute(name, value);
  280           }
  281   
  282       }
  283   
  284   
  285       /**
  286        * Return a RequestDispatcher that wraps the resource at the specified
  287        * path, which may be interpreted as relative to the current request path.
  288        *
  289        * @param path Path of the resource to be wrapped
  290        */
  291       public RequestDispatcher getRequestDispatcher(String path) {
  292   
  293           if (context == null)
  294               return (null);
  295   
  296           // If the path is already context-relative, just pass it through
  297           if (path == null)
  298               return (null);
  299           else if (path.startsWith("/"))
  300               return (context.getServletContext().getRequestDispatcher(path));
  301   
  302           // Convert a request-relative path to a context-relative one
  303           String servletPath = 
  304               (String) getAttribute(Globals.INCLUDE_SERVLET_PATH_ATTR);
  305           if (servletPath == null)
  306               servletPath = getServletPath();
  307   
  308           // Add the path info, if there is any
  309           String pathInfo = getPathInfo();
  310           String requestPath = null;
  311   
  312           if (pathInfo == null) {
  313               requestPath = servletPath;
  314           } else {
  315               requestPath = servletPath + pathInfo;
  316           }
  317   
  318           int pos = requestPath.lastIndexOf('/');
  319           String relative = null;
  320           if (pos >= 0) {
  321               relative = RequestUtil.normalize
  322                   (requestPath.substring(0, pos + 1) + path);
  323           } else {
  324               relative = RequestUtil.normalize(requestPath + path);
  325           }
  326   
  327           return (context.getServletContext().getRequestDispatcher(relative));
  328   
  329       }
  330   
  331   
  332       // --------------------------------------------- HttpServletRequest Methods
  333   
  334   
  335       /**
  336        * Override the <code>getContextPath()</code> method of the wrapped
  337        * request.
  338        */
  339       public String getContextPath() {
  340   
  341           return (this.contextPath);
  342   
  343       }
  344   
  345   
  346       /**
  347        * Override the <code>getParameter()</code> method of the wrapped request.
  348        *
  349        * @param name Name of the requested parameter
  350        */
  351       public String getParameter(String name) {
  352   
  353   	parseParameters();
  354   
  355           Object value = parameters.get(name);
  356           if (value == null)
  357               return (null);
  358           else if (value instanceof String[])
  359               return (((String[]) value)[0]);
  360           else if (value instanceof String)
  361               return ((String) value);
  362           else
  363               return (value.toString());
  364   
  365       }
  366   
  367   
  368       /**
  369        * Override the <code>getParameterMap()</code> method of the
  370        * wrapped request.
  371        */
  372       public Map getParameterMap() {
  373   
  374   	parseParameters();
  375           return (parameters);
  376   
  377       }
  378   
  379   
  380       /**
  381        * Override the <code>getParameterNames()</code> method of the
  382        * wrapped request.
  383        */
  384       public Enumeration getParameterNames() {
  385   
  386   	parseParameters();
  387           return (new Enumerator(parameters.keySet()));
  388   
  389       }
  390   
  391   
  392       /**
  393        * Override the <code>getParameterValues()</code> method of the
  394        * wrapped request.
  395        *
  396        * @param name Name of the requested parameter
  397        */
  398       public String[] getParameterValues(String name) {
  399   
  400   	parseParameters();
  401           Object value = parameters.get(name);
  402           if (value == null)
  403               return ((String[]) null);
  404           else if (value instanceof String[])
  405               return ((String[]) value);
  406           else if (value instanceof String) {
  407               String values[] = new String[1];
  408               values[0] = (String) value;
  409               return (values);
  410           } else {
  411               String values[] = new String[1];
  412               values[0] = value.toString();
  413               return (values);
  414           }
  415   
  416       }
  417   
  418   
  419       /**
  420        * Override the <code>getPathInfo()</code> method of the wrapped request.
  421        */
  422       public String getPathInfo() {
  423   
  424           return (this.pathInfo);
  425   
  426       }
  427   
  428   
  429       /**
  430        * Override the <code>getQueryString()</code> method of the wrapped
  431        * request.
  432        */
  433       public String getQueryString() {
  434   
  435           return (this.queryString);
  436   
  437       }
  438   
  439   
  440       /**
  441        * Override the <code>getRequestURI()</code> method of the wrapped
  442        * request.
  443        */
  444       public String getRequestURI() {
  445   
  446           return (this.requestURI);
  447   
  448       }
  449   
  450   
  451       /**
  452        * Override the <code>getRequestURL()</code> method of the wrapped
  453        * request.
  454        */
  455       public StringBuffer getRequestURL() {
  456   
  457           StringBuffer url = new StringBuffer();
  458           String scheme = getScheme();
  459           int port = getServerPort();
  460           if (port < 0)
  461               port = 80; // Work around java.net.URL bug
  462   
  463           url.append(scheme);
  464           url.append("://");
  465           url.append(getServerName());
  466           if ((scheme.equals("http") && (port != 80))
  467               || (scheme.equals("https") && (port != 443))) {
  468               url.append(':');
  469               url.append(port);
  470           }
  471           url.append(getRequestURI());
  472   
  473           return (url);
  474   
  475       }
  476   
  477   
  478       /**
  479        * Override the <code>getServletPath()</code> method of the wrapped
  480        * request.
  481        */
  482       public String getServletPath() {
  483   
  484           return (this.servletPath);
  485   
  486       }
  487   
  488   
  489       /**
  490        * Return the session associated with this Request, creating one
  491        * if necessary.
  492        */
  493       public HttpSession getSession() {
  494           return (getSession(true));
  495       }
  496   
  497   
  498       /**
  499        * Return the session associated with this Request, creating one
  500        * if necessary and requested.
  501        *
  502        * @param create Create a new session if one does not exist
  503        */
  504       public HttpSession getSession(boolean create) {
  505   
  506           if (crossContext) {
  507               
  508               // There cannot be a session if no context has been assigned yet
  509               if (context == null)
  510                   return (null);
  511   
  512               // Return the current session if it exists and is valid
  513               if (session != null && session.isValid()) {
  514                   return (session.getSession());
  515               }
  516   
  517               HttpSession other = super.getSession(false);
  518               if (create && (other == null)) {
  519                   // First create a session in the first context: the problem is
  520                   // that the top level request is the only one which can 
  521                   // create the cookie safely
  522                   other = super.getSession(true);
  523               }
  524               if (other != null) {
  525                   Session localSession = null;
  526                   try {
  527                       localSession =
  528                           context.getManager().findSession(other.getId());
  529                   } catch (IOException e) {
  530                       // Ignore
  531                   }
  532                   if (localSession == null && create) {
  533                       localSession = 
  534                           context.getManager().createSession(other.getId());
  535                   }
  536                   if (localSession != null) {
  537                       localSession.access();
  538                       session = localSession;
  539                       return session.getSession();
  540                   }
  541               }
  542               return null;
  543   
  544           } else {
  545               return super.getSession(create);
  546           }
  547   
  548       }
  549   
  550   
  551       /**
  552        * Returns true if the request specifies a JSESSIONID that is valid within
  553        * the context of this ApplicationHttpRequest, false otherwise.
  554        *
  555        * @return true if the request specifies a JSESSIONID that is valid within
  556        * the context of this ApplicationHttpRequest, false otherwise.
  557        */
  558       public boolean isRequestedSessionIdValid() {
  559   
  560           if (crossContext) {
  561   
  562               String requestedSessionId = getRequestedSessionId();
  563               if (requestedSessionId == null)
  564                   return (false);
  565               if (context == null)
  566                   return (false);
  567               Manager manager = context.getManager();
  568               if (manager == null)
  569                   return (false);
  570               Session session = null;
  571               try {
  572                   session = manager.findSession(requestedSessionId);
  573               } catch (IOException e) {
  574                   session = null;
  575               }
  576               if ((session != null) && session.isValid()) {
  577                   return (true);
  578               } else {
  579                   return (false);
  580               }
  581   
  582           } else {
  583               return super.isRequestedSessionIdValid();
  584           }
  585       }
  586   
  587   
  588       // -------------------------------------------------------- Package Methods
  589   
  590   
  591       /**
  592        * Recycle this request
  593        */
  594       public void recycle() {
  595           if (session != null) {
  596               session.endAccess();
  597           }
  598       }
  599   
  600   
  601       /**
  602        * Return descriptive information about this implementation.
  603        */
  604       public String getInfo() {
  605   
  606           return (info);
  607   
  608       }
  609   
  610   
  611       /**
  612        * Perform a shallow copy of the specified Map, and return the result.
  613        *
  614        * @param orig Origin Map to be copied
  615        */
  616       Map copyMap(Map orig) {
  617   
  618           if (orig == null)
  619               return (new HashMap());
  620           HashMap dest = new HashMap();
  621           Iterator keys = orig.keySet().iterator();
  622           while (keys.hasNext()) {
  623               String key = (String) keys.next();
  624               dest.put(key, orig.get(key));
  625           }
  626           return (dest);
  627   
  628       }
  629   
  630   
  631       /**
  632        * Set the context path for this request.
  633        *
  634        * @param contextPath The new context path
  635        */
  636       void setContextPath(String contextPath) {
  637   
  638           this.contextPath = contextPath;
  639   
  640       }
  641   
  642   
  643       /**
  644        * Set the path information for this request.
  645        *
  646        * @param pathInfo The new path info
  647        */
  648       void setPathInfo(String pathInfo) {
  649   
  650           this.pathInfo = pathInfo;
  651   
  652       }
  653   
  654   
  655       /**
  656        * Set the query string for this request.
  657        *
  658        * @param queryString The new query string
  659        */
  660       void setQueryString(String queryString) {
  661   
  662           this.queryString = queryString;
  663   
  664       }
  665   
  666   
  667       /**
  668        * Set the request that we are wrapping.
  669        *
  670        * @param request The new wrapped request
  671        */
  672       void setRequest(HttpServletRequest request) {
  673   
  674           super.setRequest(request);
  675   
  676           // Initialize the attributes for this request
  677           dispatcherType = request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
  678           requestDispatcherPath = 
  679               request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
  680   
  681           // Initialize the path elements for this request
  682           contextPath = request.getContextPath();
  683           pathInfo = request.getPathInfo();
  684           queryString = request.getQueryString();
  685           requestURI = request.getRequestURI();
  686           servletPath = request.getServletPath();
  687   
  688       }
  689   
  690   
  691       /**
  692        * Set the request URI for this request.
  693        *
  694        * @param requestURI The new request URI
  695        */
  696       void setRequestURI(String requestURI) {
  697   
  698           this.requestURI = requestURI;
  699   
  700       }
  701   
  702   
  703       /**
  704        * Set the servlet path for this request.
  705        *
  706        * @param servletPath The new servlet path
  707        */
  708       void setServletPath(String servletPath) {
  709   
  710           this.servletPath = servletPath;
  711   
  712       }
  713   
  714   
  715       /**
  716        * Parses the parameters of this request.
  717        *
  718        * If parameters are present in both the query string and the request
  719        * content, they are merged.
  720        */
  721       void parseParameters() {
  722   
  723   	if (parsedParams) {
  724   	    return;
  725   	}
  726   
  727           parameters = new HashMap();
  728           parameters = copyMap(getRequest().getParameterMap());
  729           mergeParameters();
  730           parsedParams = true;
  731       }
  732   
  733   
  734       /**
  735        * Save query parameters for this request.
  736        *
  737        * @param queryString The query string containing parameters for this
  738        *                    request
  739        */
  740       void setQueryParams(String queryString) {
  741           this.queryParamString = queryString;
  742       }
  743   
  744   
  745       // ------------------------------------------------------ Protected Methods
  746   
  747   
  748       /**
  749        * Is this attribute name one of the special ones that is added only for
  750        * included servlets?
  751        *
  752        * @param name Attribute name to be tested
  753        */
  754       protected boolean isSpecial(String name) {
  755   
  756           for (int i = 0; i < specials.length; i++) {
  757               if (specials[i].equals(name))
  758                   return (true);
  759           }
  760           return (false);
  761   
  762       }
  763   
  764   
  765       /**
  766        * Get a special attribute.
  767        *
  768        * @return the special attribute pos, or -1 if it is not a special 
  769        *         attribute
  770        */
  771       protected int getSpecial(String name) {
  772           for (int i = 0; i < specials.length; i++) {
  773               if (specials[i].equals(name)) {
  774                   return (i);
  775               }
  776           }
  777           return (-1);
  778       }
  779   
  780   
  781       /**
  782        * Set a special attribute.
  783        * 
  784        * @return true if the attribute was a special attribute, false otherwise
  785        */
  786       protected boolean setSpecial(String name, Object value) {
  787           for (int i = 0; i < specials.length; i++) {
  788               if (specials[i].equals(name)) {
  789                   specialAttributes[i] = value;
  790                   return (true);
  791               }
  792           }
  793           return (false);
  794       }
  795   
  796   
  797       /**
  798        * Remove a special attribute.
  799        * 
  800        * @return true if the attribute was a special attribute, false otherwise
  801        */
  802       protected boolean removeSpecial(String name) {
  803           for (int i = 0; i < specials.length; i++) {
  804               if (specials[i].equals(name)) {
  805                   specialAttributes[i] = null;
  806                   return (true);
  807               }
  808           }
  809           return (false);
  810       }
  811   
  812   
  813       /**
  814        * Merge the two sets of parameter values into a single String array.
  815        *
  816        * @param values1 First set of values
  817        * @param values2 Second set of values
  818        */
  819       protected String[] mergeValues(Object values1, Object values2) {
  820   
  821           ArrayList results = new ArrayList();
  822   
  823           if (values1 == null)
  824               ;
  825           else if (values1 instanceof String)
  826               results.add(values1);
  827           else if (values1 instanceof String[]) {
  828               String values[] = (String[]) values1;
  829               for (int i = 0; i < values.length; i++)
  830                   results.add(values[i]);
  831           } else
  832               results.add(values1.toString());
  833   
  834           if (values2 == null)
  835               ;
  836           else if (values2 instanceof String)
  837               results.add(values2);
  838           else if (values2 instanceof String[]) {
  839               String values[] = (String[]) values2;
  840               for (int i = 0; i < values.length; i++)
  841                   results.add(values[i]);
  842           } else
  843               results.add(values2.toString());
  844   
  845           String values[] = new String[results.size()];
  846           return ((String[]) results.toArray(values));
  847   
  848       }
  849   
  850   
  851       // ------------------------------------------------------ Private Methods
  852   
  853   
  854       /**
  855        * Merge the parameters from the saved query parameter string (if any), and
  856        * the parameters already present on this request (if any), such that the
  857        * parameter values from the query string show up first if there are
  858        * duplicate parameter names.
  859        */
  860       private void mergeParameters() {
  861   
  862           if ((queryParamString == null) || (queryParamString.length() < 1))
  863               return;
  864   
  865           HashMap queryParameters = new HashMap();
  866           String encoding = getCharacterEncoding();
  867           if (encoding == null)
  868               encoding = "ISO-8859-1";
  869           try {
  870               RequestUtil.parseParameters
  871                   (queryParameters, queryParamString, encoding);
  872           } catch (Exception e) {
  873               ;
  874           }
  875           Iterator keys = parameters.keySet().iterator();
  876           while (keys.hasNext()) {
  877               String key = (String) keys.next();
  878               Object value = queryParameters.get(key);
  879               if (value == null) {
  880                   queryParameters.put(key, parameters.get(key));
  881                   continue;
  882               }
  883               queryParameters.put
  884                   (key, mergeValues(value, parameters.get(key)));
  885           }
  886           parameters = queryParameters;
  887   
  888       }
  889   
  890   
  891       // ----------------------------------- AttributeNamesEnumerator Inner Class
  892   
  893   
  894       /**
  895        * Utility class used to expose the special attributes as being available
  896        * as request attributes.
  897        */
  898       protected class AttributeNamesEnumerator implements Enumeration {
  899   
  900           protected int pos = -1;
  901           protected int last = -1;
  902           protected Enumeration parentEnumeration = null;
  903           protected String next = null;
  904   
  905           public AttributeNamesEnumerator() {
  906               parentEnumeration = getRequest().getAttributeNames();
  907               for (int i = 0; i < specialAttributes.length; i++) {
  908                   if (getAttribute(specials[i]) != null) {
  909                       last = i;
  910                   }
  911               }
  912           }
  913   
  914           public boolean hasMoreElements() {
  915               return ((pos != last) || (next != null) 
  916                       || ((next = findNext()) != null));
  917           }
  918   
  919           public Object nextElement() {
  920               if (pos != last) {
  921                   for (int i = pos + 1; i <= last; i++) {
  922                       if (getAttribute(specials[i]) != null) {
  923                           pos = i;
  924                           return (specials[i]);
  925                       }
  926                   }
  927               }
  928               String result = next;
  929               if (next != null) {
  930                   next = findNext();
  931               } else {
  932                   throw new NoSuchElementException();
  933               }
  934               return result;
  935           }
  936   
  937           protected String findNext() {
  938               String result = null;
  939               while ((result == null) && (parentEnumeration.hasMoreElements())) {
  940                   String current = (String) parentEnumeration.nextElement();
  941                   if (!isSpecial(current)) {
  942                       result = current;
  943                   }
  944               }
  945               return result;
  946           }
  947   
  948       }
  949   
  950   
  951   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » core » [javadoc | source]