org.apache.catalina.core.ApplicationContextFacade.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.catalina.core.ApplicationContextFacade.java

Source

/*
 * $Header: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/ApplicationContextFacade.java,v 1.8 2003/09/02 21:22:04 remm Exp $
 * $Revision: 1.8 $
 * $Date: 2003/09/02 21:22:04 $
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */

package org.apache.catalina.core;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

/**
 * Facade object which masks the internal <code>ApplicationContext</code>
 * object from the web application.
 *
 * @author Remy Maucherat
 * @author Jean-Francois Arcand
 * @version $Revision: 1.8 $ $Date: 2003/09/02 21:22:04 $
 */

public final class ApplicationContextFacade implements ServletContext {

    // ---------------------------------------------------------- Attributes
    /**
     * Cache Class object used for reflection.
     */
    private HashMap classCache;

    /**
     * Cache method object.
     */
    private HashMap objectCache;

    private static org.apache.commons.logging.Log sysLog = org.apache.commons.logging.LogFactory
            .getLog(ApplicationContextFacade.class);

    // ----------------------------------------------------------- Constructors

    /**
     * Construct a new instance of this class, associated with the specified
     * Context instance.
     *
     * @param context The associated Context instance
     */
    public ApplicationContextFacade(ApplicationContext context) {
        super();
        this.context = context;

        classCache = new HashMap();
        objectCache = new HashMap();
        initClassCache();
    }

    private void initClassCache() {
        Class[] clazz = new Class[] { String.class };
        classCache.put("getContext", clazz);
        classCache.put("getMimeType", clazz);
        classCache.put("getResourcePaths", clazz);
        classCache.put("getResource", clazz);
        classCache.put("getResourceAsStream", clazz);
        classCache.put("getRequestDispatcher", clazz);
        classCache.put("getNamedDispatcher", clazz);
        classCache.put("getServlet", clazz);
        classCache.put("getInitParameter", clazz);
        classCache.put("setAttribute", new Class[] { String.class, Object.class });
        classCache.put("removeAttribute", clazz);
        classCache.put("getRealPath", clazz);
        classCache.put("getAttribute", clazz);
        classCache.put("log", clazz);
    }

    // ----------------------------------------------------- Instance Variables

    /**
     * Wrapped application context.
     */
    private ApplicationContext context = null;

    // ------------------------------------------------- ServletContext Methods

    public ServletContext getContext(String uripath) {
        ServletContext theContext = null;
        if (System.getSecurityManager() != null) {
            theContext = (ServletContext) doPrivileged("getContext", new Object[] { uripath });
        } else {
            theContext = context.getContext(uripath);
        }
        if ((theContext != null) && (theContext instanceof ApplicationContext)) {
            theContext = ((ApplicationContext) theContext).getFacade();
        }
        return (theContext);
    }

    public int getMajorVersion() {
        return context.getMajorVersion();
    }

    public int getMinorVersion() {
        return context.getMinorVersion();
    }

    public String getMimeType(String file) {
        if (System.getSecurityManager() != null) {
            return (String) doPrivileged("getMimeType", new Object[] { file });
        } else {
            return context.getMimeType(file);
        }
    }

    public Set getResourcePaths(String path) {
        if (System.getSecurityManager() != null) {
            return (Set) doPrivileged("getResourcePaths", new Object[] { path });
        } else {
            return context.getResourcePaths(path);
        }
    }

    public URL getResource(String path) throws MalformedURLException {
        if (System.getSecurityManager() != null) {
            try {
                return (URL) invokeMethod(context, "getResource", new Object[] { path });
            } catch (Throwable t) {
                if (t instanceof MalformedURLException) {
                    throw (MalformedURLException) t;
                }
                return null;
            }
        } else {
            return context.getResource(path);
        }
    }

    public InputStream getResourceAsStream(String path) {
        if (System.getSecurityManager() != null) {
            return (InputStream) doPrivileged("getResourceAsStream", new Object[] { path });
        } else {
            return context.getResourceAsStream(path);
        }
    }

    public RequestDispatcher getRequestDispatcher(final String path) {
        if (System.getSecurityManager() != null) {
            return (RequestDispatcher) doPrivileged("getRequestDispatcher", new Object[] { path });
        } else {
            return context.getRequestDispatcher(path);
        }
    }

    public RequestDispatcher getNamedDispatcher(String name) {
        if (System.getSecurityManager() != null) {
            return (RequestDispatcher) doPrivileged("getNamedDispatcher", new Object[] { name });
        } else {
            return context.getNamedDispatcher(name);
        }
    }

    public Servlet getServlet(String name) throws ServletException {
        if (System.getSecurityManager() != null) {
            try {
                return (Servlet) invokeMethod(context, "getServlet", new Object[] { name });
            } catch (Throwable t) {
                if (t instanceof ServletException) {
                    throw (ServletException) t;
                }
                return null;
            }
        } else {
            return context.getServlet(name);
        }
    }

    public Enumeration getServlets() {
        if (System.getSecurityManager() != null) {
            return (Enumeration) doPrivileged("getServlets", null);
        } else {
            return context.getServlets();
        }
    }

    public Enumeration getServletNames() {
        if (System.getSecurityManager() != null) {
            return (Enumeration) doPrivileged("getServletNames", null);
        } else {
            return context.getServletNames();
        }
    }

    public void log(String msg) {
        if (System.getSecurityManager() != null) {
            doPrivileged("log", new Object[] { msg });
        } else {
            context.log(msg);
        }
    }

    public void log(Exception exception, String msg) {
        if (System.getSecurityManager() != null) {
            doPrivileged("log", new Class[] { Exception.class, String.class }, new Object[] { exception, msg });
        } else {
            context.log(exception, msg);
        }
    }

