001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.core;
018:
019: import java.io.InputStream;
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.net.MalformedURLException;
023: import java.net.URL;
024: import java.security.AccessController;
025: import java.security.PrivilegedActionException;
026: import java.security.PrivilegedExceptionAction;
027: import java.util.Enumeration;
028: import java.util.HashMap;
029: import java.util.Set;
030:
031: import javax.servlet.RequestDispatcher;
032: import javax.servlet.Servlet;
033: import javax.servlet.ServletContext;
034: import javax.servlet.ServletException;
035:
036: /**
037: * Facade object which masks the internal <code>ApplicationContext</code>
038: * object from the web application.
039: *
040: * @author Remy Maucherat
041: * @author Jean-Francois Arcand
042: * @version $Revision: 1.10 $ $Date: 2004/05/26 15:36:14 $
043: */
044:
045: public final class ApplicationContextFacade implements ServletContext {
046:
047: // ---------------------------------------------------------- Attributes
048: /**
049: * Cache Class object used for reflection.
050: */
051: private HashMap classCache;
052:
053: /**
054: * Cache method object.
055: */
056: private HashMap objectCache;
057:
058: private static org.apache.commons.logging.Log sysLog = org.apache.commons.logging.LogFactory
059: .getLog(ApplicationContextFacade.class);
060:
061: // ----------------------------------------------------------- Constructors
062:
063: /**
064: * Construct a new instance of this class, associated with the specified
065: * Context instance.
066: *
067: * @param context The associated Context instance
068: */
069: public ApplicationContextFacade(ApplicationContext context) {
070: super ();
071: this .context = context;
072:
073: classCache = new HashMap();
074: objectCache = new HashMap();
075: initClassCache();
076: }
077:
078: private void initClassCache() {
079: Class[] clazz = new Class[] { String.class };
080: classCache.put("getContext", clazz);
081: classCache.put("getMimeType", clazz);
082: classCache.put("getResourcePaths", clazz);
083: classCache.put("getResource", clazz);
084: classCache.put("getResourceAsStream", clazz);
085: classCache.put("getRequestDispatcher", clazz);
086: classCache.put("getNamedDispatcher", clazz);
087: classCache.put("getServlet", clazz);
088: classCache.put("getInitParameter", clazz);
089: classCache.put("setAttribute", new Class[] { String.class,
090: Object.class });
091: classCache.put("removeAttribute", clazz);
092: classCache.put("getRealPath", clazz);
093: classCache.put("getAttribute", clazz);
094: classCache.put("log", clazz);
095: }
096:
097: // ----------------------------------------------------- Instance Variables
098:
099: /**
100: * Wrapped application context.
101: */
102: private ApplicationContext context = null;
103:
104: // ------------------------------------------------- ServletContext Methods
105:
106: public ServletContext getContext(String uripath) {
107: ServletContext theContext = null;
108: if (System.getSecurityManager() != null) {
109: theContext = (ServletContext) doPrivileged("getContext",
110: new Object[] { uripath });
111: } else {
112: theContext = context.getContext(uripath);
113: }
114: if ((theContext != null)
115: && (theContext instanceof ApplicationContext)) {
116: theContext = ((ApplicationContext) theContext).getFacade();
117: }
118: return (theContext);
119: }
120:
121: public int getMajorVersion() {
122: return context.getMajorVersion();
123: }
124:
125: public int getMinorVersion() {
126: return context.getMinorVersion();
127: }
128:
129: public String getMimeType(String file) {
130: if (System.getSecurityManager() != null) {
131: return (String) doPrivileged("getMimeType",
132: new Object[] { file });
133: } else {
134: return context.getMimeType(file);
135: }
136: }
137:
138: public Set getResourcePaths(String path) {
139: if (System.getSecurityManager() != null) {
140: return (Set) doPrivileged("getResourcePaths",
141: new Object[] { path });
142: } else {
143: return context.getResourcePaths(path);
144: }
145: }
146:
147: public URL getResource(String path) throws MalformedURLException {
148: if (System.getSecurityManager() != null) {
149: try {
150: return (URL) invokeMethod(context, "getResource",
151: new Object[] { path });
152: } catch (Throwable t) {
153: if (t instanceof MalformedURLException) {
154: throw (MalformedURLException) t;
155: }
156: return null;
157: }
158: } else {
159: return context.getResource(path);
160: }
161: }
162:
163: public InputStream getResourceAsStream(String path) {
164: if (System.getSecurityManager() != null) {
165: return (InputStream) doPrivileged("getResourceAsStream",
166: new Object[] { path });
167: } else {
168: return context.getResourceAsStream(path);
169: }
170: }
171:
172: public RequestDispatcher getRequestDispatcher(final String path) {
173: if (System.getSecurityManager() != null) {
174: return (RequestDispatcher) doPrivileged(
175: "getRequestDispatcher", new Object[] { path });
176: } else {
177: return context.getRequestDispatcher(path);
178: }
179: }
180:
181: public RequestDispatcher getNamedDispatcher(String name) {
182: if (System.getSecurityManager() != null) {
183: return (RequestDispatcher) doPrivileged(
184: "getNamedDispatcher", new Object[] { name });
185: } else {
186: return context.getNamedDispatcher(name);
187: }
188: }
189:
190: public Servlet getServlet(String name) throws ServletException {
191: if (System.getSecurityManager() != null) {
192: try {
193: return (Servlet) invokeMethod(context, "getServlet",
194: new Object[] { name });
195: } catch (Throwable t) {
196: if (t instanceof ServletException) {
197: throw (ServletException) t;
198: }
199: return null;
200: }
201: } else {
202: return context.getServlet(name);
203: }
204: }
205:
206: public Enumeration getServlets() {
207: if (System.getSecurityManager() != null) {
208: return (Enumeration) doPrivileged("getServlets", null);
209: } else {
210: return context.getServlets();
211: }
212: }
213:
214: public Enumeration getServletNames() {
215: if (System.getSecurityManager() != null) {
216: return (Enumeration) doPrivileged("getServletNames", null);
217: } else {
218: return context.getServletNames();
219: }
220: }
221:
222: public void log(String msg) {
223: if (System.getSecurityManager() != null) {
224: doPrivileged("log", new Object[] { msg });
225: } else {
226: context.log(msg);
227: }
228: }
229:
230: public void log(Exception exception, String msg) {
231: if (System.getSecurityManager() != null) {
232: doPrivileged("log", new Class[] { Exception.class,
233: String.class }, new Object[] { exception, msg });
234: } else {
235: context.log(exception, msg);
236: }
237: }
238:
239: public void log(String message, Throwable throwable) {
240: if (System.getSecurityManager() != null) {
241: doPrivileged("log", new Class[] { String.class,
242: Throwable.class }, new Object[] { message,
243: throwable });
244: } else {
245: context.log(message, throwable);
246: }
247: }
248:
249: public String getRealPath(String path) {
250: if (System.getSecurityManager() != null) {
251: return (String) doPrivileged("getRealPath",
252: new Object[] { path });
253: } else {
254: return context.getRealPath(path);
255: }
256: }
257:
258: public String getServerInfo() {
259: if (System.getSecurityManager() != null) {
260: return (String) doPrivileged("getServerInfo", null);
261: } else {
262: return context.getServerInfo();
263: }
264: }
265:
266: public String getInitParameter(String name) {
267: if (System.getSecurityManager() != null) {
268: return (String) doPrivileged("getInitParameter",
269: new Object[] { name });
270: } else {
271: return context.getInitParameter(name);
272: }
273: }
274:
275: public Enumeration getInitParameterNames() {
276: if (System.getSecurityManager() != null) {
277: return (Enumeration) doPrivileged("getInitParameterNames",
278: null);
279: } else {
280: return context.getInitParameterNames();
281: }
282: }
283:
284: public Object getAttribute(String name) {
285: if (System.getSecurityManager() != null) {
286: return doPrivileged("getAttribute", new Object[] { name });
287: } else {
288: return context.getAttribute(name);
289: }
290: }
291:
292: public Enumeration getAttributeNames() {
293: if (System.getSecurityManager() != null) {
294: return (Enumeration) doPrivileged("getAttributeNames", null);
295: } else {
296: return context.getAttributeNames();
297: }
298: }
299:
300: public void setAttribute(String name, Object object) {
301: if (System.getSecurityManager() != null) {
302: doPrivileged("setAttribute", new Object[] { name, object });
303: } else {
304: context.setAttribute(name, object);
305: }
306: }
307:
308: public void removeAttribute(String name) {
309: if (System.getSecurityManager() != null) {
310: doPrivileged("removeAttribute", new Object[] { name });
311: } else {
312: context.removeAttribute(name);
313: }
314: }
315:
316: public String getServletContextName() {
317: if (System.getSecurityManager() != null) {
318: return (String) doPrivileged("getServletContextName", null);
319: } else {
320: return context.getServletContextName();
321: }
322: }
323:
324: /**
325: * Use reflection to invoke the requested method. Cache the method object
326: * to speed up the process
327: * @param appContext The AppliationContext object on which the method
328: * will be invoked
329: * @param methodName The method to call.
330: * @param params The arguments passed to the called method.
331: */
332: private Object doPrivileged(ApplicationContext appContext,
333: final String methodName, final Object[] params) {
334: try {
335: return invokeMethod(appContext, methodName, params);
336: } catch (Throwable t) {
337: throw new RuntimeException(t.getMessage());
338: }
339:
340: }
341:
342: /**
343: * Use reflection to invoke the requested method. Cache the method object
344: * to speed up the process
345: * will be invoked
346: * @param methodName The method to call.
347: * @param params The arguments passed to the called method.
348: */
349: private Object doPrivileged(final String methodName,
350: final Object[] params) {
351: try {
352: return invokeMethod(context, methodName, params);
353: } catch (Throwable t) {
354: throw new RuntimeException(t.getMessage());
355: }
356: }
357:
358: /**
359: * Use reflection to invoke the requested method. Cache the method object
360: * to speed up the process
361: * @param appContext The AppliationContext object on which the method
362: * will be invoked
363: * @param methodName The method to call.
364: * @param params The arguments passed to the called method.
365: */
366: private Object invokeMethod(ApplicationContext appContext,
367: final String methodName, final Object[] params)
368: throws Throwable {
369:
370: try {
371: Method method = (Method) objectCache.get(methodName);
372: if (method == null) {
373: method = appContext.getClass().getMethod(methodName,
374: (Class[]) classCache.get(methodName));
375: objectCache.put(methodName, method);
376: }
377:
378: return executeMethod(method, appContext, params);
379: } catch (Exception ex) {
380: handleException(ex, methodName);
381: return null;
382: }
383: }
384:
385: /**
386: * Use reflection to invoke the requested method. Cache the method object
387: * to speed up the process
388: * @param methodName The method to invoke.
389: * @param clazz The class where the method is.
390: * @param params The arguments passed to the called method.
391: */
392: private Object doPrivileged(final String methodName,
393: final Class[] clazz, final Object[] params) {
394:
395: try {
396: Method method = context.getClass().getMethod(methodName,
397: (Class[]) clazz);
398: return executeMethod(method, context, params);
399: } catch (Exception ex) {
400: try {
401: handleException(ex, methodName);
402: } catch (Throwable t) {
403: throw new RuntimeException(t.getMessage());
404: }
405: return null;
406: }
407: }
408:
409: /**
410: * Executes the method of the specified <code>ApplicationContext</code>
411: * @param method The method object to be invoked.
412: * @param context The AppliationContext object on which the method
413: * will be invoked
414: * @param params The arguments passed to the called method.
415: */
416: private Object executeMethod(final Method method,
417: final ApplicationContext context, final Object[] params)
418: throws PrivilegedActionException, IllegalAccessException,
419: InvocationTargetException {
420:
421: if (System.getSecurityManager() != null) {
422: return AccessController
423: .doPrivileged(new PrivilegedExceptionAction() {
424: public Object run()
425: throws IllegalAccessException,
426: InvocationTargetException {
427: return method.invoke(context, params);
428: }
429: });
430: } else {
431: return method.invoke(context, params);
432: }
433: }
434:
435: /**
436: * Throw the real exception.
437: * @param ex The current exception
438: */
439: private void handleException(Exception ex, String methodName)
440: throws Throwable {
441:
442: Throwable realException;
443:
444: if (sysLog.isDebugEnabled()) {
445: sysLog.debug("ApplicationContextFacade." + methodName, ex);
446: }
447:
448: if (ex instanceof PrivilegedActionException) {
449: ex = ((PrivilegedActionException) ex).getException();
450: }
451:
452: if (ex instanceof InvocationTargetException) {
453: realException = ((InvocationTargetException) ex)
454: .getTargetException();
455: } else {
456: realException = ex;
457: }
458:
459: throw realException;
460: }
461: }
|