FileDocCategorySizeDatePackage
ApplicationContext.javaAPI DocApache Tomcat 6.0.1429925Fri Jul 20 04:20:34 BST 2007org.apache.catalina.core

ApplicationContext

public class ApplicationContext extends Object implements ServletContext
Standard implementation of ServletContext that represents a web application's execution environment. An instance of this class is associated with each instance of StandardContext.
author
Craig R. McClanahan
author
Remy Maucherat
version
$Revision: 529466 $ $Date: 2007-04-17 03:52:50 +0200 (mar., 17 avr. 2007) $

Fields Summary
protected Map
attributes
The context attributes for this context.
private Map
readOnlyAttributes
List of read only attributes for this context.
private StandardContext
context
The Context instance with which we are associated.
private static final ArrayList
empty
Empty collection to serve as the basis for empty enumerations. DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!
private ServletContext
facade
The facade around this object.
private Map
parameters
The merged context initialization parameters for this Context.
private static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
private String
basePath
Base path.
private ThreadLocal
dispatchData
Thread local data used during request dispatch.
Constructors Summary
public ApplicationContext(String basePath, StandardContext context)
Construct a new instance of this class, associated with the specified Context instance.

param
context The associated Context instance

        super();
        this.context = context;
        this.basePath = basePath;
    
Methods Summary
protected voidclearAttributes()
Clear all application-created attributes.


        // Create list of attributes to be removed
        ArrayList list = new ArrayList();
        Iterator iter = attributes.keySet().iterator();
        while (iter.hasNext()) {
            list.add(iter.next());
        }

        // Remove application originated attributes
        // (read only attributes will be left in place)
        Iterator keys = list.iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            removeAttribute(key);
        }
        
    
public java.lang.ObjectgetAttribute(java.lang.String name)
Return the value of the specified context attribute, if any; otherwise return null.

param
name Name of the context attribute to return


        return (attributes.get(name));

    
public java.util.EnumerationgetAttributeNames()
Return an enumeration of the names of the context attributes associated with this context.


        return new Enumerator(attributes.keySet(), true);

    
protected StandardContextgetContext()

        return this.context;
    
public javax.servlet.ServletContextgetContext(java.lang.String uri)
Return a ServletContext object that corresponds to a specified URI on the server. This method allows servlets to gain access to the context for various parts of the server, and as needed obtain RequestDispatcher objects or resources from the context. The given path must be absolute (beginning with a "/"), and is interpreted based on our virtual host's document root.