    public void log(String message, Throwable throwable) {
        if (System.getSecurityManager() != null) {
            doPrivileged("log", new Class[] { String.class, Throwable.class }, new Object[] { message, throwable });
        } else {
            context.log(message, throwable);
        }
    }

    public String getRealPath(String path) {
        if (System.getSecurityManager() != null) {
            return (String) doPrivileged("getRealPath", new Object[] { path });
        } else {
            return context.getRealPath(path);
        }
    }

    public String getServerInfo() {
        if (System.getSecurityManager() != null) {
            return (String) doPrivileged("getServerInfo", null);
        } else {
            return context.getServerInfo();
        }
    }

    public String getInitParameter(String name) {
        if (System.getSecurityManager() != null) {
            return (String) doPrivileged("getInitParameter", new Object[] { name });
        } else {
            return context.getInitParameter(name);
        }
    }

    public Enumeration getInitParameterNames() {
        if (System.getSecurityManager() != null) {
            return (Enumeration) doPrivileged("getInitParameterNames", null);
        } else {
            return context.getInitParameterNames();
        }
    }

    public Object getAttribute(String name) {
        if (System.getSecurityManager() != null) {
            return doPrivileged("getAttribute", new Object[] { name });
        } else {
            return context.getAttribute(name);
        }
    }

    public Enumeration getAttributeNames() {
        if (System.getSecurityManager() != null) {
            return (Enumeration) doPrivileged("getAttributeNames", null);
        } else {
            return context.getAttributeNames();
        }
    }

    public void setAttribute(String name, Object object) {
        if (System.getSecurityManager() != null) {
            doPrivileged("setAttribute", new Object[] { name, object });
        } else {
            context.setAttribute(name, object);
        }
    }

    public void removeAttribute(String name) {
        if (System.getSecurityManager() != null) {
            doPrivileged("removeAttribute", new Object[] { name });
        } else {
            context.removeAttribute(name);
        }
    }

    public String getServletContextName() {
        if (System.getSecurityManager() != null) {
            return (String) doPrivileged("getServletContextName", null);
        } else {
            return context.getServletContextName();
        }
    }

    /**
     * Use reflection to invoke the requested method. Cache the method object 
     * to speed up the process
     * @param appContext The AppliationContext object on which the method
     *                   will be invoked
     * @param methodName The method to call.
     * @param params The arguments passed to the called method.
     */
    private Object doPrivileged(ApplicationContext appContext, final String methodName, final Object[] params) {
        try {
            return invokeMethod(appContext, methodName, params);
        } catch (Throwable t) {
            throw new RuntimeException(t.getMessage());
        }

    }

    /**
     * Use reflection to invoke the requested method. Cache the method object 
     * to speed up the process
     *                   will be invoked
     * @param methodName The method to call.
     * @param params The arguments passed to the called method.
     */
    private Object doPrivileged(final String methodName, final Object[] params) {
        try {
            return invokeMethod(context, methodName, params);
        } catch (Throwable t) {
            throw new RuntimeException(t.getMessage());
        }
    }

    /**
     * Use reflection to invoke the requested method. Cache the method object 
     * to speed up the process
     * @param appContext The AppliationContext object on which the method
     *                   will be invoked
     * @param methodName The method to call.
     * @param params The arguments passed to the called method.
     */
    private Object invokeMethod(ApplicationContext appContext, final String methodName, final Object[] params)
            throws Throwable {

        try {
            Method method = (Method) objectCache.get(methodName);
            if (method == null) {
                method = appContext.getClass().getMethod(methodName, (Class[]) classCache.get(methodName));
                objectCache.put(methodName, method);
            }

            return executeMethod(method, appContext, params);
        } catch (Exception ex) {
            handleException(ex, methodName);
            return null;
        }
    }

    /**
     * Use reflection to invoke the requested method. Cache the method object 
     * to speed up the process
     * @param appContext The AppliationContext object on which the method
     *                   will be invoked
     * @param methodName The method to call.
     * @param params The arguments passed to the called method.
     */
    private Object doPrivileged(final String methodName, final Class[] clazz, final Object[] params) {

        try {
            Method method = context.getClass().getMethod(methodName, (Class[]) clazz);
            return executeMethod(method, context, params);
        } catch (Exception ex) {
            try {
                handleException(ex, methodName);
            } catch (Throwable t) {
                throw new RuntimeException(t.getMessage());
            }
            return null;
        }
    }

    /**
     * Executes the method of the specified <code>ApplicationContext</code>
     * @param method The method object to be invoked.
     * @param context The AppliationContext object on which the method
     *                   will be invoked
     * @param params The arguments passed to the called method.
     */
    private Object executeMethod(final Method method, final ApplicationContext context, final Object[] params)
            throws PrivilegedActionException, IllegalAccessException, InvocationTargetException {

        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged(new PrivilegedExceptionAction() {
                public Object run() throws IllegalAccessException, InvocationTargetException {
                    return method.invoke(context, params);
                }
            });
        } else {
            return method.invoke(context, params);
        }
    }

    /**
     * Throw the real exception.
     * @param ex The current exception
     */
    private void handleException(Exception ex, String methodName) throws Throwable {

        Throwable realException;

        if (sysLog.isDebugEnabled()) {
            sysLog.debug("ApplicationContextFacade." + methodName, ex);
        }

        if (ex instanceof PrivilegedActionException) {
            ex = ((PrivilegedActionException) ex).getException();
        }

        if (ex instanceof InvocationTargetException) {
            realException = ((InvocationTargetException) ex).getTargetException();
        } else {
            realException = ex;
        }

        throw realException;
    }
}