001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.core;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.Serializable;
023: import java.lang.reflect.InvocationTargetException;
024: import java.util.ArrayList;
025: import java.util.Enumeration;
026: import java.util.Map;
027: import java.util.Properties;
028:
029: import javax.naming.NamingException;
030: import javax.servlet.Filter;
031: import javax.servlet.FilterConfig;
032: import javax.servlet.ServletContext;
033: import javax.servlet.ServletException;
034:
035: import org.apache.AnnotationProcessor;
036: import org.apache.catalina.Context;
037: import org.apache.catalina.Globals;
038: import org.apache.catalina.deploy.FilterDef;
039: import org.apache.catalina.security.SecurityUtil;
040: import org.apache.catalina.util.Enumerator;
041: import org.apache.catalina.util.StringManager;
042: import org.apache.tomcat.util.log.SystemLogHandler;
043:
044: /**
045: * Implementation of a <code>javax.servlet.FilterConfig</code> useful in
046: * managing the filter instances instantiated when a web application
047: * is first started.
048: *
049: * @author Craig R. McClanahan
050: * @version $Revision: 505593 $ $Date: 2007-02-10 01:54:56 +0100 (sam., 10 févr. 2007) $
051: */
052:
053: final class ApplicationFilterConfig implements FilterConfig,
054: Serializable {
055:
056: protected static StringManager sm = StringManager
057: .getManager(Constants.Package);
058:
059: // ----------------------------------------------------------- Constructors
060:
061: /**
062: * Construct a new ApplicationFilterConfig for the specified filter
063: * definition.
064: *
065: * @param context The context with which we are associated
066: * @param filterDef Filter definition for which a FilterConfig is to be
067: * constructed
068: *
069: * @exception ClassCastException if the specified class does not implement
070: * the <code>javax.servlet.Filter</code> interface
071: * @exception ClassNotFoundException if the filter class cannot be found
072: * @exception IllegalAccessException if the filter class cannot be
073: * publicly instantiated
074: * @exception InstantiationException if an exception occurs while
075: * instantiating the filter object
076: * @exception ServletException if thrown by the filter's init() method
077: * @throws NamingException
078: * @throws InvocationTargetException
079: */
080: public ApplicationFilterConfig(Context context, FilterDef filterDef)
081: throws ClassCastException, ClassNotFoundException,
082: IllegalAccessException, InstantiationException,
083: ServletException, InvocationTargetException,
084: NamingException {
085:
086: super ();
087:
088: if (restrictedFilters == null) {
089: restrictedFilters = new Properties();
090: try {
091: InputStream is = this
092: .getClass()
093: .getClassLoader()
094: .getResourceAsStream(
095: "org/apache/catalina/core/RestrictedFilters.properties");
096: if (is != null) {
097: restrictedFilters.load(is);
098: } else {
099: context
100: .getLogger()
101: .error(
102: sm
103: .getString("applicationFilterConfig.restrictedFiltersResources"));
104: }
105: } catch (IOException e) {
106: context
107: .getLogger()
108: .error(
109: sm
110: .getString("applicationFilterConfig.restrictedServletsResources"),
111: e);
112: }
113: }
114:
115: this .context = context;
116: setFilterDef(filterDef);
117:
118: }
119:
120: // ----------------------------------------------------- Instance Variables
121:
122: /**
123: * The Context with which we are associated.
124: */
125: private Context context = null;
126:
127: /**
128: * The application Filter we are configured for.
129: */
130: private transient Filter filter = null;
131:
132: /**
133: * The <code>FilterDef</code> that defines our associated Filter.
134: */
135: private FilterDef filterDef = null;
136:
137: /**
138: * Restricted filters (which can only be loaded by a privileged webapp).
139: */
140: protected static Properties restrictedFilters = null;
141:
142: // --------------------------------------------------- FilterConfig Methods
143:
144: /**
145: * Return the name of the filter we are configuring.
146: */
147: public String getFilterName() {
148:
149: return (filterDef.getFilterName());
150:
151: }
152:
153: /**
154: * Return a <code>String</code> containing the value of the named
155: * initialization parameter, or <code>null</code> if the parameter
156: * does not exist.
157: *
158: * @param name Name of the requested initialization parameter
159: */
160: public String getInitParameter(String name) {
161:
162: Map map = filterDef.getParameterMap();
163: if (map == null)
164: return (null);
165: else
166: return ((String) map.get(name));
167:
168: }
169:
170: /**
171: * Return an <code>Enumeration</code> of the names of the initialization
172: * parameters for this Filter.
173: */
174: public Enumeration getInitParameterNames() {
175:
176: Map map = filterDef.getParameterMap();
177: if (map == null)
178: return (new Enumerator(new ArrayList()));
179: else
180: return (new Enumerator(map.keySet()));
181:
182: }
183:
184: /**
185: * Return the ServletContext of our associated web application.
186: */
187: public ServletContext getServletContext() {
188:
189: return (this .context.getServletContext());
190:
191: }
192:
193: /**
194: * Return a String representation of this object.
195: */
196: public String toString() {
197:
198: StringBuffer sb = new StringBuffer("ApplicationFilterConfig[");
199: sb.append("name=");
200: sb.append(filterDef.getFilterName());
201: sb.append(", filterClass=");
202: sb.append(filterDef.getFilterClass());
203: sb.append("]");
204: return (sb.toString());
205:
206: }
207:
208: // -------------------------------------------------------- Package Methods
209:
210: /**
211: * Return the application Filter we are configured for.
212: *
213: * @exception ClassCastException if the specified class does not implement
214: * the <code>javax.servlet.Filter</code> interface
215: * @exception ClassNotFoundException if the filter class cannot be found
216: * @exception IllegalAccessException if the filter class cannot be
217: * publicly instantiated
218: * @exception InstantiationException if an exception occurs while
219: * instantiating the filter object
220: * @exception ServletException if thrown by the filter's init() method
221: * @throws NamingException
222: * @throws InvocationTargetException
223: */
224: Filter getFilter() throws ClassCastException,
225: ClassNotFoundException, IllegalAccessException,
226: InstantiationException, ServletException,
227: InvocationTargetException, NamingException {
228:
229: // Return the existing filter instance, if any
230: if (this .filter != null)
231: return (this .filter);
232:
233: // Identify the class loader we will be using
234: String filterClass = filterDef.getFilterClass();
235: ClassLoader classLoader = null;
236: if (filterClass.startsWith("org.apache.catalina."))
237: classLoader = this .getClass().getClassLoader();
238: else
239: classLoader = context.getLoader().getClassLoader();
240:
241: ClassLoader oldCtxClassLoader = Thread.currentThread()
242: .getContextClassLoader();
243:
244: // Instantiate a new instance of this filter and return it
245: Class clazz = classLoader.loadClass(filterClass);
246: if (!isFilterAllowed(clazz)) {
247: throw new SecurityException(sm.getString(
248: "applicationFilterConfig.privilegedFilter",
249: filterClass));
250: }
251: this .filter = (Filter) clazz.newInstance();
252: if (!context.getIgnoreAnnotations()) {
253: if (context instanceof StandardContext) {
254: AnnotationProcessor processor = ((StandardContext) context)
255: .getAnnotationProcessor();
256: processor.processAnnotations(this .filter);
257: processor.postConstruct(this .filter);
258: }
259: }
260: if (context instanceof StandardContext
261: && ((StandardContext) context).getSwallowOutput()) {
262: try {
263: SystemLogHandler.startCapture();
264: filter.init(this );
265: } finally {
266: String log = SystemLogHandler.stopCapture();
267: if (log != null && log.length() > 0) {
268: getServletContext().log(log);
269: }
270: }
271: } else {
272: filter.init(this );
273: }
274: return (this .filter);
275:
276: }
277:
278: /**
279: * Return the filter definition we are configured for.
280: */
281: FilterDef getFilterDef() {
282:
283: return (this .filterDef);
284:
285: }
286:
287: /**
288: * Return <code>true</code> if loading this filter is allowed.
289: */
290: protected boolean isFilterAllowed(Class filterClass) {
291:
292: // Privileged webapps may load all servlets without restriction
293: if (context.getPrivileged()) {
294: return true;
295: }
296:
297: Class clazz = filterClass;
298: while (clazz != null
299: && !clazz.getName().equals("javax.servlet.Filter")) {
300: if ("restricted".equals(restrictedFilters.getProperty(clazz
301: .getName()))) {
302: return (false);
303: }
304: clazz = clazz.getSuperclass();
305: }
306:
307: return (true);
308:
309: }
310:
311: /**
312: * Release the Filter instance associated with this FilterConfig,
313: * if there is one.
314: */
315: void release() {
316:
317: if (this .filter != null) {
318: if (Globals.IS_SECURITY_ENABLED) {
319: try {
320: SecurityUtil.doAsPrivilege("destroy", filter);
321: } catch (java.lang.Exception ex) {
322: context
323: .getLogger()
324: .error(
325: "ApplicationFilterConfig.doAsPrivilege",
326: ex);
327: }
328: SecurityUtil.remove(filter);
329: } else {
330: filter.destroy();
331: }
332: if (!context.getIgnoreAnnotations()) {
333: try {
334: ((StandardContext) context)
335: .getAnnotationProcessor().preDestroy(
336: this .filter);
337: } catch (Exception e) {
338: context.getLogger().error(
339: "ApplicationFilterConfig.preDestroy", e);
340: }
341: }
342: }
343: this .filter = null;
344:
345: }
346:
347: /**
348: * Set the filter definition we are configured for. This has the side
349: * effect of instantiating an instance of the corresponding filter class.
350: *
351: * @param filterDef The new filter definition
352: *
353: * @exception ClassCastException if the specified class does not implement
354: * the <code>javax.servlet.Filter</code> interface
355: * @exception ClassNotFoundException if the filter class cannot be found
356: * @exception IllegalAccessException if the filter class cannot be
357: * publicly instantiated
358: * @exception InstantiationException if an exception occurs while
359: * instantiating the filter object
360: * @exception ServletException if thrown by the filter's init() method
361: * @throws NamingException
362: * @throws InvocationTargetException
363: */
364: void setFilterDef(FilterDef filterDef) throws ClassCastException,
365: ClassNotFoundException, IllegalAccessException,
366: InstantiationException, ServletException,
367: InvocationTargetException, NamingException {
368:
369: this .filterDef = filterDef;
370: if (filterDef == null) {
371:
372: // Release any previously allocated filter instance
373: if (this .filter != null) {
374: if (Globals.IS_SECURITY_ENABLED) {
375: try {
376: SecurityUtil.doAsPrivilege("destroy", filter);
377: } catch (java.lang.Exception ex) {
378: context
379: .getLogger()
380: .error(
381: "ApplicationFilterConfig.doAsPrivilege",
382: ex);
383: }
384: SecurityUtil.remove(filter);
385: } else {
386: filter.destroy();
387: }
388: if (!context.getIgnoreAnnotations()) {
389: try {
390: ((StandardContext) context)
391: .getAnnotationProcessor().preDestroy(
392: this .filter);
393: } catch (Exception e) {
394: context
395: .getLogger()
396: .error(
397: "ApplicationFilterConfig.preDestroy",
398: e);
399: }
400: }
401: }
402: this .filter = null;
403:
404: } else {
405:
406: // Allocate a new filter instance
407: Filter filter = getFilter();
408:
409: }
410:
411: }
412:
413: // -------------------------------------------------------- Private Methods
414:
415: }
|