FileDocCategorySizeDatePackage
ApplicationContext.javaAPI DocGlassfish v2 API36799Tue Jul 03 11:05:00 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: 1.15 $ $Date: 2007/07/03 18:05:00 $

Fields Summary
private static final SecurityPermission
GET_UNWRAPPED_CONTEXT_PERMISSION
private HashMap
attributes
The context attributes for this context.
private HashMap
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 HashMap
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 ArrayList
alternateDocBases
Alternate doc bases
private String
logPrefix
Log prefix string
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

        this(basePath, null, context);
    
public ApplicationContext(String basePath, ArrayList alternateDocBases, StandardContext context)

        super();
        this.context = context;
        this.basePath = basePath;
        this.alternateDocBases = alternateDocBases;

        //START PWC 6403328
        this.logPrefix = sm.getString("applicationContext.logPrefix",
                                      context.logName());
        //END PWC 6403328

        setAttribute("com.sun.faces.useMyFaces",
                     Boolean.valueOf(context.isUseMyFaces()));
    
Methods Summary
voidclearAttributes()
Clear all application-created attributes.


        // Create list of attributes to be removed
        ArrayList list = new ArrayList();
        synchronized (attributes) {
            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


        synchronized (attributes) {
            return (attributes.get(name));
        }

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


        synchronized (attributes) {
            return new Enumerator(attributes.keySet(), true);
        }

    
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()
Returns the context path of the web application.

The context path is the portion of the request URI that is used to select the context of the request. The context path always comes first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets in the default (root) context, this method returns "".

It is possible that a servlet container may match a context by more than one context path. In such cases the {@link javax.servlet.http.HttpServletRequest#getContextPath()} will return the actual context path used by the request and it may differ from the path returned by this method. The context path returned by this method should be considered as the prime or preferred context path of the application.

see
javax.servlet.http.HttpServletRequest#getContextPath()

        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();
        synchronized (parameters) {
            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();
        synchronized (parameters) {
           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);
    
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 = null;
        if (alternateDocBases == null
                || alternateDocBases.size() == 0) {
            file = new File(basePath, path);
        } else {
            AlternateDocBase match = AlternateDocBase.findMatch(
                                                path, alternateDocBases);
            if (match != null) {
                file = new File(match.getBasePath(), path);
            } else {
                // None of the url patterns for alternate doc bases matched
                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();
        }
 
        // Retrieve 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 = null;

            if (alternateDocBases == null
                    || alternateDocBases.size() == 0) {
                resources = context.getResources();
            } else {
                AlternateDocBase match = AlternateDocBase.findMatch(
                                                path, alternateDocBases);
                if (match != null) {
                    resources = match.getResources();
                } else {
                    // None of the url patterns for alternate doc bases matched
                    resources = context.getResources();
                }
            }

            if (resources != null) {
                String fullPath = context.getName() + path;
                String hostName = context.getParent().getName();
                try {
                    resources.lookup(path);
                    return new URL
                        /* SJSAS 6318494
                        ("jndi", null, 0, getJNDIUri(hostName, fullPath),
                         */
                        // START SJAS 6318494
                        ("jndi", "", 0, getJNDIUri(hostName, fullPath),
                        // END SJSAS 6318494
		         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 = null;

        if (alternateDocBases == null
                || alternateDocBases.size() == 0) {
            resources = context.getResources();
        } else {
            AlternateDocBase match = AlternateDocBase.findMatch(
                                path, alternateDocBases);
            if (match != null) {
                resources = match.getResources();
            } else {
                // None of the url patterns for alternate doc bases matched
                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 = null;

        if (alternateDocBases == null
                || alternateDocBases.size() == 0) {
            resources = context.getResources();
        } else {
            AlternateDocBase match = AlternateDocBase.findMatch(
                                path, alternateDocBases);
            if (match != null) {
                resources = match.getResources();
            } else {
                // None of the url patterns for alternate doc bases matched
                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));
    
public StandardContextgetUnwrappedContext()
Gets the underlying StandardContext to which this ApplicationContext is delegating.

return
The underlying StandardContext


        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(GET_UNWRAPPED_CONTEXT_PERMISSION);
        }

        return this.context;        
    
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());
        }

    
private static voidlistPaths(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();
            String childPath = path + "/" + name;
            set.add(childPath);
            Object object = binding.getObject();
            if (object instanceof DirContext) {
                listPaths(set, resources, childPath);
            }
        }

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

param
message Message to be written


        Logger logger = context.getLogger();
        if (logger != null) {
            /* PWC 6403328
            logger.log(context.logName() + message, Logger.INFORMATION);
            */
            //START PWC 6403328
            logger.log(this.logPrefix + message, Logger.INFORMATION);
            //END PWC 6403328
        }
    
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

        
        Logger logger = context.getLogger();
        if (logger != null)
            logger.log(exception, context.logName() + message);

    
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

        
        Logger logger = context.getLogger();
        if (logger != null)
            logger.log(context.logName() + 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;
        HashMap results = new HashMap();
        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
        synchronized (attributes) {
            // 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(
                    ContainerEvent.BEFORE_CONTEXT_ATTRIBUTE_REMOVED,
                    listener);
                listener.attributeRemoved(event);
                context.fireContainerEvent(
                    ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_REMOVED,
                    listener);
            } catch (Throwable t) {
                context.fireContainerEvent(
                    ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_REMOVED,
                    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
        synchronized (attributes) {
            // Check for read only attribute
            if (readOnlyAttributes.containsKey(name))
                return;
            oldValue = attributes.get(name);
            if (oldValue != null)
                replaced = true;
            attributes.put(name, value);
        }
        
        if ( name.equals(Globals.CLASS_PATH_ATTR)){
            setAttributeReadOnly(name);
        }
        
        // 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(
                        ContainerEvent.BEFORE_CONTEXT_ATTRIBUTE_REPLACED,
                        listener);
                    listener.attributeReplaced(event);
                    context.fireContainerEvent(
                        ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_REPLACED,
                        listener);
                } else {
                    context.fireContainerEvent(
                        ContainerEvent.BEFORE_CONTEXT_ATTRIBUTE_ADDED,
                        listener);
                    listener.attributeAdded(event);
                    context.fireContainerEvent(
                        ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_ADDED,
                        listener);
                }
            } catch (Throwable t) {
                if (replaced) {
                    context.fireContainerEvent(
                        ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_REPLACED,
                        listener);
                } else {
                    context.fireContainerEvent(
                        ContainerEvent.AFTER_CONTEXT_ATTRIBUTE_ADDED,
                        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.


        synchronized (attributes) {
            if (attributes.containsKey(name))
                readOnlyAttributes.put(name, name);
        }