| /* |
| * Copyright 1999,2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| 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; |
| |
| import org.apache.catalina.security.SecurityUtil; |
| |
| |
| /** |
| * Facade object which masks the internal <code>ApplicationContext</code> |
| * object from the web application. |
| * |
| * @author Remy Maucherat |
| * @author Jean-Francois Arcand |
| * @version $Revision$ $Date$ |
| */ |
| |
| public final class ApplicationContextFacade |
| implements ServletContext { |
| |
| // ---------------------------------------------------------- Attributes |
| /** |
| * Cache Class object used for reflection. |
| */ |
| private HashMap classCache; |
| |
| |
| /** |
| * Cache method object. |
| */ |
| private HashMap objectCache; |
| |
| |
| // ----------------------------------------------------------- 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 (SecurityUtil.isPackageProtectionEnabled()) { |
| 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 (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String)doPrivileged("getMimeType", new Object[]{file}); |
| } else { |
| return context.getMimeType(file); |
| } |
| } |
| |
| |
| public Set getResourcePaths(String path) { |
| if (SecurityUtil.isPackageProtectionEnabled()){ |
| 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 (SecurityUtil.isPackageProtectionEnabled()) { |
| return (InputStream) doPrivileged("getResourceAsStream", |
| new Object[]{path}); |
| } else { |
| return context.getResourceAsStream(path); |
| } |
| } |
| |
| |
| public RequestDispatcher getRequestDispatcher(final String path) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (RequestDispatcher) doPrivileged("getRequestDispatcher", |
| new Object[]{path}); |
| } else { |
| return context.getRequestDispatcher(path); |
| } |
| } |
| |
| |
| public RequestDispatcher getNamedDispatcher(String name) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (RequestDispatcher) doPrivileged("getNamedDispatcher", |
| new Object[]{name}); |
| } else { |
| return context.getNamedDispatcher(name); |
| } |
| } |
| |
| |
| public Servlet getServlet(String name) |
| throws ServletException { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| 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 (SecurityUtil.isPackageProtectionEnabled()) { |
| return (Enumeration) doPrivileged("getServlets", null); |
| } else { |
| return context.getServlets(); |
| } |
| } |
| |
| |
| public Enumeration getServletNames() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (Enumeration) doPrivileged("getServletNames", null); |
| } else { |
| return context.getServletNames(); |
| } |
| } |
| |
| |
| public void log(String msg) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| doPrivileged("log", new Object[]{msg} ); |
| } else { |
| context.log(msg); |
| } |
| } |
| |
| |
| public void log(Exception exception, String msg) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| 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 (SecurityUtil.isPackageProtectionEnabled()) { |
| doPrivileged("log", new Class[]{String.class, Throwable.class}, |
| new Object[]{message, throwable}); |
| } else { |
| context.log(message, throwable); |
| } |
| } |
| |
| |
| public String getRealPath(String path) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String) doPrivileged("getRealPath", new Object[]{path}); |
| } else { |
| return context.getRealPath(path); |
| } |
| } |
| |
| |
| public String getServerInfo() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String) doPrivileged("getServerInfo", null); |
| } else { |
| return context.getServerInfo(); |
| } |
| } |
| |
| |
| public String getInitParameter(String name) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String) doPrivileged("getInitParameter", |
| new Object[]{name}); |
| } else { |
| return context.getInitParameter(name); |
| } |
| } |
| |
| |
| public Enumeration getInitParameterNames() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (Enumeration) doPrivileged("getInitParameterNames", null); |
| } else { |
| return context.getInitParameterNames(); |
| } |
| } |
| |
| |
| public Object getAttribute(String name) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return doPrivileged("getAttribute", new Object[]{name}); |
| } else { |
| return context.getAttribute(name); |
| } |
| } |
| |
| |
| public Enumeration getAttributeNames() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (Enumeration) doPrivileged("getAttributeNames", null); |
| } else { |
| return context.getAttributeNames(); |
| } |
| } |
| |
| |
| public void setAttribute(String name, Object object) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| doPrivileged("setAttribute", new Object[]{name,object}); |
| } else { |
| context.setAttribute(name, object); |
| } |
| } |
| |
| |
| public void removeAttribute(String name) { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| doPrivileged("removeAttribute", new Object[]{name}); |
| } else { |
| context.removeAttribute(name); |
| } |
| } |
| |
| |
| public String getServletContextName() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String) doPrivileged("getServletContextName", null); |
| } else { |
| return context.getServletContextName(); |
| } |
| } |
| |
| |
| public String getContextPath() { |
| if (SecurityUtil.isPackageProtectionEnabled()) { |
| return (String) doPrivileged("getContextPath", null); |
| } else { |
| return context.getContextPath(); |
| } |
| } |
| |
| |
| /** |
| * 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, |
| 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; |
| } finally { |
| params = null; |
| } |
| } |
| |
| /** |
| * Use reflection to invoke the requested method. Cache the method object |
| * to speed up the process |
| * @param methodName The method to invoke. |
| * @param clazz The class where the method is. |
| * @param params The arguments passed to the called method. |
| */ |
| private Object doPrivileged(final String methodName, |
| final Class[] clazz, |
| 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; |
| } finally { |
| params = 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 (SecurityUtil.isPackageProtectionEnabled()){ |
| 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 (ex instanceof PrivilegedActionException) { |
| ex = ((PrivilegedActionException) ex).getException(); |
| } |
| |
| if (ex instanceof InvocationTargetException) { |
| realException = |
| ((InvocationTargetException) ex).getTargetException(); |
| } else { |
| realException = ex; |
| } |
| |
| throw realException; |
| } |
| } |