param
uri Absolute URI of a resource on the server


        // Validate the format of the specified argument
        if ((uri == null) || (!uri.startsWith("/")))
            return (null);

        Context child = null;
        try {
            Host host = (Host) context.getParent();
            String mapuri = uri;
            while (true) {
                child = (Context) host.findChild(mapuri);
                if (child != null)
                    break;
                int slash = mapuri.lastIndexOf('/");
                if (slash < 0)
                    break;
                mapuri = mapuri.substring(0, slash);
            }
        } catch (Throwable t) {
            return (null);
        }

        if (child == null)
            return (null);

        if (context.getCrossContext()) {
            // If crossContext is enabled, can always return the context
            return child.getServletContext();
        } else if (child == context) {
            // Can still return the current context
            return context.getServletContext();
        } else {
            // Nothing to return
            return (null);
        }
    
public java.lang.StringgetContextPath()
Return the main path associated with this context.

        return context.getPath();
    
protected javax.servlet.ServletContextgetFacade()
Return the facade associated with this ApplicationContext.


        return (this.facade);

    
public java.lang.StringgetInitParameter(java.lang.String name)
Return the value of the specified initialization parameter, or null if this parameter does not exist.

param
name Name of the initialization parameter to retrieve


        mergeParameters();
        return ((String) parameters.get(name));

    
public java.util.EnumerationgetInitParameterNames()
Return the names of the context's initialization parameters, or an empty enumeration if the context has no initialization parameters.


        mergeParameters();
        return (new Enumerator(parameters.keySet()));

    
private static java.lang.StringgetJNDIUri(java.lang.String hostName, java.lang.String path)
Get full path, based on the host name and the context path.

        if (!path.startsWith("/"))
            return "/" + hostName + "/" + path;
        else
            return "/" + hostName + path;
    
public intgetMajorVersion()
Return the major version of the Java Servlet API that we implement.


        return (Constants.MAJOR_VERSION);

    
public java.lang.StringgetMimeType(java.lang.String file)
Return the MIME type of the specified file, or null if the MIME type cannot be determined.

param
file Filename for which to identify a MIME type


        if (file == null)
            return (null);
        int period = file.lastIndexOf(".");
        if (period < 0)
            return (null);
        String extension = file.substring(period + 1);
        if (extension.length() < 1)
            return (null);
        return (context.findMimeMapping(extension));

    
public intgetMinorVersion()
Return the minor version of the Java Servlet API that we implement.


        return (Constants.MINOR_VERSION);

    
public javax.servlet.RequestDispatchergetNamedDispatcher(java.lang.String name)
Return a RequestDispatcher object that acts as a wrapper for the named servlet.

param
name Name of the servlet for which a dispatcher is requested


        // Validate the name argument
        if (name == null)
            return (null);

        // Create and return a corresponding request dispatcher
        Wrapper wrapper = (Wrapper) context.findChild(name);
        if (wrapper == null)
            return (null);
        
        return new ApplicationDispatcher(wrapper, null, null, null, null, name);

    
protected java.util.MapgetReadonlyAttributes()

        return this.readOnlyAttributes;
    
public java.lang.StringgetRealPath(java.lang.String path)
Return the real path for a given virtual path, if possible; otherwise return null.

param
path The path to the desired resource


        if (!context.isFilesystemBased())
            return null;

        if (path == null) {
            return null;
        }

        File file = new File(basePath, path);
        return (file.getAbsolutePath());

    
public javax.servlet.RequestDispatchergetRequestDispatcher(java.lang.String path)
Return a RequestDispatcher instance that acts as a wrapper for the resource at the given path. The path must begin with a "/" and is interpreted as relative to the current context root.

param
path The path to the desired resource.


        // Validate the path argument
        if (path == null)
            return (null);
        if (!path.startsWith("/"))
            throw new IllegalArgumentException
                (sm.getString
                 ("applicationContext.requestDispatcher.iae", path));
        path = normalize(path);
        if (path == null)
            return (null);

        // Use the thread local URI and mapping data
        DispatchData dd = dispatchData.get();
        if (dd == null) {
            dd = new DispatchData();
            dispatchData.set(dd);
        }

        MessageBytes uriMB = dd.uriMB;
        uriMB.recycle();

        // Get query string
        String queryString = null;
        int pos = path.indexOf('?");
        if (pos >= 0) {
            queryString = path.substring(pos + 1);
        } else {
            pos = path.length();
        }
 
        // Use the thread local mapping data
        MappingData mappingData = dd.mappingData;

        // Map the URI
        CharChunk uriCC = uriMB.getCharChunk();
        try {
            uriCC.append(context.getPath(), 0, context.getPath().length());
            /*
             * Ignore any trailing path params (separated by ';') for mapping
             * purposes
             */
            int semicolon = path.indexOf(';");
            if (pos >= 0 && semicolon > pos) {
                semicolon = -1;
            }
            uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
            context.getMapper().map(uriMB, mappingData);
            if (mappingData.wrapper == null) {
                return (null);
            }
            /*
             * Append any trailing path params (separated by ';') that were
             * ignored for mapping purposes, so that they're reflected in the
             * RequestDispatcher's requestURI
             */
            if (semicolon > 0) {
                uriCC.append(path, semicolon, pos - semicolon);
            }
        } catch (Exception e) {
            // Should never happen
            log(sm.getString("applicationContext.mapping.error"), e);
            return (null);
        }

        Wrapper wrapper = (Wrapper) mappingData.wrapper;
        String wrapperPath = mappingData.wrapperPath.toString();
        String pathInfo = mappingData.pathInfo.toString();

        mappingData.recycle();
        
        // Construct a RequestDispatcher to process this request
        return new ApplicationDispatcher
            (wrapper, uriCC.toString(), wrapperPath, pathInfo, 
             queryString, null);

    
public java.net.URLgetResource(java.lang.String path)
Return the URL to the resource that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.

param
path The path to the desired resource
exception
MalformedURLException if the path is not given in the correct form


        if (path == null || !path.startsWith("/")) {
            throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path));
        }
        
        path = normalize(path);
        if (path == null)
            return (null);

        String libPath = "/WEB-INF/lib/";
        if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) {
            File jarFile = null;
            if (context.isFilesystemBased()) {
                jarFile = new File(basePath, path);
            } else {
                jarFile = new File(context.getWorkPath(), path);
            }
            if (jarFile.exists()) {
                return jarFile.toURL();
            } else {
                return null;
            }
        } else {

            DirContext resources = context.getResources();
            if (resources != null) {
                String fullPath = context.getName() + path;
                String hostName = context.getParent().getName();
                try {
                    resources.lookup(path);
                    return new URL
                        ("jndi", "", 0, getJNDIUri(hostName, fullPath),
                         new DirContextURLStreamHandler(resources));
                } catch (Exception e) {
                    // Ignore
                }
            }
        }

        return (null);

    
