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.File;
   23   import java.io.InputStream;
   24   import java.net.MalformedURLException;
   25   import java.net.URL;
   26   import java.util.ArrayList;
   27   import java.util.Enumeration;
   28   import java.util.Iterator;
   29   import java.util.Map;
   30   import java.util.Set;
   31   import java.util.concurrent.ConcurrentHashMap;
   32   
   33   import javax.naming.Binding;
   34   import javax.naming.NamingException;
   35   import javax.naming.directory.DirContext;
   36   import javax.servlet.RequestDispatcher;
   37   import javax.servlet.Servlet;
   38   import javax.servlet.ServletContext;
   39   import javax.servlet.ServletContextAttributeEvent;
   40   import javax.servlet.ServletContextAttributeListener;
   41   
   42   import org.apache.catalina.Context;
   43   import org.apache.catalina.Host;
   44   import org.apache.catalina.Wrapper;
   45   import org.apache.catalina.deploy.ApplicationParameter;
   46   import org.apache.catalina.util.Enumerator;
   47   import org.apache.catalina.util.ResourceSet;
   48   import org.apache.catalina.util.ServerInfo;
   49   import org.apache.catalina.util.StringManager;
   50   import org.apache.naming.resources.DirContextURLStreamHandler;
   51   import org.apache.naming.resources.Resource;
   52   import org.apache.tomcat.util.buf.CharChunk;
   53   import org.apache.tomcat.util.buf.MessageBytes;
   54   import org.apache.tomcat.util.http.mapper.MappingData;
   55   
   56   
   57   /**
   58    * Standard implementation of <code>ServletContext</code> that represents
   59    * a web application's execution environment.  An instance of this class is
   60    * associated with each instance of <code>StandardContext</code>.
   61    *
   62    * @author Craig R. McClanahan
   63    * @author Remy Maucherat
   64    * @version $Revision: 606606 $ $Date: 2007-12-23 21:09:23 +0100 (dim., 23 déc. 2007) $
   65    */
   66   
   67   public class ApplicationContext
   68       implements ServletContext {
   69   
   70       // ----------------------------------------------------------- Constructors
   71   
   72   
   73       /**
   74        * Construct a new instance of this class, associated with the specified
   75        * Context instance.
   76        *
   77        * @param context The associated Context instance
   78        */
   79       public ApplicationContext(String basePath, StandardContext context) {
   80           super();
   81           this.context = context;
   82           this.basePath = basePath;
   83       }
   84   
   85   
   86       // ----------------------------------------------------- Instance Variables
   87   
   88   
   89       /**
   90        * The context attributes for this context.
   91        */
   92       protected Map attributes = new ConcurrentHashMap();
   93   
   94   
   95       /**
   96        * List of read only attributes for this context.
   97        */
   98       private Map readOnlyAttributes = new ConcurrentHashMap();
   99   
  100   
  101       /**
  102        * The Context instance with which we are associated.
  103        */
  104       private StandardContext context = null;
  105   
  106   
  107       /**
  108        * Empty collection to serve as the basis for empty enumerations.
  109        * <strong>DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!</strong>
  110        */
  111       private static final ArrayList empty = new ArrayList();
  112   
  113   
  114       /**
  115        * The facade around this object.
  116        */
  117       private ServletContext facade = new ApplicationContextFacade(this);
  118   
  119   
  120       /**
  121        * The merged context initialization parameters for this Context.
  122        */
  123       private Map parameters = null;
  124   
  125   
  126       /**
  127        * The string manager for this package.
  128        */
  129       private static final StringManager sm =
  130         StringManager.getManager(Constants.Package);
  131   
  132   
  133       /**
  134        * Base path.
  135        */
  136       private String basePath = null;
  137   
  138   
  139       /**
  140        * Thread local data used during request dispatch.
  141        */
  142       private ThreadLocal<DispatchData> dispatchData =
  143           new ThreadLocal<DispatchData>();
  144   
  145   
  146       // --------------------------------------------------------- Public Methods
  147   
  148   
  149       /**
  150        * Return the resources object that is mapped to a specified path.
  151        * The path must begin with a "/" and is interpreted as relative to the
  152        * current context root.
  153        */
  154       public DirContext getResources() {
  155   
  156           return context.getResources();
  157   
  158       }
  159   
  160   
  161       // ------------------------------------------------- ServletContext Methods
  162   
  163   
  164       /**
  165        * Return the value of the specified context attribute, if any;
  166        * otherwise return <code>null</code>.
  167        *
  168        * @param name Name of the context attribute to return
  169        */
  170       public Object getAttribute(String name) {
  171   
  172           return (attributes.get(name));
  173   
  174       }
  175   
  176   
  177       /**
  178        * Return an enumeration of the names of the context attributes
  179        * associated with this context.
  180        */
  181       public Enumeration getAttributeNames() {
  182   
  183           return new Enumerator(attributes.keySet(), true);
  184   
  185       }
  186   
  187   
  188       /**
  189        * Return a <code>ServletContext</code> object that corresponds to a
  190        * specified URI on the server.  This method allows servlets to gain
  191        * access to the context for various parts of the server, and as needed
  192        * obtain <code>RequestDispatcher</code> objects or resources from the
  193        * context.  The given path must be absolute (beginning with a "/"),
  194        * and is interpreted based on our virtual host's document root.
  195        *
  196        * @param uri Absolute URI of a resource on the server
  197        */
  198       public ServletContext getContext(String uri) {
  199   
  200           // Validate the format of the specified argument
  201           if ((uri == null) || (!uri.startsWith("/")))
  202               return (null);
  203   
  204           Context child = null;
  205           try {
  206               Host host = (Host) context.getParent();
  207               String mapuri = uri;
  208               while (true) {
  209                   child = (Context) host.findChild(mapuri);
  210                   if (child != null)
  211                       break;
  212                   int slash = mapuri.lastIndexOf('/');
  213                   if (slash < 0)
  214                       break;
  215                   mapuri = mapuri.substring(0, slash);
  216               }
  217           } catch (Throwable t) {
  218               return (null);
  219           }
  220   
  221           if (child == null)
  222               return (null);
  223   
  224           if (context.getCrossContext()) {
  225               // If crossContext is enabled, can always return the context
  226               return child.getServletContext();
  227           } else if (child == context) {
  228               // Can still return the current context
  229               return context.getServletContext();
  230           } else {
  231               // Nothing to return
  232               return (null);
  233           }
  234       }
  235   
  236       
  237       /**
  238        * Return the main path associated with this context.
  239        */
  240       public String getContextPath() {
  241           return context.getPath();
  242       }
  243       
  244   
  245       /**
  246        * Return the value of the specified initialization parameter, or
  247        * <code>null</code> if this parameter does not exist.
  248        *
  249        * @param name Name of the initialization parameter to retrieve
  250        */
  251       public String getInitParameter(final String name) {
  252   
  253           mergeParameters();
  254           return ((String) parameters.get(name));
  255   
  256       }
  257   
  258   
  259       /**
  260        * Return the names of the context's initialization parameters, or an
  261        * empty enumeration if the context has no initialization parameters.
  262        */
  263       public Enumeration getInitParameterNames() {
  264   
  265           mergeParameters();
  266           return (new Enumerator(parameters.keySet()));
  267   
  268       }
  269   
  270   
  271       /**
  272        * Return the major version of the Java Servlet API that we implement.
  273        */
  274       public int getMajorVersion() {
  275   
  276           return (Constants.MAJOR_VERSION);
  277   
  278       }
  279   
  280   
  281       /**
  282        * Return the minor version of the Java Servlet API that we implement.
  283        */
  284       public int getMinorVersion() {
  285   
  286           return (Constants.MINOR_VERSION);
  287   
  288       }
  289   
  290   
  291       /**
  292        * Return the MIME type of the specified file, or <code>null</code> if
  293        * the MIME type cannot be determined.
  294        *
  295        * @param file Filename for which to identify a MIME type
  296        */
  297       public String getMimeType(String file) {
  298   
  299           if (file == null)
  300               return (null);
  301           int period = file.lastIndexOf(".");
  302           if (period < 0)
  303               return (null);
  304           String extension = file.substring(period + 1);
  305           if (extension.length() < 1)
  306               return (null);
  307           return (context.findMimeMapping(extension));
  308   
  309       }
  310   
  311   
  312       /**
  313        * Return a <code>RequestDispatcher</code> object that acts as a
  314        * wrapper for the named servlet.
  315        *
  316        * @param name Name of the servlet for which a dispatcher is requested
  317        */
  318       public RequestDispatcher getNamedDispatcher(String name) {
  319   
  320           // Validate the name argument
  321           if (name == null)
  322               return (null);
  323   
  324           // Create and return a corresponding request dispatcher
  325           Wrapper wrapper = (Wrapper) context.findChild(name);
  326           if (wrapper == null)
  327               return (null);
  328           
  329           return new ApplicationDispatcher(wrapper, null, null, null, null, name);
  330   
  331       }
  332   
  333   
  334       /**
  335        * Return the real path for a given virtual path, if possible; otherwise
  336        * return <code>null</code>.
  337        *
  338        * @param path The path to the desired resource
  339        */
  340       public String getRealPath(String path) {
  341   
  342           if (!context.isFilesystemBased())
  343               return null;
  344   
  345           if (path == null) {
  346               return null;
  347           }
  348   
  349           File file = new File(basePath, path);
  350           return (file.getAbsolutePath());
  351   
  352       }
  353   
  354   
  355       /**
  356        * Return a <code>RequestDispatcher</code> instance that acts as a
  357        * wrapper for the resource at the given path.  The path must begin
  358        * with a "/" and is interpreted as relative to the current context root.
  359        *
  360        * @param path The path to the desired resource.
  361        */
  362       public RequestDispatcher getRequestDispatcher(String path) {
  363   
  364           // Validate the path argument
  365           if (path == null)
  366               return (null);
  367           if (!path.startsWith("/"))
  368               throw new IllegalArgumentException
  369                   (sm.getString
  370                    ("applicationContext.requestDispatcher.iae", path));
  371           path = normalize(path);
  372           if (path == null)
  373               return (null);
  374   
  375           // Use the thread local URI and mapping data
  376           DispatchData dd = dispatchData.get();
  377           if (dd == null) {
  378               dd = new DispatchData();
  379               dispatchData.set(dd);
  380           }
  381   
  382           MessageBytes uriMB = dd.uriMB;
  383           uriMB.recycle();
  384   
  385           // Get query string
  386           String queryString = null;
  387           int pos = path.indexOf('?');
  388           if (pos >= 0) {
  389               queryString = path.substring(pos + 1);
  390           } else {
  391               pos = path.length();
  392           }
  393    
  394           // Use the thread local mapping data
  395           MappingData mappingData = dd.mappingData;
  396   
  397           // Map the URI
  398           CharChunk uriCC = uriMB.getCharChunk();
  399           try {
  400               uriCC.append(context.getPath(), 0, context.getPath().length());
  401               /*
  402                * Ignore any trailing path params (separated by ';') for mapping
  403                * purposes
  404                */
  405               int semicolon = path.indexOf(';');
  406               if (pos >= 0 && semicolon > pos) {
  407                   semicolon = -1;
  408               }
  409               uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
  410               context.getMapper().map(uriMB, mappingData);
  411               if (mappingData.wrapper == null) {
  412                   return (null);
  413               }
  414               /*
  415                * Append any trailing path params (separated by ';') that were
  416                * ignored for mapping purposes, so that they're reflected in the
  417                * RequestDispatcher's requestURI
  418                */
  419               if (semicolon > 0) {
  420                   uriCC.append(path, semicolon, pos - semicolon);
  421               }
  422           } catch (Exception e) {
  423               // Should never happen
  424               log(sm.getString("applicationContext.mapping.error"), e);
  425               return (null);
  426           }
  427   
  428           Wrapper wrapper = (Wrapper) mappingData.wrapper;
  429           String wrapperPath = mappingData.wrapperPath.toString();
  430           String pathInfo = mappingData.pathInfo.toString();
  431   
  432           mappingData.recycle();
  433           
  434           // Construct a RequestDispatcher to process this request
  435           return new ApplicationDispatcher
  436               (wrapper, uriCC.toString(), wrapperPath, pathInfo, 
  437                queryString, null);
  438   
  439       }
  440   
  441   
  442   
  443       /**
  444        * Return the URL to the resource that is mapped to a specified path.
  445        * The path must begin with a "/" and is interpreted as relative to the
  446        * current context root.
  447        *
  448        * @param path The path to the desired resource
  449        *
  450        * @exception MalformedURLException if the path is not given
  451        *  in the correct form
  452        */
  453       public URL getResource(String path)
  454           throws MalformedURLException {
  455   
  456           if (path == null || !path.startsWith("/")) {
  457               throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path));
  458           }
  459           
  460           path = normalize(path);
  461           if (path == null)
  462               return (null);
  463   
  464           String libPath = "/WEB-INF/lib/";
  465           if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) {
  466               File jarFile = null;
  467               if (context.isFilesystemBased()) {
  468                   jarFile = new File(basePath, path);
  469               } else {
  470                   jarFile = new File(context.getWorkPath(), path);
  471               }
  472               if (jarFile.exists()) {
  473                   return jarFile.toURL();
  474               } else {
  475                   return null;
  476               }
  477           } else {
  478   
  479               DirContext resources = context.getResources();
  480               if (resources != null) {
  481                   String fullPath = context.getName() + path;
  482                   String hostName = context.getParent().getName();
  483                   try {
  484                       resources.lookup(path);
  485                       return new URL
  486                           ("jndi", "", 0, getJNDIUri(hostName, fullPath),
  487                            new DirContextURLStreamHandler(resources));
  488                   } catch (Exception e) {
  489                       // Ignore
  490                   }
  491               }
  492           }
  493   
  494           return (null);
  495   
  496       }
  497   
  498   
  499       /**
  500        * Return the requested resource as an <code>InputStream</code>.  The
  501        * path must be specified according to the rules described under
  502        * <code>getResource</code>.  If no such resource can be identified,
  503        * return <code>null</code>.
  504        *
  505        * @param path The path to the desired resource.
  506        */
  507       public InputStream getResourceAsStream(String path) {
  508   
  509           path = normalize(path);
  510           if (path == null || !path.startsWith("/"))
  511               return (null);
  512   
  513           DirContext resources = context.getResources();
  514           if (resources != null) {
  515               try {
  516                   Object resource = resources.lookup(path);
  517                   if (resource instanceof Resource)
  518                       return (((Resource) resource).streamContent());
  519               } catch (Exception e) {
  520               }
  521           }
  522           return (null);
  523   
  524       }
  525   
  526   
  527       /**
  528        * Return a Set containing the resource paths of resources member of the
  529        * specified collection. Each path will be a String starting with
  530        * a "/" character. The returned set is immutable.
  531        *
  532        * @param path Collection path
  533        */
  534       public Set getResourcePaths(String path) {
  535   
  536           // Validate the path argument
  537           if (path == null) {
  538               return null;
  539           }
  540           if (!path.startsWith("/")) {
  541               throw new IllegalArgumentException
  542                   (sm.getString("applicationContext.resourcePaths.iae", path));
  543           }
  544   
  545           path = normalize(path);
  546           if (path == null)
  547               return (null);
  548   
  549           DirContext resources = context.getResources();
  550           if (resources != null) {
  551               return (getResourcePathsInternal(resources, path));
  552           }
  553           return (null);
  554   
  555       }
  556   
  557   
  558       /**
  559        * Internal implementation of getResourcesPath() logic.
  560        *
  561        * @param resources Directory context to search
  562        * @param path Collection path
  563        */
  564       private Set getResourcePathsInternal(DirContext resources, String path) {
  565   
  566           ResourceSet set = new ResourceSet();
  567           try {
  568               listCollectionPaths(set, resources, path);
  569           } catch (NamingException e) {
  570               return (null);
  571           }
  572           set.setLocked(true);
  573           return (set);
  574   
  575       }
  576   
  577   
  578       /**
  579        * Return the name and version of the servlet container.
  580        */
  581       public String getServerInfo() {
  582   
  583           return (ServerInfo.getServerInfo());
  584   
  585       }
  586   
  587   
  588       /**
  589        * @deprecated As of Java Servlet API 2.1, with no direct replacement.
  590        */
  591       public Servlet getServlet(String name) {
  592   
  593           return (null);
  594   
  595       }
  596   
  597   
  598       /**
  599        * Return the display name of this web application.
  600        */
  601       public String getServletContextName() {
  602   
  603           return (context.getDisplayName());
  604   
  605       }
  606   
  607   
  608       /**
  609        * @deprecated As of Java Servlet API 2.1, with no direct replacement.
  610        */
  611       public Enumeration getServletNames() {
  612           return (new Enumerator(empty));
  613       }
  614   
  615   
  616       /**
  617        * @deprecated As of Java Servlet API 2.1, with no direct replacement.
  618        */
  619       public Enumeration getServlets() {
  620           return (new Enumerator(empty));
  621       }
  622   
  623   
  624       /**
  625        * Writes the specified message to a servlet log file.
  626        *
  627        * @param message Message to be written
  628        */
  629       public void log(String message) {
  630   
  631           context.getLogger().info(message);
  632   
  633       }
  634   
  635   
  636       /**
  637        * Writes the specified exception and message to a servlet log file.
  638        *
  639        * @param exception Exception to be reported
  640        * @param message Message to be written
  641        *
  642        * @deprecated As of Java Servlet API 2.1, use
  643        *  <code>log(String, Throwable)</code> instead
  644        */
  645       public void log(Exception exception, String message) {
  646           
  647           context.getLogger().error(message, exception);
  648   
  649       }
  650   
  651   
  652       /**
  653        * Writes the specified message and exception to a servlet log file.
  654        *
  655        * @param message Message to be written
  656        * @param throwable Exception to be reported
  657        */
  658       public void log(String message, Throwable throwable) {
  659           
  660           context.getLogger().error(message, throwable);
  661   
  662       }
  663   
  664   
  665       /**
  666        * Remove the context attribute with the specified name, if any.
  667        *
  668        * @param name Name of the context attribute to be removed
  669        */
  670       public void removeAttribute(String name) {
  671   
  672           Object value = null;
  673           boolean found = false;
  674   
  675           // Remove the specified attribute
  676           // Check for read only attribute
  677           if (readOnlyAttributes.containsKey(name))
  678               return;
  679           found = attributes.containsKey(name);
  680           if (found) {
  681               value = attributes.get(name);
  682               attributes.remove(name);
  683           } else {
  684               return;
  685           }
  686   
  687           // Notify interested application event listeners
  688           Object listeners[] = context.getApplicationEventListeners();
  689           if ((listeners == null) || (listeners.length == 0))
  690               return;
  691           ServletContextAttributeEvent event =
  692             new ServletContextAttributeEvent(context.getServletContext(),
  693                                               name, value);
  694           for (int i = 0; i < listeners.length; i++) {
  695               if (!(listeners[i] instanceof ServletContextAttributeListener))
  696                   continue;
  697               ServletContextAttributeListener listener =
  698                   (ServletContextAttributeListener) listeners[i];
  699               try {
  700                   context.fireContainerEvent("beforeContextAttributeRemoved",
  701                                              listener);
  702                   listener.attributeRemoved(event);
  703                   context.fireContainerEvent("afterContextAttributeRemoved",
  704                                              listener);
  705               } catch (Throwable t) {
  706                   context.fireContainerEvent("afterContextAttributeRemoved",
  707                                              listener);
  708                   // FIXME - should we do anything besides log these?
  709                   log(sm.getString("applicationContext.attributeEvent"), t);
  710               }
  711           }
  712   
  713       }
  714   
  715   
  716       /**
  717        * Bind the specified value with the specified context attribute name,
  718        * replacing any existing value for that name.
  719        *
  720        * @param name Attribute name to be bound
  721        * @param value New attribute value to be bound
  722        */
  723       public void setAttribute(String name, Object value) {
  724   
  725           // Name cannot be null
  726           if (name == null)
  727               throw new IllegalArgumentException
  728                   (sm.getString("applicationContext.setAttribute.namenull"));
  729   
  730           // Null value is the same as removeAttribute()
  731           if (value == null) {
  732               removeAttribute(name);
  733               return;
  734           }
  735   
  736           Object oldValue = null;
  737           boolean replaced = false;
  738   
  739           // Add or replace the specified attribute
  740           // Check for read only attribute
  741           if (readOnlyAttributes.containsKey(name))
  742               return;
  743           oldValue = attributes.get(name);
  744           if (oldValue != null)
  745               replaced = true;
  746           attributes.put(name, value);
  747   
  748           // Notify interested application event listeners
  749           Object listeners[] = context.getApplicationEventListeners();
  750           if ((listeners == null) || (listeners.length == 0))
  751               return;
  752           ServletContextAttributeEvent event = null;
  753           if (replaced)
  754               event =
  755                   new ServletContextAttributeEvent(context.getServletContext(),
  756                                                    name, oldValue);
  757           else
  758               event =
  759                   new ServletContextAttributeEvent(context.getServletContext(),
  760                                                    name, value);
  761   
  762           for (int i = 0; i < listeners.length; i++) {
  763               if (!(listeners[i] instanceof ServletContextAttributeListener))
  764                   continue;
  765               ServletContextAttributeListener listener =
  766                   (ServletContextAttributeListener) listeners[i];
  767               try {
  768                   if (replaced) {
  769                       context.fireContainerEvent
  770                           ("beforeContextAttributeReplaced", listener);
  771                       listener.attributeReplaced(event);
  772                       context.fireContainerEvent("afterContextAttributeReplaced",
  773                                                  listener);
  774                   } else {
  775                       context.fireContainerEvent("beforeContextAttributeAdded",
  776                                                  listener);
  777                       listener.attributeAdded(event);
  778                       context.fireContainerEvent("afterContextAttributeAdded",
  779                                                  listener);
  780                   }
  781               } catch (Throwable t) {
  782                   if (replaced)
  783                       context.fireContainerEvent("afterContextAttributeReplaced",
  784                                                  listener);
  785                   else
  786                       context.fireContainerEvent("afterContextAttributeAdded",
  787                                                  listener);
  788                   // FIXME - should we do anything besides log these?
  789                   log(sm.getString("applicationContext.attributeEvent"), t);
  790               }
  791           }
  792   
  793       }
  794   
  795   
  796       // -------------------------------------------------------- Package Methods
  797       protected StandardContext getContext() {
  798           return this.context;
  799       }
  800       
  801       protected Map getReadonlyAttributes() {
  802           return this.readOnlyAttributes;
  803       }
  804       /**
  805        * Clear all application-created attributes.
  806        */
  807       protected void clearAttributes() {
  808   
  809           // Create list of attributes to be removed
  810           ArrayList list = new ArrayList();
  811           Iterator iter = attributes.keySet().iterator();
  812           while (iter.hasNext()) {
  813               list.add(iter.next());
  814           }
  815   
  816           // Remove application originated attributes
  817           // (read only attributes will be left in place)
  818           Iterator keys = list.iterator();
  819           while (keys.hasNext()) {
  820               String key = (String) keys.next();
  821               removeAttribute(key);
  822           }
  823           
  824       }
  825       
  826       
  827       /**
  828        * Return the facade associated with this ApplicationContext.
  829        */
  830       protected ServletContext getFacade() {
  831   
  832           return (this.facade);
  833   
  834       }
  835   
  836   
  837       /**
  838        * Set an attribute as read only.
  839        */
  840       void setAttributeReadOnly(String name) {
  841   
  842           if (attributes.containsKey(name))
  843               readOnlyAttributes.put(name, name);
  844   
  845       }
  846   
  847   
  848       // -------------------------------------------------------- Private Methods
  849   
  850   
  851       /**
  852        * Return a context-relative path, beginning with a "/", that represents
  853        * the canonical version of the specified path after ".." and "." elements
  854        * are resolved out.  If the specified path attempts to go outside the
  855        * boundaries of the current context (i.e. too many ".." path elements
  856        * are present), return <code>null</code> instead.
  857        *
  858        * @param path Path to be normalized
  859        */
  860       private String normalize(String path) {
  861   
  862           if (path == null) {
  863               return null;
  864           }
  865   
  866           String normalized = path;
  867   
  868           // Normalize the slashes
  869           if (normalized.indexOf('\\') >= 0)
  870               normalized = normalized.replace('\\', '/');
  871   
  872           // Resolve occurrences of "/../" in the normalized path
  873           while (true) {
  874               int index = normalized.indexOf("/../");
  875               if (index < 0)
  876                   break;
  877               if (index == 0)
  878                   return (null);  // Trying to go outside our context
  879               int index2 = normalized.lastIndexOf('/', index - 1);
  880               normalized = normalized.substring(0, index2) +
  881                   normalized.substring(index + 3);
  882           }
  883   
  884           // Return the normalized path that we have completed
  885           return (normalized);
  886   
  887       }
  888   
  889   
  890       /**
  891        * Merge the context initialization parameters specified in the application
  892        * deployment descriptor with the application parameters described in the
  893        * server configuration, respecting the <code>override</code> property of
  894        * the application parameters appropriately.
  895        */
  896       private void mergeParameters() {
  897   
  898           if (parameters != null)
  899               return;
  900           Map results = new ConcurrentHashMap();
  901           String names[] = context.findParameters();
  902           for (int i = 0; i < names.length; i++)
  903               results.put(names[i], context.findParameter(names[i]));
  904           ApplicationParameter params[] =
  905               context.findApplicationParameters();
  906           for (int i = 0; i < params.length; i++) {
  907               if (params[i].getOverride()) {
  908                   if (results.get(params[i].getName()) == null)
  909                       results.put(params[i].getName(), params[i].getValue());
  910               } else {
  911                   results.put(params[i].getName(), params[i].getValue());
  912               }
  913           }
  914           parameters = results;
  915   
  916       }
  917   
  918   
  919       /**
  920        * List resource paths (recursively), and store all of them in the given
  921        * Set.
  922        */
  923       private static void listCollectionPaths
  924           (Set set, DirContext resources, String path)
  925           throws NamingException {
  926   
  927           Enumeration childPaths = resources.listBindings(path);
  928           while (childPaths.hasMoreElements()) {
  929               Binding binding = (Binding) childPaths.nextElement();
  930               String name = binding.getName();
  931               StringBuffer childPath = new StringBuffer(path);
  932               if (!"/".equals(path) && !path.endsWith("/"))
  933                   childPath.append("/");
  934               childPath.append(name);
  935               Object object = binding.getObject();
  936               if (object instanceof DirContext) {
  937                   childPath.append("/");
  938               }
  939               set.add(childPath.toString());
  940           }
  941   
  942       }
  943   
  944   
  945       /**
  946        * Get full path, based on the host name and the context path.
  947        */
  948       private static String getJNDIUri(String hostName, String path) {
  949           if (!path.startsWith("/"))
  950               return "/" + hostName + "/" + path;
  951           else
  952               return "/" + hostName + path;
  953       }
  954   
  955   
  956       /**
  957        * Internal class used as thread-local storage when doing path
  958        * mapping during dispatch.
  959        */
  960       private final class DispatchData {
  961   
  962           public MessageBytes uriMB;
  963           public MappingData mappingData;
  964   
  965           public DispatchData() {
  966               uriMB = MessageBytes.newInstance();
  967               CharChunk uriCC = uriMB.getCharChunk();
  968               uriCC.setLimit(-1);
  969               mappingData = new MappingData();
  970           }
  971       }
  972   
  973   
  974   }

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