1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.core;
20
21
22 import java.io.InputStream;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.security.AccessController;
28 import java.security.PrivilegedActionException;
29 import java.security.PrivilegedExceptionAction;
30 import java.util.Enumeration;
31 import java.util.EventListener;
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.concurrent.ConcurrentHashMap;
36
37 import javax.servlet.Filter;
38 import javax.servlet.FilterRegistration;
39 import javax.servlet.RequestDispatcher;
40 import javax.servlet.Servlet;
41 import javax.servlet.ServletContext;
42 import javax.servlet.ServletException;
43 import javax.servlet.ServletRegistration;
44 import javax.servlet.ServletRegistration.Dynamic;
45 import javax.servlet.SessionCookieConfig;
46 import javax.servlet.SessionTrackingMode;
47 import javax.servlet.descriptor.JspConfigDescriptor;
48
49 import org.apache.catalina.Globals;
50 import org.apache.catalina.security.SecurityUtil;
51 import org.apache.tomcat.util.ExceptionUtils;
52
53
54 /**
55  * Facade object which masks the internal <code>ApplicationContext</code>
56  * object from the web application.
57  *
58  * @author Remy Maucherat
59  */

60 public class ApplicationContextFacade implements ServletContext {
61
62     // ---------------------------------------------------------- Attributes
63     /**
64      * Cache Class object used for reflection.
65      */

66     private final Map<String,Class<?>[]> classCache;
67
68
69     /**
70      * Cache method object.
71      */

72     private final Map<String,Method> objectCache;
73
74
75     // ----------------------------------------------------------- Constructors
76
77
78     /**
79      * Construct a new instance of this class, associated with the specified
80      * Context instance.
81      *
82      * @param context The associated Context instance
83      */

84     public ApplicationContextFacade(ApplicationContext context) {
85         super();
86         this.context = context;
87
88         classCache = new HashMap<>();
89         objectCache = new ConcurrentHashMap<>();
90         initClassCache();
91     }
92
93
94     private void initClassCache(){
95         Class<?>[] clazz = new Class[]{String.class};
96         classCache.put("getContext", clazz);
97         classCache.put("getMimeType", clazz);
98         classCache.put("getResourcePaths", clazz);
99         classCache.put("getResource", clazz);
100         classCache.put("getResourceAsStream", clazz);
101         classCache.put("getRequestDispatcher", clazz);
102         classCache.put("getNamedDispatcher", clazz);
103         classCache.put("getServlet", clazz);
104         classCache.put("setInitParameter"new Class[]{String.class, String.class});
105         classCache.put("createServlet"new Class[]{Class.class});
106         classCache.put("addServlet"new Class[]{String.class, String.class});
107         classCache.put("createFilter"new Class[]{Class.class});
108         classCache.put("addFilter"new Class[]{String.class, String.class});
109         classCache.put("createListener"new Class[]{Class.class});
110         classCache.put("addListener", clazz);
111         classCache.put("getFilterRegistration", clazz);
112         classCache.put("getServletRegistration", clazz);
113         classCache.put("getInitParameter", clazz);
114         classCache.put("setAttribute"new Class[]{String.class, Object.class});
115         classCache.put("removeAttribute", clazz);
116         classCache.put("getRealPath", clazz);
117         classCache.put("getAttribute", clazz);
118         classCache.put("log", clazz);
119         classCache.put("setSessionTrackingModes"new Class[]{Set.class} );
120     }
121
122
123     // ----------------------------------------------------- Instance Variables
124
125
126     /**
127      * Wrapped application context.
128      */

129     private final ApplicationContext context;
130
131
132     // ------------------------------------------------- ServletContext Methods
133
134
135     @Override
136     public ServletContext getContext(String uripath) {
137         ServletContext theContext = null;
138         if (SecurityUtil.isPackageProtectionEnabled()) {
139             theContext = (ServletContext)
140                 doPrivileged("getContext"new Object[]{uripath});
141         } else {
142             theContext = context.getContext(uripath);
143         }
144         if ((theContext != null) &&
145             (theContext instanceof ApplicationContext)){
146             theContext = ((ApplicationContext)theContext).getFacade();
147         }
148         return theContext;
149     }
150
151
152     @Override
153     public int getMajorVersion() {
154         return context.getMajorVersion();
155     }
156
157
158     @Override
159     public int getMinorVersion() {
160         return context.getMinorVersion();
161     }
162
163
164     @Override
165     public String getMimeType(String file) {
166         if (SecurityUtil.isPackageProtectionEnabled()) {
167             return (String)doPrivileged("getMimeType"new Object[]{file});
168         } else {
169             return context.getMimeType(file);
170         }
171     }
172
173     @Override
174     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
175     public Set<String> getResourcePaths(String path) {
176         if (SecurityUtil.isPackageProtectionEnabled()){
177             return (Set<String>)doPrivileged("getResourcePaths",
178                     new Object[]{path});
179         } else {
180             return context.getResourcePaths(path);
181         }
182     }
183
184
185     @Override
186     public URL getResource(String path)
187         throws MalformedURLException {
188         if (Globals.IS_SECURITY_ENABLED) {
189             try {
190                 return (URL) invokeMethod(context, "getResource",
191                                           new Object[]{path});
192             } catch(Throwable t) {
193                 ExceptionUtils.handleThrowable(t);
194                 if (t instanceof MalformedURLException){
195                     throw (MalformedURLException)t;
196                 }
197                 return null;
198             }
199         } else {
200             return context.getResource(path);
201         }
202     }
203
204
205     @Override
206     public InputStream getResourceAsStream(String path) {
207         if (SecurityUtil.isPackageProtectionEnabled()) {
208             return (InputStream) doPrivileged("getResourceAsStream",
209                                               new Object[]{path});
210         } else {
211             return context.getResourceAsStream(path);
212         }
213     }
214
215
216     @Override
217     public RequestDispatcher getRequestDispatcher(final String path) {
218         if (SecurityUtil.isPackageProtectionEnabled()) {
219             return (RequestDispatcher) doPrivileged("getRequestDispatcher",
220                                                     new Object[]{path});
221         } else {
222             return context.getRequestDispatcher(path);
223         }
224     }
225
226
227     @Override
228     public RequestDispatcher getNamedDispatcher(String name) {
229         if (SecurityUtil.isPackageProtectionEnabled()) {
230             return (RequestDispatcher) doPrivileged("getNamedDispatcher",
231                                                     new Object[]{name});
232         } else {
233             return context.getNamedDispatcher(name);
234         }
235     }
236
237
238     /**
239      * @deprecated As of Java Servlet API 2.1, with no direct replacement.
240      */

241     @Override
242     @Deprecated
243     public Servlet getServlet(String name)
244         throws ServletException {
245         if (SecurityUtil.isPackageProtectionEnabled()) {
246             try {
247                 return (Servlet) invokeMethod(context, "getServlet",
248                                               new Object[]{name});
249             } catch (Throwable t) {
250                 ExceptionUtils.handleThrowable(t);
251                 if (t instanceof ServletException) {
252                     throw (ServletException) t;
253                 }
254                 return null;
255             }
256         } else {
257             return context.getServlet(name);
258         }
259     }
260
261
262     /**
263      * @deprecated As of Java Servlet API 2.1, with no direct replacement.
264      */

265     @Override
266     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
267     @Deprecated
268     public Enumeration<Servlet> getServlets() {
269         if (SecurityUtil.isPackageProtectionEnabled()) {
270             return (Enumeration<Servlet>) doPrivileged("getServlets"null);
271         } else {
272             return context.getServlets();
273         }
274     }
275
276
277     /**
278      * @deprecated As of Java Servlet API 2.1, with no direct replacement.
279      */

280     @Override
281     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
282     @Deprecated
283     public Enumeration<String> getServletNames() {
284         if (SecurityUtil.isPackageProtectionEnabled()) {
285             return (Enumeration<String>) doPrivileged("getServletNames"null);
286         } else {
287             return context.getServletNames();
288         }
289    }
290
291
292     @Override
293     public void log(String msg) {
294         if (SecurityUtil.isPackageProtectionEnabled()) {
295             doPrivileged("log"new Object[]{msg} );
296         } else {
297             context.log(msg);
298         }
299     }
300
301
302     /**
303      * @deprecated As of Java Servlet API 2.1, use
304      *  <code>log(String, Throwable)</code> instead
305      */

306     @Override
307     @Deprecated
308     public void log(Exception exception, String msg) {
309         if (SecurityUtil.isPackageProtectionEnabled()) {
310             doPrivileged("log"new Class[]{Exception.class, String.class},
311                          new Object[]{exception,msg});
312         } else {
313             context.log(exception, msg);
314         }
315     }
316
317
318     @Override
319     public void log(String message, Throwable throwable) {
320         if (SecurityUtil.isPackageProtectionEnabled()) {
321             doPrivileged("log"new Class[]{String.class, Throwable.class},
322                          new Object[]{message, throwable});
323         } else {
324             context.log(message, throwable);
325         }
326     }
327
328
329     @Override
330     public String getRealPath(String path) {
331         if (SecurityUtil.isPackageProtectionEnabled()) {
332             return (String) doPrivileged("getRealPath"new Object[]{path});
333         } else {
334             return context.getRealPath(path);
335         }
336     }
337
338
339     @Override
340     public String getServerInfo() {
341         if (SecurityUtil.isPackageProtectionEnabled()) {
342             return (String) doPrivileged("getServerInfo"null);
343         } else {
344             return context.getServerInfo();
345         }
346     }
347
348
349     @Override
350     public String getInitParameter(String name) {
351         if (SecurityUtil.isPackageProtectionEnabled()) {
352             return (String) doPrivileged("getInitParameter",
353                                          new Object[]{name});
354         } else {
355             return context.getInitParameter(name);
356         }
357     }
358
359
360     @Override
361     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
362     public Enumeration<String> getInitParameterNames() {
363         if (SecurityUtil.isPackageProtectionEnabled()) {
364             return (Enumeration<String>) doPrivileged(
365                     "getInitParameterNames"null);
366         } else {
367             return context.getInitParameterNames();
368         }
369     }
370
371
372     @Override
373     public Object getAttribute(String name) {
374         if (SecurityUtil.isPackageProtectionEnabled()) {
375             return doPrivileged("getAttribute"new Object[]{name});
376         } else {
377             return context.getAttribute(name);
378         }
379      }
380
381
382     @Override
383     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
384     public Enumeration<String> getAttributeNames() {
385         if (SecurityUtil.isPackageProtectionEnabled()) {
386             return (Enumeration<String>) doPrivileged(
387                     "getAttributeNames"null);
388         } else {
389             return context.getAttributeNames();
390         }
391     }
392
393
394     @Override
395     public void setAttribute(String name, Object object) {
396         if (SecurityUtil.isPackageProtectionEnabled()) {
397             doPrivileged("setAttribute"new Object[]{name,object});
398         } else {
399             context.setAttribute(name, object);
400         }
401     }
402
403
404     @Override
405     public void removeAttribute(String name) {
406         if (SecurityUtil.isPackageProtectionEnabled()) {
407             doPrivileged("removeAttribute"new Object[]{name});
408         } else {
409             context.removeAttribute(name);
410         }
411     }
412
413
414     @Override
415     public String getServletContextName() {
416         if (SecurityUtil.isPackageProtectionEnabled()) {
417             return (String) doPrivileged("getServletContextName"null);
418         } else {
419             return context.getServletContextName();
420         }
421     }
422
423
424     @Override
425     public String getContextPath() {
426         if (SecurityUtil.isPackageProtectionEnabled()) {
427             return (String) doPrivileged("getContextPath"null);
428         } else {
429             return context.getContextPath();
430         }
431     }
432
433
434     @Override
435     public FilterRegistration.Dynamic addFilter(String filterName,
436             String className) {
437         if (SecurityUtil.isPackageProtectionEnabled()) {
438             return (FilterRegistration.Dynamic) doPrivileged(
439                     "addFilter"new Object[]{filterName, className});
440         } else {
441             return context.addFilter(filterName, className);
442         }
443     }
444
445
446     @Override
447     public FilterRegistration.Dynamic addFilter(String filterName,
448             Filter filter) {
449         if (SecurityUtil.isPackageProtectionEnabled()) {
450             return (FilterRegistration.Dynamic) doPrivileged("addFilter",
451                     new Class[]{String.class, Filter.class},
452                     new Object[]{filterName, filter});
453         } else {
454             return context.addFilter(filterName, filter);
455         }
456     }
457
458
459     @Override
460     public FilterRegistration.Dynamic addFilter(String filterName,
461             Class<? extends Filter> filterClass) {
462         if (SecurityUtil.isPackageProtectionEnabled()) {
463             return (FilterRegistration.Dynamic) doPrivileged("addFilter",
464                     new Class[]{String.class, Class.class},
465                     new Object[]{filterName, filterClass});
466         } else {
467             return context.addFilter(filterName, filterClass);
468         }
469     }
470
471     @Override
472     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
473     public <T extends Filter> T createFilter(Class<T> c)
474     throws ServletException {
475         if (SecurityUtil.isPackageProtectionEnabled()) {
476             try {
477                 return (T) invokeMethod(context, "createFilter",
478                                               new Object[]{c});
479             } catch (Throwable t) {
480                 ExceptionUtils.handleThrowable(t);
481                 if (t instanceof ServletException) {
482                     throw (ServletException) t;
483                 }
484                 return null;
485             }
486         } else {
487             return context.createFilter(c);
488         }
489     }
490
491
492     @Override
493     public FilterRegistration getFilterRegistration(String filterName) {
494         if (SecurityUtil.isPackageProtectionEnabled()) {
495             return (FilterRegistration) doPrivileged(
496                     "getFilterRegistration"new Object[]{filterName});
497         } else {
498             return context.getFilterRegistration(filterName);
499         }
500     }
501
502
503     @Override
504     public ServletRegistration.Dynamic addServlet(String servletName,
505             String className) {
506         if (SecurityUtil.isPackageProtectionEnabled()) {
507             return (ServletRegistration.Dynamic) doPrivileged(
508                     "addServlet"new Object[]{servletName, className});
509         } else {
510             return context.addServlet(servletName, className);
511         }
512     }
513
514
515     @Override
516     public ServletRegistration.Dynamic addServlet(String servletName,
517             Servlet servlet) {
518         if (SecurityUtil.isPackageProtectionEnabled()) {
519             return (ServletRegistration.Dynamic) doPrivileged("addServlet",
520                     new Class[]{String.class, Servlet.class},
521                     new Object[]{servletName, servlet});
522         } else {
523             return context.addServlet(servletName, servlet);
524         }
525     }
526
527
528     @Override
529     public ServletRegistration.Dynamic addServlet(String servletName,
530             Class<? extends Servlet> servletClass) {
531         if (SecurityUtil.isPackageProtectionEnabled()) {
532             return (ServletRegistration.Dynamic) doPrivileged("addServlet",
533                     new Class[]{String.class, Class.class},
534                     new Object[]{servletName, servletClass});
535         } else {
536             return context.addServlet(servletName, servletClass);
537         }
538     }
539
540
541     @Override
542     public Dynamic addJspFile(String jspName, String jspFile) {
543         if (SecurityUtil.isPackageProtectionEnabled()) {
544             return (ServletRegistration.Dynamic) doPrivileged("addJspFile",
545                     new Object[]{jspName, jspFile});
546         } else {
547             return context.addJspFile(jspName, jspFile);
548         }
549     }
550
551
552     @Override
553     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
554     public <T extends Servlet> T createServlet(Class<T> c)
555     throws ServletException {
556         if (SecurityUtil.isPackageProtectionEnabled()) {
557             try {
558                 return (T) invokeMethod(context, "createServlet",
559                                               new Object[]{c});
560             } catch (Throwable t) {
561                 ExceptionUtils.handleThrowable(t);
562                 if (t instanceof ServletException) {
563                     throw (ServletException) t;
564                 }
565                 return null;
566             }
567         } else {
568             return context.createServlet(c);
569         }
570     }
571
572
573     @Override
574     public ServletRegistration getServletRegistration(String servletName) {
575         if (SecurityUtil.isPackageProtectionEnabled()) {
576             return (ServletRegistration) doPrivileged(
577                     "getServletRegistration"new Object[]{servletName});
578         } else {
579             return context.getServletRegistration(servletName);
580         }
581     }
582
583
584     @Override
585     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
586     public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
587         if (SecurityUtil.isPackageProtectionEnabled()) {
588             return (Set<SessionTrackingMode>)
589                 doPrivileged("getDefaultSessionTrackingModes"null);
590         } else {
591             return context.getDefaultSessionTrackingModes();
592         }
593     }
594
595     @Override
596     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
597     public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
598         if (SecurityUtil.isPackageProtectionEnabled()) {
599             return (Set<SessionTrackingMode>)
600                 doPrivileged("getEffectiveSessionTrackingModes"null);
601         } else {
602             return context.getEffectiveSessionTrackingModes();
603         }
604     }
605
606
607     @Override
608     public SessionCookieConfig getSessionCookieConfig() {
609         if (SecurityUtil.isPackageProtectionEnabled()) {
610             return (SessionCookieConfig)
611                 doPrivileged("getSessionCookieConfig"null);
612         } else {
613             return context.getSessionCookieConfig();
614         }
615     }
616
617
618     @Override
619     public void setSessionTrackingModes(
620             Set<SessionTrackingMode> sessionTrackingModes) {
621         if (SecurityUtil.isPackageProtectionEnabled()) {
622             doPrivileged("setSessionTrackingModes",
623                     new Object[]{sessionTrackingModes});
624         } else {
625             context.setSessionTrackingModes(sessionTrackingModes);
626         }
627     }
628
629
630     @Override
631     public boolean setInitParameter(String name, String value) {
632         if (SecurityUtil.isPackageProtectionEnabled()) {
633             return ((Boolean) doPrivileged("setInitParameter",
634                     new Object[]{name, value})).booleanValue();
635         } else {
636             return context.setInitParameter(name, value);
637         }
638     }
639
640
641     @Override
642     public void addListener(Class<? extends EventListener> listenerClass) {
643         if (SecurityUtil.isPackageProtectionEnabled()) {
644             doPrivileged("addListener",
645                     new Class[]{Class.class},
646                     new Object[]{listenerClass});
647         } else {
648             context.addListener(listenerClass);
649         }
650     }
651
652
653     @Override
654     public void addListener(String className) {
655         if (SecurityUtil.isPackageProtectionEnabled()) {
656             doPrivileged("addListener",
657                     new Object[]{className});
658         } else {
659             context.addListener(className);
660         }
661     }
662
663
664     @Override
665     public <T extends EventListener> void addListener(T t) {
666         if (SecurityUtil.isPackageProtectionEnabled()) {
667             doPrivileged("addListener",
668                     new Class[]{EventListener.class},
669                     new Object[]{t});
670         } else {
671             context.addListener(t);
672         }
673     }
674
675
676     @Override
677     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
678     public <T extends EventListener> T createListener(Class<T> c)
679             throws ServletException {
680         if (SecurityUtil.isPackageProtectionEnabled()) {
681             try {
682                 return (T) invokeMethod(context, "createListener",
683                                               new Object[]{c});
684             } catch (Throwable t) {
685                 ExceptionUtils.handleThrowable(t);
686                 if (t instanceof ServletException) {
687                     throw (ServletException) t;
688                 }
689                 return null;
690             }
691         } else {
692             return context.createListener(c);
693         }
694     }
695
696
697     @Override
698     public void declareRoles(String... roleNames) {
699         if (SecurityUtil.isPackageProtectionEnabled()) {
700             doPrivileged("declareRoles"new Object[]{roleNames});
701         } else {
702             context.declareRoles(roleNames);
703         }
704     }
705
706
707     @Override
708     public ClassLoader getClassLoader() {
709         if (SecurityUtil.isPackageProtectionEnabled()) {
710             return (ClassLoader) doPrivileged("getClassLoader"null);
711         } else {
712             return context.getClassLoader();
713         }
714     }
715
716
717     @Override
718     public int getEffectiveMajorVersion() {
719         if (SecurityUtil.isPackageProtectionEnabled()) {
720             return ((Integer) doPrivileged("getEffectiveMajorVersion",
721                     null)).intValue();
722         } else  {
723             return context.getEffectiveMajorVersion();
724         }
725     }
726
727
728     @Override
729     public int getEffectiveMinorVersion() {
730         if (SecurityUtil.isPackageProtectionEnabled()) {
731             return ((Integer) doPrivileged("getEffectiveMinorVersion",
732                     null)).intValue();
733         } else  {
734             return context.getEffectiveMinorVersion();
735         }
736     }
737
738
739     @Override
740     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
741     public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
742         if (SecurityUtil.isPackageProtectionEnabled()) {
743             return (Map<String, ? extends FilterRegistration>) doPrivileged(
744                     "getFilterRegistrations"null);
745         } else {
746             return context.getFilterRegistrations();
747         }
748     }
749
750
751     @Override
752     public JspConfigDescriptor getJspConfigDescriptor() {
753         if (SecurityUtil.isPackageProtectionEnabled()) {
754             return (JspConfigDescriptor) doPrivileged("getJspConfigDescriptor",
755                     null);
756         } else {
757             return context.getJspConfigDescriptor();
758         }
759     }
760
761
762     @Override
763     @SuppressWarnings("unchecked"// doPrivileged() returns the correct type
764     public Map<String, ? extends ServletRegistration> getServletRegistrations() {
765         if (SecurityUtil.isPackageProtectionEnabled()) {
766             return (Map<String, ? extends ServletRegistration>) doPrivileged(
767                     "getServletRegistrations"null);
768         } else {
769             return context.getServletRegistrations();
770         }
771     }
772
773
774     @Override
775     public String getVirtualServerName() {
776         if (SecurityUtil.isPackageProtectionEnabled()) {
777             return (String) doPrivileged("getVirtualServerName"null);
778         } else  {
779             return context.getVirtualServerName();
780         }
781     }
782
783
784     @Override
785     public int getSessionTimeout() {
786         if (SecurityUtil.isPackageProtectionEnabled()) {
787             return ((Integer) doPrivileged("getSessionTimeout"null)).intValue();
788         } else  {
789             return context.getSessionTimeout();
790         }
791     }
792
793
794     @Override
795     public void setSessionTimeout(int sessionTimeout) {
796         if (SecurityUtil.isPackageProtectionEnabled()) {
797             doPrivileged("setSessionTimeout"new Object[] { Integer.valueOf(sessionTimeout) });
798         } else  {
799             context.setSessionTimeout(sessionTimeout);
800         }
801     }
802
803
804     @Override
805     public String getRequestCharacterEncoding() {
806         if (SecurityUtil.isPackageProtectionEnabled()) {
807             return (String) doPrivileged("getRequestCharacterEncoding"null);
808         } else  {
809             return context.getRequestCharacterEncoding();
810         }
811     }
812
813
814     @Override
815     public void setRequestCharacterEncoding(String encoding) {
816         if (SecurityUtil.isPackageProtectionEnabled()) {
817             doPrivileged("setRequestCharacterEncoding"new Object[] { encoding });
818         } else  {
819             context.setRequestCharacterEncoding(encoding);
820         }
821     }
822
823
824     @Override
825     public String getResponseCharacterEncoding() {
826         if (SecurityUtil.isPackageProtectionEnabled()) {
827             return (String) doPrivileged("getResponseCharacterEncoding"null);
828         } else  {
829             return context.getResponseCharacterEncoding();
830         }
831     }
832
833
834     @Override
835     public void setResponseCharacterEncoding(String encoding) {
836         if (SecurityUtil.isPackageProtectionEnabled()) {
837             doPrivileged("setResponseCharacterEncoding"new Object[] { encoding });
838         } else  {
839             context.setResponseCharacterEncoding(encoding);
840         }
841     }
842
843
844     /**
845      * Use reflection to invoke the requested method. Cache the method object
846      * to speed up the process
847      * @param methodName The method to call.
848      * @param params The arguments passed to the called method.
849      */

850     private Object doPrivileged(final String methodName, final Object[] params) {
851         try{
852             return invokeMethod(context, methodName, params);
853         }catch(Throwable t){
854             ExceptionUtils.handleThrowable(t);
855             throw new RuntimeException(t.getMessage(), t);
856         }
857     }
858
859
860     /**
861      * Use reflection to invoke the requested method. Cache the method object
862      * to speed up the process
863      * @param appContext The ApplicationContext object on which the method
864      *                   will be invoked
865      * @param methodName The method to call.
866      * @param params The arguments passed to the called method.
867      */

868     private Object invokeMethod(ApplicationContext appContext,
869                                 final String methodName,
870                                 Object[] params)
871         throws Throwable{
872
873         try{
874             Method method = objectCache.get(methodName);
875             if (method == null){
876                 method = appContext.getClass()
877                     .getMethod(methodName, classCache.get(methodName));
878                 objectCache.put(methodName, method);
879             }
880
881             return executeMethod(method,appContext,params);
882         } catch (Exception ex){
883             handleException(ex);
884             return null;
885         } finally {
886             params = null;
887         }
888     }
889
890     /**
891      * Use reflection to invoke the requested method. Cache the method object
892      * to speed up the process
893      * @param methodName The method to invoke.
894      * @param clazz The class where the method is.
895      * @param params The arguments passed to the called method.
896      */

897     private Object doPrivileged(final String methodName,
898                                 final Class<?>[] clazz,
899                                 Object[] params) {
900
901         try{
902             Method method = context.getClass().getMethod(methodName, clazz);
903             return executeMethod(method,context,params);
904         } catch (Exception ex){
905             try {
906                 handleException(ex);
907             } catch (Throwable t){
908                 ExceptionUtils.handleThrowable(t);
909                 throw new RuntimeException(t.getMessage());
910             }
911             return null;
912         } finally {
913             params = null;
914         }
915     }
916
917
918     /**
919      * Executes the method of the specified <code>ApplicationContext</code>
920      * @param method The method object to be invoked.
921      * @param context The ApplicationContext object on which the method
922      *                   will be invoked
923      * @param params The arguments passed to the called method.
924      */

925     private Object executeMethod(final Method method,
926                                  final ApplicationContext context,
927                                  final Object[] params)
928             throws PrivilegedActionException,
929                    IllegalAccessException,
930                    InvocationTargetException {
931
932         if (SecurityUtil.isPackageProtectionEnabled()){
933            return AccessController.doPrivileged(
934                    new PrivilegedExecuteMethod(method, context,  params));
935         } else {
936             return method.invoke(context, params);
937         }
938     }
939
940
941     /**
942      *
943      * Throw the real exception.
944      * @param ex The current exception
945      */

946     private void handleException(Exception ex)
947         throws Throwable {
948
949         Throwable realException;
950
951         if (ex instanceof PrivilegedActionException) {
952             ex = ((PrivilegedActionException) ex).getException();
953         }
954
955         if (ex instanceof InvocationTargetException) {
956             realException = ex.getCause();
957             if (realException == null) {
958                 realException = ex;
959             }
960         } else {
961             realException = ex;
962         }
963
964         throw realException;
965     }
966
967
968     private static class PrivilegedExecuteMethod implements PrivilegedExceptionAction<Object> {
969
970         private final Method method;
971         private final ApplicationContext context;
972         private final Object[] params;
973
974         public PrivilegedExecuteMethod(Method method, ApplicationContext context, Object[] params) {
975             this.method = method;
976             this.context = context;
977             this.params = params;
978         }
979
980         @Override
981         public Object run() throws Exception {
982             return method.invoke(context, params);
983         }
984     }
985 }
986