public java.io.InputStreamgetResourceAsStream(java.lang.String path)
Return the requested resource as an InputStream. The path must be specified according to the rules described under getResource. If no such resource can be identified, return null.

param
path The path to the desired resource.


        path = normalize(path);
        if (path == null)
            return (null);

        DirContext resources = context.getResources();
        if (resources != null) {
            try {
                Object resource = resources.lookup(path);
                if (resource instanceof Resource)
                    return (((Resource) resource).streamContent());
            } catch (Exception e) {
            }
        }
        return (null);

    
public java.util.SetgetResourcePaths(java.lang.String path)
Return a Set containing the resource paths of resources member of the specified collection. Each path will be a String starting with a "/" character. The returned set is immutable.

param
path Collection path


        // Validate the path argument
        if (path == null) {
            return null;
        }
        if (!path.startsWith("/")) {
            throw new IllegalArgumentException
                (sm.getString("applicationContext.resourcePaths.iae", path));
        }

        path = normalize(path);
        if (path == null)
            return (null);

        DirContext resources = context.getResources();
        if (resources != null) {
            return (getResourcePathsInternal(resources, path));
        }
        return (null);

    
private java.util.SetgetResourcePathsInternal(javax.naming.directory.DirContext resources, java.lang.String path)
Internal implementation of getResourcesPath() logic.

param
resources Directory context to search
param
path Collection path


        ResourceSet set = new ResourceSet();
        try {
            listCollectionPaths(set, resources, path);
        } catch (NamingException e) {
            return (null);
        }
        set.setLocked(true);
        return (set);

    
public javax.naming.directory.DirContextgetResources()
Return the resources object that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.



    // --------------------------------------------------------- Public Methods


                                     
       

        return context.getResources();

    
public java.lang.StringgetServerInfo()
Return the name and version of the servlet container.


        return (ServerInfo.getServerInfo());

    
public javax.servlet.ServletgetServlet(java.lang.String name)

deprecated
As of Java Servlet API 2.1, with no direct replacement.


        return (null);

    
public java.lang.StringgetServletContextName()
Return the display name of this web application.


        return (context.getDisplayName());

    
public java.util.EnumerationgetServletNames()

deprecated
As of Java Servlet API 2.1, with no direct replacement.

        return (new Enumerator(empty));
    
public java.util.EnumerationgetServlets()

deprecated
As of Java Servlet API 2.1, with no direct replacement.

        return (new Enumerator(empty));
    
private static voidlistCollectionPaths(java.util.Set set, javax.naming.directory.DirContext resources, java.lang.String path)
List resource paths (recursively), and store all of them in the given Set.


        Enumeration childPaths = resources.listBindings(path);
        while (childPaths.hasMoreElements()) {
            Binding binding = (Binding) childPaths.nextElement();
            String name = binding.getName();
            StringBuffer childPath = new StringBuffer(path);
            if (!"/".equals(path) && !path.endsWith("/"))
                childPath.append("/");
            childPath.append(name);
            Object object = binding.getObject();
            if (object instanceof DirContext) {
                childPath.append("/");
            }
            set.add(childPath.toString());
        }

    
public voidlog(java.lang.String message)
Writes the specified message to a servlet log file.

param
message Message to be written


        context.getLogger().info(message);

    
public voidlog(java.lang.Exception exception, java.lang.String message)
Writes the specified exception and message to a servlet log file.

param
exception Exception to be reported
param
message Message to be written
deprecated
As of Java Servlet API 2.1, use log(String, Throwable) instead

        
        context.getLogger().error(message, exception);

    
public voidlog(java.lang.String message, java.lang.Throwable throwable)
Writes the specified message and exception to a servlet log file.

param
message Message to be written
param
throwable Exception to be reported

        
        context.getLogger().error(message, throwable);

    
private voidmergeParameters()
Merge the context initialization parameters specified in the application deployment descriptor with the application parameters described in the server configuration, respecting the override property of the application parameters appropriately.


        if (parameters != null)
            return;
        Map results = new ConcurrentHashMap();
        String names[] = context.findParameters();
        for (int i = 0; i < names.length; i++)
            results.put(names[i], context.findParameter(names[i]));
        ApplicationParameter params[] =
            context.findApplicationParameters();
        for (int i = 0; i < params.length; i++) {
            if (params[i].getOverride()) {
                if (results.get(params[i].getName()) == null)
                    results.put(params[i].getName(), params[i].getValue());
            } else {
                results.put(params[i].getName(), params[i].getValue());
            }
        }
        parameters = results;

    
