Save This Page
Home » apache-tomcat-6.0.26-src » org.apache » catalina » core » [javadoc | source]
    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.IOException;
   23   import java.io.InputStream;
   24   import java.io.Serializable;
   25   import java.lang.reflect.InvocationTargetException;
   26   import java.util.ArrayList;
   27   import java.util.Collections;
   28   import java.util.Enumeration;
   29   import java.util.Map;
   30   import java.util.Properties;
   31   
   32   import javax.management.ObjectName;
   33   import javax.naming.NamingException;
   34   import javax.servlet.Filter;
   35   import javax.servlet.FilterConfig;
   36   import javax.servlet.ServletContext;
   37   import javax.servlet.ServletException;
   38   
   39   import org.apache.AnnotationProcessor;
   40   import org.apache.catalina.Context;
   41   import org.apache.catalina.Globals;
   42   import org.apache.catalina.deploy.FilterDef;
   43   import org.apache.catalina.security.SecurityUtil;
   44   import org.apache.catalina.util.Enumerator;
   45   import org.apache.catalina.util.StringManager;
   46   import org.apache.juli.logging.LogFactory;
   47   import org.apache.tomcat.util.log.SystemLogHandler;
   48   import org.apache.tomcat.util.modeler.Registry;
   49   
   50   
   51   /**
   52    * Implementation of a <code>javax.servlet.FilterConfig</code> useful in
   53    * managing the filter instances instantiated when a web application
   54    * is first started.
   55    *
   56    * @author Craig R. McClanahan
   57    * @version $Revision: 812133 $ $Date: 2009-09-07 15:37:06 +0200 (Mon, 07 Sep 2009) $
   58    */
   59   
   60   public final class ApplicationFilterConfig implements FilterConfig, Serializable {
   61   
   62   
   63       protected static StringManager sm =
   64           StringManager.getManager(Constants.Package);
   65       
   66       private static org.apache.juli.logging.Log log =
   67           LogFactory.getLog(ApplicationFilterConfig.class);
   68   
   69       // ----------------------------------------------------------- Constructors
   70   
   71   
   72       /**
   73        * Construct a new ApplicationFilterConfig for the specified filter
   74        * definition.
   75        *
   76        * @param context The context with which we are associated
   77        * @param filterDef Filter definition for which a FilterConfig is to be
   78        *  constructed
   79        *
   80        * @exception ClassCastException if the specified class does not implement
   81        *  the <code>javax.servlet.Filter</code> interface
   82        * @exception ClassNotFoundException if the filter class cannot be found
   83        * @exception IllegalAccessException if the filter class cannot be
   84        *  publicly instantiated
   85        * @exception InstantiationException if an exception occurs while
   86        *  instantiating the filter object
   87        * @exception ServletException if thrown by the filter's init() method
   88        * @throws NamingException 
   89        * @throws InvocationTargetException 
   90        */
   91       ApplicationFilterConfig(Context context, FilterDef filterDef)
   92           throws ClassCastException, ClassNotFoundException,
   93                  IllegalAccessException, InstantiationException,
   94                  ServletException, InvocationTargetException, NamingException {
   95   
   96           super();
   97   
   98           if (restrictedFilters == null) {
   99               restrictedFilters = new Properties();
  100               try {
  101                   InputStream is = 
  102                       this.getClass().getClassLoader().getResourceAsStream
  103                           ("org/apache/catalina/core/RestrictedFilters.properties");
  104                   if (is != null) {
  105                       restrictedFilters.load(is);
  106                   } else {
  107                       context.getLogger().error(sm.getString("applicationFilterConfig.restrictedFiltersResources"));
  108                   }
  109               } catch (IOException e) {
  110                   context.getLogger().error(sm.getString("applicationFilterConfig.restrictedServletsResources"), e);
  111               }
  112           }
  113           
  114           this.context = context;
  115           setFilterDef(filterDef);
  116   
  117       }
  118   
  119   
  120       // ----------------------------------------------------- Instance Variables
  121   
  122   
  123       /**
  124        * The Context with which we are associated.
  125        */
  126       private Context context = null;
  127   
  128   
  129       /**
  130        * The application Filter we are configured for.
  131        */
  132       private transient Filter filter = null;
  133   
  134   
  135       /**
  136        * The <code>FilterDef</code> that defines our associated Filter.
  137        */
  138       private FilterDef filterDef = null;
  139   
  140   
  141       /**
  142        * Restricted filters (which can only be loaded by a privileged webapp).
  143        */
  144       protected static Properties restrictedFilters = null;
  145   
  146       /**
  147        * JMX registration name
  148        */
  149       private ObjectName oname;
  150       
  151       // --------------------------------------------------- FilterConfig Methods
  152   
  153   
  154       /**
  155        * Return the name of the filter we are configuring.
  156        */
  157       public String getFilterName() {
  158           return (filterDef.getFilterName());
  159       }
  160   
  161       /**
  162        * Return the class of the filter we are configuring.
  163        */
  164       public String getFilterClass() {
  165           return filterDef.getFilterClass();
  166       }
  167   
  168       /**
  169        * Return a <code>String</code> containing the value of the named
  170        * initialization parameter, or <code>null</code> if the parameter
  171        * does not exist.
  172        *
  173        * @param name Name of the requested initialization parameter
  174        */
  175       public String getInitParameter(String name) {
  176   
  177           Map map = filterDef.getParameterMap();
  178           if (map == null)
  179               return (null);
  180           else
  181               return ((String) map.get(name));
  182   
  183       }
  184   
  185   
  186       /**
  187        * Return an <code>Enumeration</code> of the names of the initialization
  188        * parameters for this Filter.
  189        */
  190       public Enumeration getInitParameterNames() {
  191   
  192           Map map = filterDef.getParameterMap();
  193           if (map == null)
  194               return (new Enumerator(new ArrayList()));
  195           else
  196               return (new Enumerator(map.keySet()));
  197   
  198       }
  199   
  200   
  201       /**
  202        * Return the ServletContext of our associated web application.
  203        */
  204       public ServletContext getServletContext() {
  205   
  206           return (this.context.getServletContext());
  207   
  208       }
  209   
  210   
  211       /**
  212        * Return a String representation of this object.
  213        */
  214       public String toString() {
  215   
  216           StringBuffer sb = new StringBuffer("ApplicationFilterConfig[");
  217           sb.append("name=");
  218           sb.append(filterDef.getFilterName());
  219           sb.append(", filterClass=");
  220           sb.append(filterDef.getFilterClass());
  221           sb.append("]");
  222           return (sb.toString());
  223   
  224       }
  225   
  226       // --------------------------------------------------------- Public Methods
  227   
  228       public Map<String, String> getFilterInitParameterMap() {
  229           return Collections.unmodifiableMap(filterDef.getParameterMap());
  230       }
  231   
  232       // -------------------------------------------------------- Package Methods
  233   
  234   
  235       /**
  236        * Return the application Filter we are configured for.
  237        *
  238        * @exception ClassCastException if the specified class does not implement
  239        *  the <code>javax.servlet.Filter</code> interface
  240        * @exception ClassNotFoundException if the filter class cannot be found
  241        * @exception IllegalAccessException if the filter class cannot be
  242        *  publicly instantiated
  243        * @exception InstantiationException if an exception occurs while
  244        *  instantiating the filter object
  245        * @exception ServletException if thrown by the filter's init() method
  246        * @throws NamingException 
  247        * @throws InvocationTargetException 
  248        */
  249       Filter getFilter() throws ClassCastException, ClassNotFoundException,
  250           IllegalAccessException, InstantiationException, ServletException, 
  251           InvocationTargetException, NamingException {
  252   
  253           // Return the existing filter instance, if any
  254           if (this.filter != null)
  255               return (this.filter);
  256   
  257           // Identify the class loader we will be using
  258           String filterClass = filterDef.getFilterClass();
  259           ClassLoader classLoader = null;
  260           if (filterClass.startsWith("org.apache.catalina."))
  261               classLoader = this.getClass().getClassLoader();
  262           else
  263               classLoader = context.getLoader().getClassLoader();
  264   
  265           ClassLoader oldCtxClassLoader =
  266               Thread.currentThread().getContextClassLoader();
  267   
  268           // Instantiate a new instance of this filter and return it
  269           Class clazz = classLoader.loadClass(filterClass);
  270           if (!isFilterAllowed(clazz)) {
  271               throw new SecurityException
  272                   (sm.getString("applicationFilterConfig.privilegedFilter",
  273                           filterClass));
  274           }
  275           this.filter = (Filter) clazz.newInstance();
  276           if (!context.getIgnoreAnnotations()) {
  277               if (context instanceof StandardContext) {
  278                  AnnotationProcessor processor = ((StandardContext)context).getAnnotationProcessor();
  279                  processor.processAnnotations(this.filter);
  280                  processor.postConstruct(this.filter);
  281               }
  282           }
  283           if (context instanceof StandardContext &&
  284               ((StandardContext) context).getSwallowOutput()) {
  285               try {
  286                   SystemLogHandler.startCapture();
  287                   filter.init(this);
  288               } finally {
  289                   String log = SystemLogHandler.stopCapture();
  290                   if (log != null && log.length() > 0) {
  291                       getServletContext().log(log);
  292                   }
  293               }
  294           } else {
  295               filter.init(this);
  296           }
  297           
  298           // Expose filter via JMX
  299           registerJMX();
  300           
  301           return (this.filter);
  302   
  303       }
  304   
  305   
  306       /**
  307        * Return the filter definition we are configured for.
  308        */
  309       FilterDef getFilterDef() {
  310   
  311           return (this.filterDef);
  312   
  313       }
  314   
  315   
  316       /**
  317        * Return <code>true</code> if loading this filter is allowed.
  318        */
  319       protected boolean isFilterAllowed(Class filterClass) {
  320   
  321           // Privileged webapps may load all servlets without restriction
  322           if (context.getPrivileged()) {
  323               return true;
  324           }
  325   
  326           Class clazz = filterClass;
  327           while (clazz != null && !clazz.getName().equals("javax.servlet.Filter")) {
  328               if ("restricted".equals(restrictedFilters.getProperty(clazz.getName()))) {
  329                   return (false);
  330               }
  331               clazz = clazz.getSuperclass();
  332           }
  333           
  334           return (true);
  335   
  336       }
  337   
  338   
  339       /**
  340        * Release the Filter instance associated with this FilterConfig,
  341        * if there is one.
  342        */
  343       void release() {
  344   
  345           unregisterJMX();
  346           
  347           if (this.filter != null)
  348           {
  349               if (Globals.IS_SECURITY_ENABLED) {
  350                   try {
  351                       SecurityUtil.doAsPrivilege("destroy", filter); 
  352                   } catch(java.lang.Exception ex){                    
  353                       context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
  354                   }
  355                   SecurityUtil.remove(filter);
  356               } else { 
  357                   filter.destroy();
  358               }
  359               if (!context.getIgnoreAnnotations()) {
  360                   try {
  361                       ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
  362                   } catch (Exception e) {
  363                       context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
  364                   }
  365               }
  366           }
  367           this.filter = null;
  368   
  369        }
  370   
  371   
  372       /**
  373        * Set the filter definition we are configured for.  This has the side
  374        * effect of instantiating an instance of the corresponding filter class.
  375        *
  376        * @param filterDef The new filter definition
  377        *
  378        * @exception ClassCastException if the specified class does not implement
  379        *  the <code>javax.servlet.Filter</code> interface
  380        * @exception ClassNotFoundException if the filter class cannot be found
  381        * @exception IllegalAccessException if the filter class cannot be
  382        *  publicly instantiated
  383        * @exception InstantiationException if an exception occurs while
  384        *  instantiating the filter object
  385        * @exception ServletException if thrown by the filter's init() method
  386        * @throws NamingException 
  387        * @throws InvocationTargetException 
  388        */
  389       void setFilterDef(FilterDef filterDef)
  390           throws ClassCastException, ClassNotFoundException,
  391                  IllegalAccessException, InstantiationException,
  392                  ServletException, InvocationTargetException, NamingException {
  393   
  394           this.filterDef = filterDef;
  395           if (filterDef == null) {
  396   
  397               // Release any previously allocated filter instance
  398               if (this.filter != null){
  399                   if (Globals.IS_SECURITY_ENABLED) {
  400                       try{
  401                           SecurityUtil.doAsPrivilege("destroy", filter);  
  402                       } catch(java.lang.Exception ex){    
  403                           context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
  404                       }
  405                       SecurityUtil.remove(filter);
  406                   } else { 
  407                       filter.destroy();
  408                   }
  409                   if (!context.getIgnoreAnnotations()) {
  410                       try {
  411                           ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
  412                       } catch (Exception e) {
  413                           context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
  414                       }
  415                   }
  416               }
  417               this.filter = null;
  418   
  419           } else {
  420   
  421               // Allocate a new filter instance
  422               Filter filter = getFilter();
  423   
  424           }
  425   
  426       }
  427   
  428   
  429       // -------------------------------------------------------- Private Methods
  430   
  431   
  432       private void registerJMX() {
  433           String parentName = context.getName();
  434           parentName = ("".equals(parentName)) ? "/" : parentName;
  435   
  436           String hostName = context.getParent().getName();
  437           hostName = (hostName == null) ? "DEFAULT" : hostName;
  438   
  439           // domain == engine name
  440           String domain = context.getParent().getParent().getName();
  441   
  442           String webMod = "//" + hostName + parentName;
  443           String onameStr = null;
  444           if (context instanceof StandardContext) {
  445               StandardContext standardContext = (StandardContext) context;
  446               onameStr = domain + ":j2eeType=Filter,name=" +
  447                    filterDef.getFilterName() + ",WebModule=" + webMod +
  448                    ",J2EEApplication=" +
  449                    standardContext.getJ2EEApplication() + ",J2EEServer=" +
  450                    standardContext.getJ2EEServer();
  451           } else {
  452               onameStr = domain + ":j2eeType=Filter,name=" +
  453                    filterDef.getFilterName() + ",WebModule=" + webMod;
  454   }
  455           try {
  456               oname = new ObjectName(onameStr);
  457               Registry.getRegistry(null, null).registerComponent(this, oname,
  458                       null);
  459           } catch (Exception ex) {
  460               log.info(sm.getString("applicationFilterConfig.jmxRegisterFail",
  461                       getFilterClass(), getFilterName()), ex);
  462           }
  463       }
  464       
  465       private void unregisterJMX() {
  466           // unregister this component
  467           if (oname != null) {
  468               try {
  469                   Registry.getRegistry(null, null).unregisterComponent(oname);
  470                   if (log.isDebugEnabled())
  471                       log.debug(sm.getString(
  472                               "applicationFilterConfig.jmxUnregister",
  473                               getFilterClass(), getFilterName()));
  474               } catch(Exception ex) {
  475                   log.error(sm.getString(
  476                           "applicationFilterConfig.jmxUnregisterFail",
  477                           getFilterClass(), getFilterName()), ex);
  478               }
  479           }
  480   
  481       }
  482   }

Save This Page
Home » apache-tomcat-6.0.26-src » org.apache » catalina » core » [javadoc | source]