private java.lang.Stringnormalize(java.lang.String path)
Return a context-relative path, beginning with a "/", that represents the canonical version of the specified path after ".." and "." elements are resolved out. If the specified path attempts to go outside the boundaries of the current context (i.e. too many ".." path elements are present), return null instead.

param
path Path to be normalized


        if (path == null) {
            return null;
        }

        String normalized = path;

        // Normalize the slashes and add leading slash if necessary
        if (normalized.indexOf('\\") >= 0)
            normalized = normalized.replace('\\", '/");

        // Resolve occurrences of "/../" in the normalized path
        while (true) {
            int index = normalized.indexOf("/../");
            if (index < 0)
                break;
            if (index == 0)
                return (null);  // Trying to go outside our context
            int index2 = normalized.lastIndexOf('/", index - 1);
            normalized = normalized.substring(0, index2) +
                normalized.substring(index + 3);
        }

        // Return the normalized path that we have completed
        return (normalized);

    
public voidremoveAttribute(java.lang.String name)
Remove the context attribute with the specified name, if any.

param
name Name of the context attribute to be removed


        Object value = null;
        boolean found = false;

        // Remove the specified attribute
        // Check for read only attribute
        if (readOnlyAttributes.containsKey(name))
            return;
        found = attributes.containsKey(name);
        if (found) {
            value = attributes.get(name);
            attributes.remove(name);
        } else {
            return;
        }

        // Notify interested application event listeners
        Object listeners[] = context.getApplicationEventListeners();
        if ((listeners == null) || (listeners.length == 0))
            return;
        ServletContextAttributeEvent event =
          new ServletContextAttributeEvent(context.getServletContext(),
                                            name, value);
        for (int i = 0; i < listeners.length; i++) {
            if (!(listeners[i] instanceof ServletContextAttributeListener))
                continue;
            ServletContextAttributeListener listener =
                (ServletContextAttributeListener) listeners[i];
            try {
                context.fireContainerEvent("beforeContextAttributeRemoved",
                                           listener);
                listener.attributeRemoved(event);
                context.fireContainerEvent("afterContextAttributeRemoved",
                                           listener);
            } catch (Throwable t) {
                context.fireContainerEvent("afterContextAttributeRemoved",
                                           listener);
                // FIXME - should we do anything besides log these?
                log(sm.getString("applicationContext.attributeEvent"), t);
            }
        }

    
public voidsetAttribute(java.lang.String name, java.lang.Object value)
Bind the specified value with the specified context attribute name, replacing any existing value for that name.

param
name Attribute name to be bound
param
value New attribute value to be bound


        // Name cannot be null
        if (name == null)
            throw new IllegalArgumentException
                (sm.getString("applicationContext.setAttribute.namenull"));

        // Null value is the same as removeAttribute()
        if (value == null) {
            removeAttribute(name);
            return;
        }

        Object oldValue = null;
        boolean replaced = false;

        // Add or replace the specified attribute
        // Check for read only attribute
        if (readOnlyAttributes.containsKey(name))
            return;
        oldValue = attributes.get(name);
        if (oldValue != null)
            replaced = true;
        attributes.put(name, value);

        // Notify interested application event listeners
        Object listeners[] = context.getApplicationEventListeners();
        if ((listeners == null) || (listeners.length == 0))
            return;
        ServletContextAttributeEvent event = null;
        if (replaced)
            event =
                new ServletContextAttributeEvent(context.getServletContext(),
                                                 name, oldValue);
        else
            event =
                new ServletContextAttributeEvent(context.getServletContext(),
                                                 name, value);

        for (int i = 0; i < listeners.length; i++) {
            if (!(listeners[i] instanceof ServletContextAttributeListener))
                continue;
            ServletContextAttributeListener listener =
                (ServletContextAttributeListener) listeners[i];
            try {
                if (replaced) {
                    context.fireContainerEvent
                        ("beforeContextAttributeReplaced", listener);
                    listener.attributeReplaced(event);
                    context.fireContainerEvent("afterContextAttributeReplaced",
                                               listener);
                } else {
                    context.fireContainerEvent("beforeContextAttributeAdded",
                                               listener);
                    listener.attributeAdded(event);
                    context.fireContainerEvent("afterContextAttributeAdded",
                                               listener);
                }
            } catch (Throwable t) {
                if (replaced)
                    context.fireContainerEvent("afterContextAttributeReplaced",
                                               listener);
                else
                    context.fireContainerEvent("afterContextAttributeAdded",
                                               listener);
                // FIXME - should we do anything besides log these?
                log(sm.getString("applicationContext.attributeEvent"), t);
            }
        }

    
voidsetAttributeReadOnly(java.lang.String name)
Set an attribute as read only.


        if (attributes.containsKey(name))
            readOnlyAttributes.put(name, name);