Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » startup » [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.startup;
   20   
   21   
   22   import java.io.File;
   23   import java.io.FileInputStream;
   24   import java.io.FileNotFoundException;
   25   import java.io.IOException;
   26   import java.io.InputStream;
   27   import java.net.URL;
   28   import java.util.Map;
   29   import java.util.Properties;
   30   
   31   import javax.servlet.ServletContext;
   32   
   33   import org.apache.catalina.Authenticator;
   34   import org.apache.catalina.Container;
   35   import org.apache.catalina.Context;
   36   import org.apache.catalina.Engine;
   37   import org.apache.catalina.Globals;
   38   import org.apache.catalina.Host;
   39   import org.apache.catalina.Lifecycle;
   40   import org.apache.catalina.LifecycleEvent;
   41   import org.apache.catalina.LifecycleListener;
   42   import org.apache.catalina.Pipeline;
   43   import org.apache.catalina.Valve;
   44   import org.apache.catalina.Wrapper;
   45   import org.apache.catalina.core.ContainerBase;
   46   import org.apache.catalina.core.StandardContext;
   47   import org.apache.catalina.core.StandardEngine;
   48   import org.apache.catalina.core.StandardHost;
   49   import org.apache.catalina.deploy.ErrorPage;
   50   import org.apache.catalina.deploy.FilterDef;
   51   import org.apache.catalina.deploy.FilterMap;
   52   import org.apache.catalina.deploy.LoginConfig;
   53   import org.apache.catalina.deploy.SecurityConstraint;
   54   import org.apache.catalina.util.StringManager;
   55   import org.apache.tomcat.util.digester.Digester;
   56   import org.apache.tomcat.util.digester.RuleSet;
   57   import org.xml.sax.ErrorHandler;
   58   import org.xml.sax.InputSource;
   59   import org.xml.sax.SAXParseException;
   60   
   61   /**
   62    * Startup event listener for a <b>Context</b> that configures the properties
   63    * of that Context, and the associated defined servlets.
   64    *
   65    * @author Craig R. McClanahan
   66    * @author Jean-Francois Arcand
   67    * @version $Revision: 556489 $ $Date: 2007-07-16 04:01:01 +0200 (lun., 16 juil. 2007) $
   68    */
   69   
   70   public class ContextConfig
   71       implements LifecycleListener {
   72   
   73       protected static org.apache.juli.logging.Log log=
   74           org.apache.juli.logging.LogFactory.getLog( ContextConfig.class );
   75   
   76       // ----------------------------------------------------- Instance Variables
   77   
   78   
   79       /**
   80        * Custom mappings of login methods to authenticators
   81        */
   82       protected Map customAuthenticators;
   83   
   84   
   85       /**
   86        * The set of Authenticators that we know how to configure.  The key is
   87        * the name of the implemented authentication method, and the value is
   88        * the fully qualified Java class name of the corresponding Valve.
   89        */
   90       protected static Properties authenticators = null;
   91   
   92   
   93       /**
   94        * The Context we are associated with.
   95        */
   96       protected Context context = null;
   97   
   98   
   99       /**
  100        * The default web application's context file location.
  101        */
  102       protected String defaultContextXml = null;
  103       
  104       
  105       /**
  106        * The default web application's deployment descriptor location.
  107        */
  108       protected String defaultWebXml = null;
  109       
  110       
  111       /**
  112        * Track any fatal errors during startup configuration processing.
  113        */
  114       protected boolean ok = false;
  115   
  116   
  117       /**
  118        * Any parse error which occurred while parsing XML descriptors.
  119        */
  120       protected SAXParseException parseException = null;
  121   
  122       
  123       /**
  124        * Original docBase.
  125        */
  126       protected String originalDocBase = null;
  127       
  128   
  129       /**
  130        * The string resources for this package.
  131        */
  132       protected static final StringManager sm =
  133           StringManager.getManager(Constants.Package);
  134   
  135   
  136       /**
  137        * The <code>Digester</code> we will use to process web application
  138        * context files.
  139        */
  140       protected static Digester contextDigester = null;
  141       
  142       
  143       /**
  144        * The <code>Digester</code> we will use to process web application
  145        * deployment descriptor files.
  146        */
  147       protected static Digester webDigester = null;
  148       
  149       
  150       /**
  151        * The <code>Rule</code> used to parse the web.xml
  152        */
  153       protected static WebRuleSet webRuleSet = new WebRuleSet();
  154   
  155       /**
  156        * Attribute value used to turn on/off XML validation
  157        */
  158        protected static boolean xmlValidation = false;
  159   
  160   
  161       /**
  162        * Attribute value used to turn on/off XML namespace awarenes.
  163        */
  164       protected static boolean xmlNamespaceAware = false;
  165   
  166       
  167       /**
  168        * Deployment count.
  169        */
  170       protected static long deploymentCount = 0L;
  171       
  172       
  173       protected static final LoginConfig DUMMY_LOGIN_CONFIG =
  174                                   new LoginConfig("NONE", null, null, null);
  175   
  176   
  177       // ------------------------------------------------------------- Properties
  178   
  179   
  180       /**
  181        * Return the location of the default deployment descriptor
  182        */
  183       public String getDefaultWebXml() {
  184           if( defaultWebXml == null ) {
  185               defaultWebXml=Constants.DefaultWebXml;
  186           }
  187   
  188           return (this.defaultWebXml);
  189   
  190       }
  191   
  192   
  193       /**
  194        * Set the location of the default deployment descriptor
  195        *
  196        * @param path Absolute/relative path to the default web.xml
  197        */
  198       public void setDefaultWebXml(String path) {
  199   
  200           this.defaultWebXml = path;
  201   
  202       }
  203   
  204   
  205       /**
  206        * Return the location of the default context file
  207        */
  208       public String getDefaultContextXml() {
  209           if( defaultContextXml == null ) {
  210               defaultContextXml=Constants.DefaultContextXml;
  211           }
  212   
  213           return (this.defaultContextXml);
  214   
  215       }
  216   
  217   
  218       /**
  219        * Set the location of the default context file
  220        *
  221        * @param path Absolute/relative path to the default context.xml
  222        */
  223       public void setDefaultContextXml(String path) {
  224   
  225           this.defaultContextXml = path;
  226   
  227       }
  228   
  229   
  230       /**
  231        * Sets custom mappings of login methods to authenticators.
  232        *
  233        * @param customAuthenticators Custom mappings of login methods to
  234        * authenticators
  235        */
  236       public void setCustomAuthenticators(Map customAuthenticators) {
  237           this.customAuthenticators = customAuthenticators;
  238       }
  239   
  240   
  241       // --------------------------------------------------------- Public Methods
  242   
  243   
  244       /**
  245        * Process events for an associated Context.
  246        *
  247        * @param event The lifecycle event that has occurred
  248        */
  249       public void lifecycleEvent(LifecycleEvent event) {
  250   
  251           // Identify the context we are associated with
  252           try {
  253               context = (Context) event.getLifecycle();
  254           } catch (ClassCastException e) {
  255               log.error(sm.getString("contextConfig.cce", event.getLifecycle()), e);
  256               return;
  257           }
  258   
  259           // Process the event that has occurred
  260           if (event.getType().equals(Lifecycle.START_EVENT)) {
  261               start();
  262           } else if (event.getType().equals(StandardContext.BEFORE_START_EVENT)) {
  263               beforeStart();
  264           } else if (event.getType().equals(StandardContext.AFTER_START_EVENT)) {
  265               // Restore docBase for management tools
  266               if (originalDocBase != null) {
  267                   String docBase = context.getDocBase();
  268                   context.setDocBase(originalDocBase);
  269                   originalDocBase = docBase;
  270               }
  271           } else if (event.getType().equals(Lifecycle.STOP_EVENT)) {
  272               if (originalDocBase != null) {
  273                   String docBase = context.getDocBase();
  274                   context.setDocBase(originalDocBase);
  275                   originalDocBase = docBase;
  276               }
  277               stop();
  278           } else if (event.getType().equals(Lifecycle.INIT_EVENT)) {
  279               init();
  280           } else if (event.getType().equals(Lifecycle.DESTROY_EVENT)) {
  281               destroy();
  282           }
  283   
  284       }
  285   
  286   
  287       // -------------------------------------------------------- protected Methods
  288   
  289   
  290       /**
  291        * Process the application classes annotations, if it exists.
  292        */
  293       protected void applicationAnnotationsConfig() {
  294           
  295           long t1=System.currentTimeMillis();
  296           
  297           WebAnnotationSet.loadApplicationAnnotations(context);
  298           
  299           long t2=System.currentTimeMillis();
  300           if (context instanceof StandardContext) {
  301               ((StandardContext) context).setStartupTime(t2-t1+
  302                       ((StandardContext) context).getStartupTime());
  303           }
  304       }
  305   
  306   
  307       /**
  308        * Process the application configuration file, if it exists.
  309        */
  310       protected void applicationWebConfig() {
  311   
  312           String altDDName = null;
  313   
  314           // Open the application web.xml file, if it exists
  315           InputStream stream = null;
  316           ServletContext servletContext = context.getServletContext();
  317           if (servletContext != null) {
  318               altDDName = (String)servletContext.getAttribute(
  319                                                           Globals.ALT_DD_ATTR);
  320               if (altDDName != null) {
  321                   try {
  322                       stream = new FileInputStream(altDDName);
  323                   } catch (FileNotFoundException e) {
  324                       log.error(sm.getString("contextConfig.altDDNotFound",
  325                                              altDDName));
  326                   }
  327               }
  328               else {
  329                   stream = servletContext.getResourceAsStream
  330                       (Constants.ApplicationWebXml);
  331               }
  332           }
  333           if (stream == null) {
  334               if (log.isDebugEnabled()) {
  335                   log.debug(sm.getString("contextConfig.applicationMissing") + " " + context);
  336               }
  337               return;
  338           }
  339           
  340           long t1=System.currentTimeMillis();
  341   
  342           if (webDigester == null){
  343               webDigester = createWebDigester();
  344           }
  345           
  346           URL url=null;
  347           // Process the application web.xml file
  348           synchronized (webDigester) {
  349               try {
  350                   if (altDDName != null) {
  351                       url = new File(altDDName).toURL();
  352                   } else {
  353                       url = servletContext.getResource(
  354                                                   Constants.ApplicationWebXml);
  355                   }
  356                   if( url!=null ) {
  357                       InputSource is = new InputSource(url.toExternalForm());
  358                       is.setByteStream(stream);
  359                       if (context instanceof StandardContext) {
  360                           ((StandardContext) context).setReplaceWelcomeFiles(true);
  361                       }
  362                       webDigester.push(context);
  363                       webDigester.setErrorHandler(new ContextErrorHandler());
  364   
  365                       if(log.isDebugEnabled()) {
  366                           log.debug("Parsing application web.xml file at " + url.toExternalForm());
  367                       }
  368   
  369                       webDigester.parse(is);
  370   
  371                       if (parseException != null) {
  372                           ok = false;
  373                       }
  374                   } else {
  375                       log.info("No web.xml, using defaults " + context );
  376                   }
  377               } catch (SAXParseException e) {
  378                   log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
  379                   log.error(sm.getString("contextConfig.applicationPosition",
  380                                    "" + e.getLineNumber(),
  381                                    "" + e.getColumnNumber()));
  382                   ok = false;
  383               } catch (Exception e) {
  384                   log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
  385                   ok = false;
  386               } finally {
  387                   webDigester.reset();
  388                   parseException = null;
  389                   try {
  390                       if (stream != null) {
  391                           stream.close();
  392                       }
  393                   } catch (IOException e) {
  394                       log.error(sm.getString("contextConfig.applicationClose"), e);
  395                   }
  396               }
  397           }
  398           webRuleSet.recycle();
  399   
  400           long t2=System.currentTimeMillis();
  401           if (context instanceof StandardContext) {
  402               ((StandardContext) context).setStartupTime(t2-t1);
  403           }
  404       }
  405   
  406   
  407       /**
  408        * Set up an Authenticator automatically if required, and one has not
  409        * already been configured.
  410        */
  411       protected synchronized void authenticatorConfig() {
  412   
  413           // Does this Context require an Authenticator?
  414           SecurityConstraint constraints[] = context.findConstraints();
  415           if ((constraints == null) || (constraints.length == 0))
  416               return;
  417           LoginConfig loginConfig = context.getLoginConfig();
  418           if (loginConfig == null) {
  419               loginConfig = DUMMY_LOGIN_CONFIG;
  420               context.setLoginConfig(loginConfig);
  421           }
  422   
  423           // Has an authenticator been configured already?
  424           if (context instanceof Authenticator)
  425               return;
  426           if (context instanceof ContainerBase) {
  427               Pipeline pipeline = ((ContainerBase) context).getPipeline();
  428               if (pipeline != null) {
  429                   Valve basic = pipeline.getBasic();
  430                   if ((basic != null) && (basic instanceof Authenticator))
  431                       return;
  432                   Valve valves[] = pipeline.getValves();
  433                   for (int i = 0; i < valves.length; i++) {
  434                       if (valves[i] instanceof Authenticator)
  435                           return;
  436                   }
  437               }
  438           } else {
  439               return;     // Cannot install a Valve even if it would be needed
  440           }
  441   
  442           // Has a Realm been configured for us to authenticate against?
  443           if (context.getRealm() == null) {
  444               log.error(sm.getString("contextConfig.missingRealm"));
  445               ok = false;
  446               return;
  447           }
  448   
  449           /*
  450            * First check to see if there is a custom mapping for the login
  451            * method. If so, use it. Otherwise, check if there is a mapping in
  452            * org/apache/catalina/startup/Authenticators.properties.
  453            */
  454           Valve authenticator = null;
  455           if (customAuthenticators != null) {
  456               authenticator = (Valve)
  457                   customAuthenticators.get(loginConfig.getAuthMethod());
  458           }
  459           if (authenticator == null) {
  460               // Load our mapping properties if necessary
  461               if (authenticators == null) {
  462                   try {
  463                       InputStream is=this.getClass().getClassLoader().getResourceAsStream("org/apache/catalina/startup/Authenticators.properties");
  464                       if( is!=null ) {
  465                           authenticators = new Properties();
  466                           authenticators.load(is);
  467                       } else {
  468                           log.error(sm.getString(
  469                                   "contextConfig.authenticatorResources"));
  470                           ok=false;
  471                           return;
  472                       }
  473                   } catch (IOException e) {
  474                       log.error(sm.getString(
  475                                   "contextConfig.authenticatorResources"), e);
  476                       ok = false;
  477                       return;
  478                   }
  479               }
  480   
  481               // Identify the class name of the Valve we should configure
  482               String authenticatorName = null;
  483               authenticatorName =
  484                       authenticators.getProperty(loginConfig.getAuthMethod());
  485               if (authenticatorName == null) {
  486                   log.error(sm.getString("contextConfig.authenticatorMissing",
  487                                    loginConfig.getAuthMethod()));
  488                   ok = false;
  489                   return;
  490               }
  491   
  492               // Instantiate and install an Authenticator of the requested class
  493               try {
  494                   Class authenticatorClass = Class.forName(authenticatorName);
  495                   authenticator = (Valve) authenticatorClass.newInstance();
  496               } catch (Throwable t) {
  497                   log.error(sm.getString(
  498                                       "contextConfig.authenticatorInstantiate",
  499                                       authenticatorName),
  500                             t);
  501                   ok = false;
  502               }
  503           }
  504   
  505           if (authenticator != null && context instanceof ContainerBase) {
  506               Pipeline pipeline = ((ContainerBase) context).getPipeline();
  507               if (pipeline != null) {
  508                   ((ContainerBase) context).addValve(authenticator);
  509                   if (log.isDebugEnabled()) {
  510                       log.debug(sm.getString(
  511                                       "contextConfig.authenticatorConfigured",
  512                                       loginConfig.getAuthMethod()));
  513                   }
  514               }
  515           }
  516   
  517       }
  518   
  519   
  520       /**
  521        * Create (if necessary) and return a Digester configured to process the
  522        * web application deployment descriptor (web.xml).
  523        */
  524       protected static Digester createWebDigester() {
  525           Digester webDigester =
  526               createWebXmlDigester(xmlNamespaceAware, xmlValidation);
  527           return webDigester;
  528       }
  529   
  530   
  531       /**
  532        * Create (if necessary) and return a Digester configured to process the
  533        * web application deployment descriptor (web.xml).
  534        */
  535       public static Digester createWebXmlDigester(boolean namespaceAware,
  536                                                   boolean validation) {
  537           
  538           Digester webDigester =  DigesterFactory.newDigester(xmlValidation,
  539                                                               xmlNamespaceAware,
  540                                                               webRuleSet);
  541           return webDigester;
  542       }
  543   
  544       
  545       /**
  546        * Create (if necessary) and return a Digester configured to process the
  547        * context configuration descriptor for an application.
  548        */
  549       protected Digester createContextDigester() {
  550           Digester digester = new Digester();
  551           digester.setValidating(false);
  552           RuleSet contextRuleSet = new ContextRuleSet("", false);
  553           digester.addRuleSet(contextRuleSet);
  554           RuleSet namingRuleSet = new NamingRuleSet("Context/");
  555           digester.addRuleSet(namingRuleSet);
  556           return digester;
  557       }
  558   
  559   
  560       protected String getBaseDir() {
  561           Container engineC=context.getParent().getParent();
  562           if( engineC instanceof StandardEngine ) {
  563               return ((StandardEngine)engineC).getBaseDir();
  564           }
  565           return System.getProperty("catalina.base");
  566       }
  567   
  568       /**
  569        * Process the default configuration file, if it exists.
  570        * The default config must be read with the container loader - so
  571        * container servlets can be loaded
  572        */
  573       protected void defaultWebConfig() {
  574           long t1=System.currentTimeMillis();
  575   
  576           // Open the default web.xml file, if it exists
  577           if( defaultWebXml==null && context instanceof StandardContext ) {
  578               defaultWebXml=((StandardContext)context).getDefaultWebXml();
  579           }
  580           // set the default if we don't have any overrides
  581           if( defaultWebXml==null ) getDefaultWebXml();
  582   
  583           File file = new File(this.defaultWebXml);
  584           if (!file.isAbsolute()) {
  585               file = new File(getBaseDir(),
  586                               this.defaultWebXml);
  587           }
  588   
  589           InputStream stream = null;
  590           InputSource source = null;
  591   
  592           try {
  593               if ( ! file.exists() ) {
  594                   // Use getResource and getResourceAsStream
  595                   stream = getClass().getClassLoader()
  596                       .getResourceAsStream(defaultWebXml);
  597                   if( stream != null ) {
  598                       source = new InputSource
  599                               (getClass().getClassLoader()
  600                               .getResource(defaultWebXml).toString());
  601                   } 
  602                   if( stream== null ) { 
  603                       // maybe embedded
  604                       stream = getClass().getClassLoader()
  605                           .getResourceAsStream("web-embed.xml");
  606                       if( stream != null ) {
  607                           source = new InputSource
  608                           (getClass().getClassLoader()
  609                                   .getResource("web-embed.xml").toString());
  610                       }                                         
  611                   }
  612                   
  613                   if( stream== null ) {
  614                       log.info("No default web.xml");
  615                   }
  616               } else {
  617                   source =
  618                       new InputSource("file://" + file.getAbsolutePath());
  619                   stream = new FileInputStream(file);
  620                   context.addWatchedResource(file.getAbsolutePath());
  621               }
  622           } catch (Exception e) {
  623               log.error(sm.getString("contextConfig.defaultMissing") 
  624                         + " " + defaultWebXml + " " + file , e);
  625           }
  626   
  627           if (webDigester == null){
  628               webDigester = createWebDigester();
  629           }
  630           
  631           if (stream != null) {
  632               processDefaultWebConfig(webDigester, stream, source);
  633               webRuleSet.recycle();
  634           }
  635   
  636           long t2=System.currentTimeMillis();
  637           if( (t2-t1) > 200 )
  638               log.debug("Processed default web.xml " + file + " "  + ( t2-t1));
  639   
  640           stream = null;
  641           source = null;
  642   
  643           String resourceName = getHostConfigPath(Constants.HostWebXml);
  644           file = new File(getConfigBase(), resourceName);
  645           
  646           try {
  647               if ( ! file.exists() ) {
  648                   // Use getResource and getResourceAsStream
  649                   stream = getClass().getClassLoader()
  650                       .getResourceAsStream(resourceName);
  651                   if( stream != null ) {
  652                       source = new InputSource
  653                               (getClass().getClassLoader()
  654                               .getResource(resourceName).toString());
  655                   }
  656               } else {
  657                   source =
  658                       new InputSource("file://" + file.getAbsolutePath());
  659                   stream = new FileInputStream(file);
  660               }
  661           } catch (Exception e) {
  662               log.error(sm.getString("contextConfig.defaultMissing") 
  663                         + " " + resourceName + " " + file , e);
  664           }
  665   
  666           if (stream != null) {
  667               processDefaultWebConfig(webDigester, stream, source);
  668               webRuleSet.recycle();
  669           }
  670   
  671       }
  672   
  673   
  674       /**
  675        * Process a default web.xml.
  676        */
  677       protected void processDefaultWebConfig(Digester digester, InputStream stream, 
  678               InputSource source) {
  679   
  680           if (log.isDebugEnabled())
  681               log.debug("Processing context [" + context.getName() 
  682                       + "] web configuration resource " + source.getSystemId());
  683   
  684           // Process the default web.xml file
  685           synchronized (digester) {
  686               try {
  687                   source.setByteStream(stream);
  688                   
  689                   if (context instanceof StandardContext)
  690                       ((StandardContext) context).setReplaceWelcomeFiles(true);
  691                   digester.setClassLoader(this.getClass().getClassLoader());
  692                   digester.setUseContextClassLoader(false);
  693                   digester.push(context);
  694                   digester.setErrorHandler(new ContextErrorHandler());
  695                   digester.parse(source);
  696                   if (parseException != null) {
  697                       ok = false;
  698                   }
  699               } catch (SAXParseException e) {
  700                   log.error(sm.getString("contextConfig.defaultParse"), e);
  701                   log.error(sm.getString("contextConfig.defaultPosition",
  702                                    "" + e.getLineNumber(),
  703                                    "" + e.getColumnNumber()));
  704                   ok = false;
  705               } catch (Exception e) {
  706                   log.error(sm.getString("contextConfig.defaultParse"), e);
  707                   ok = false;
  708               } finally {
  709                   digester.reset();
  710                   parseException = null;
  711                   try {
  712                       if (stream != null) {
  713                           stream.close();
  714                       }
  715                   } catch (IOException e) {
  716                       log.error(sm.getString("contextConfig.defaultClose"), e);
  717                   }
  718               }
  719           }
  720       }
  721   
  722   
  723       /**
  724        * Process the default configuration file, if it exists.
  725        */
  726       protected void contextConfig() {
  727           
  728           // Open the default web.xml file, if it exists
  729           if( defaultContextXml==null && context instanceof StandardContext ) {
  730               defaultContextXml = ((StandardContext)context).getDefaultContextXml();
  731           }
  732           // set the default if we don't have any overrides
  733           if( defaultContextXml==null ) getDefaultContextXml();
  734   
  735           if (!context.getOverride()) {
  736               processContextConfig(new File(getBaseDir()), defaultContextXml);
  737               processContextConfig(getConfigBase(), getHostConfigPath(Constants.HostContextXml));
  738           }
  739           if (context.getConfigFile() != null)
  740               processContextConfig(new File(context.getConfigFile()), null);
  741           
  742       }
  743   
  744       
  745       /**
  746        * Process a context.xml.
  747        */
  748       protected void processContextConfig(File baseDir, String resourceName) {
  749           
  750           if (log.isDebugEnabled())
  751               log.debug("Processing context [" + context.getName() 
  752                       + "] configuration file " + baseDir + " " + resourceName);
  753   
  754           InputSource source = null;
  755           InputStream stream = null;
  756   
  757           File file = baseDir;
  758           if (resourceName != null) {
  759               file = new File(baseDir, resourceName);
  760           }
  761           
  762           try {
  763               if ( !file.exists() ) {
  764                   if (resourceName != null) {
  765                       // Use getResource and getResourceAsStream
  766                       stream = getClass().getClassLoader()
  767                           .getResourceAsStream(resourceName);
  768                       if( stream != null ) {
  769                           source = new InputSource
  770                               (getClass().getClassLoader()
  771                               .getResource(resourceName).toString());
  772                       }
  773                   }
  774               } else {
  775                   source =
  776                       new InputSource("file://" + file.getAbsolutePath());
  777                   stream = new FileInputStream(file);
  778                   // Add as watched resource so that cascade reload occurs if a default
  779                   // config file is modified/added/removed
  780                   context.addWatchedResource(file.getAbsolutePath());
  781               }
  782           } catch (Exception e) {
  783               log.error(sm.getString("contextConfig.contextMissing",  
  784                         resourceName + " " + file) , e);
  785           }
  786           
  787           if (source == null)
  788               return;
  789           if (contextDigester == null){
  790               contextDigester = createContextDigester();
  791           }
  792           synchronized (contextDigester) {
  793               try {
  794                   source.setByteStream(stream);
  795                   contextDigester.setClassLoader(this.getClass().getClassLoader());
  796                   contextDigester.setUseContextClassLoader(false);
  797                   contextDigester.push(context.getParent());
  798                   contextDigester.push(context);
  799                   contextDigester.setErrorHandler(new ContextErrorHandler());
  800                   contextDigester.parse(source);
  801                   if (parseException != null) {
  802                       ok = false;
  803                   }
  804                   if (log.isDebugEnabled())
  805                       log.debug("Successfully processed context [" + context.getName() 
  806                               + "] configuration file " + baseDir + " " + resourceName);
  807               } catch (SAXParseException e) {
  808                   log.error(sm.getString("contextConfig.contextParse",
  809                           context.getName()), e);
  810                   log.error(sm.getString("contextConfig.defaultPosition",
  811                                    "" + e.getLineNumber(),
  812                                    "" + e.getColumnNumber()));
  813                   ok = false;
  814               } catch (Exception e) {
  815                   log.error(sm.getString("contextConfig.contextParse",
  816                           context.getName()), e);
  817                   ok = false;
  818               } finally {
  819                   contextDigester.reset();
  820                   parseException = null;
  821                   try {
  822                       if (stream != null) {
  823                           stream.close();
  824                       }
  825                   } catch (IOException e) {
  826                       log.error(sm.getString("contextConfig.contextClose"), e);
  827                   }
  828               }
  829           }
  830       }
  831   
  832       
  833       /**
  834        * Adjust docBase.
  835        */
  836       protected void fixDocBase()
  837           throws IOException {
  838           
  839           Host host = (Host) context.getParent();
  840           String appBase = host.getAppBase();
  841   
  842           boolean unpackWARs = true;
  843           if (host instanceof StandardHost) {
  844               unpackWARs = ((StandardHost) host).isUnpackWARs() 
  845                   && ((StandardContext) context).getUnpackWAR();
  846           }
  847   
  848           File canonicalAppBase = new File(appBase);
  849           if (canonicalAppBase.isAbsolute()) {
  850               canonicalAppBase = canonicalAppBase.getCanonicalFile();
  851           } else {
  852               canonicalAppBase = 
  853                   new File(System.getProperty("catalina.base"), appBase)
  854                   .getCanonicalFile();
  855           }
  856   
  857           String docBase = context.getDocBase();
  858           if (docBase == null) {
  859               // Trying to guess the docBase according to the path
  860               String path = context.getPath();
  861               if (path == null) {
  862                   return;
  863               }
  864               if (path.equals("")) {
  865                   docBase = "ROOT";
  866               } else {
  867                   if (path.startsWith("/")) {
  868                       docBase = path.substring(1);
  869                   } else {
  870                       docBase = path;
  871                   }
  872               }
  873           }
  874   
  875           File file = new File(docBase);
  876           if (!file.isAbsolute()) {
  877               docBase = (new File(canonicalAppBase, docBase)).getPath();
  878           } else {
  879               docBase = file.getCanonicalPath();
  880           }
  881           file = new File(docBase);
  882           String origDocBase = docBase;
  883           
  884           String contextPath = context.getPath();
  885           if (contextPath.equals("")) {
  886               contextPath = "ROOT";
  887           }
  888           if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
  889               URL war = new URL("jar:" + (new File(docBase)).toURL() + "!/");
  890               docBase = ExpandWar.expand(host, war, contextPath);
  891               file = new File(docBase);
  892               docBase = file.getCanonicalPath();
  893               if (context instanceof StandardContext) {
  894                   ((StandardContext) context).setOriginalDocBase(origDocBase);
  895               }
  896           } else {
  897               File docDir = new File(docBase);
  898               if (!docDir.exists()) {
  899                   File warFile = new File(docBase + ".war");
  900                   if (warFile.exists()) {
  901                       if (unpackWARs) {
  902                           URL war = new URL("jar:" + warFile.toURL() + "!/");
  903                           docBase = ExpandWar.expand(host, war, contextPath);
  904                           file = new File(docBase);
  905                           docBase = file.getCanonicalPath();
  906                       } else {
  907                           docBase = warFile.getCanonicalPath();
  908                       }
  909                   }
  910                   if (context instanceof StandardContext) {
  911                       ((StandardContext) context).setOriginalDocBase(origDocBase);
  912                   }
  913               }
  914           }
  915   
  916           if (docBase.startsWith(canonicalAppBase.getPath())) {
  917               docBase = docBase.substring(canonicalAppBase.getPath().length());
  918               docBase = docBase.replace(File.separatorChar, '/');
  919               if (docBase.startsWith("/")) {
  920                   docBase = docBase.substring(1);
  921               }
  922           } else {
  923               docBase = docBase.replace(File.separatorChar, '/');
  924           }
  925   
  926           context.setDocBase(docBase);
  927   
  928       }
  929       
  930       
  931       protected void antiLocking()
  932           throws IOException {
  933   
  934           if ((context instanceof StandardContext) 
  935               && ((StandardContext) context).getAntiResourceLocking()) {
  936               
  937               Host host = (Host) context.getParent();
  938               String appBase = host.getAppBase();
  939               String docBase = context.getDocBase();
  940               if (docBase == null)
  941                   return;
  942               if (originalDocBase == null) {
  943                   originalDocBase = docBase;
  944               } else {
  945                   docBase = originalDocBase;
  946               }
  947               File docBaseFile = new File(docBase);
  948               if (!docBaseFile.isAbsolute()) {
  949                   File file = new File(appBase);
  950                   if (!file.isAbsolute()) {
  951                       file = new File(System.getProperty("catalina.base"), appBase);
  952                   }
  953                   docBaseFile = new File(file, docBase);
  954               }
  955               
  956               String path = context.getPath();
  957               if (path == null) {
  958                   return;
  959               }
  960               if (path.equals("")) {
  961                   docBase = "ROOT";
  962               } else {
  963                   if (path.startsWith("/")) {
  964                       docBase = path.substring(1);
  965                   } else {
  966                       docBase = path;
  967                   }
  968               }
  969   
  970               File file = null;
  971               if (docBase.toLowerCase().endsWith(".war")) {
  972                   file = new File(System.getProperty("java.io.tmpdir"),
  973                           deploymentCount++ + "-" + docBase + ".war");
  974               } else {
  975                   file = new File(System.getProperty("java.io.tmpdir"), 
  976                           deploymentCount++ + "-" + docBase);
  977               }
  978               
  979               if (log.isDebugEnabled())
  980                   log.debug("Anti locking context[" + context.getPath() 
  981                           + "] setting docBase to " + file);
  982               
  983               // Cleanup just in case an old deployment is lying around
  984               ExpandWar.delete(file);
  985               if (ExpandWar.copy(docBaseFile, file)) {
  986                   context.setDocBase(file.getAbsolutePath());
  987               }
  988               
  989           }
  990           
  991       }
  992       
  993   
  994       /**
  995        * Process a "init" event for this Context.
  996        */
  997       protected void init() {
  998           // Called from StandardContext.init()
  999   
 1000           if (log.isDebugEnabled())
 1001               log.debug(sm.getString("contextConfig.init"));
 1002           context.setConfigured(false);
 1003           ok = true;
 1004           
 1005           contextConfig();
 1006           
 1007           try {
 1008               fixDocBase();
 1009           } catch (IOException e) {
 1010               log.error(sm.getString("contextConfig.fixDocBase"), e);
 1011           }
 1012           
 1013       }
 1014       
 1015       
 1016       /**
 1017        * Process a "before start" event for this Context.
 1018        */
 1019       protected synchronized void beforeStart() {
 1020           
 1021           try {
 1022               antiLocking();
 1023           } catch (IOException e) {
 1024               log.error(sm.getString("contextConfig.antiLocking"), e);
 1025           }
 1026           
 1027       }
 1028       
 1029       
 1030       /**
 1031        * Process a "start" event for this Context.
 1032        */
 1033       protected synchronized void start() {
 1034           // Called from StandardContext.start()
 1035   
 1036           if (log.isDebugEnabled())
 1037               log.debug(sm.getString("contextConfig.start"));
 1038   
 1039           // Set properties based on DefaultContext
 1040           Container container = context.getParent();
 1041           if( !context.getOverride() ) {
 1042               if( container instanceof Host ) {
 1043                   // Reset the value only if the attribute wasn't
 1044                   // set on the context.
 1045                   xmlValidation = context.getXmlValidation();
 1046                   if (!xmlValidation) {
 1047                       xmlValidation = ((Host)container).getXmlValidation();
 1048                   }
 1049                   
 1050                   xmlNamespaceAware = context.getXmlNamespaceAware();
 1051                   if (!xmlNamespaceAware){
 1052                       xmlNamespaceAware 
 1053                                   = ((Host)container).getXmlNamespaceAware();
 1054                   }
 1055   
 1056                   container = container.getParent();
 1057               }
 1058           }
 1059   
 1060           // Process the default and application web.xml files
 1061           defaultWebConfig();
 1062           applicationWebConfig();
 1063           if (!context.getIgnoreAnnotations()) {
 1064               applicationAnnotationsConfig();
 1065           }
 1066           if (ok) {
 1067               validateSecurityRoles();
 1068           }
 1069   
 1070           // Configure an authenticator if we need one
 1071           if (ok)
 1072               authenticatorConfig();
 1073   
 1074           // Dump the contents of this pipeline if requested
 1075           if ((log.isDebugEnabled()) && (context instanceof ContainerBase)) {
 1076               log.debug("Pipeline Configuration:");
 1077               Pipeline pipeline = ((ContainerBase) context).getPipeline();
 1078               Valve valves[] = null;
 1079               if (pipeline != null)
 1080                   valves = pipeline.getValves();
 1081               if (valves != null) {
 1082                   for (int i = 0; i < valves.length; i++) {
 1083                       log.debug("  " + valves[i].getInfo());
 1084                   }
 1085               }
 1086               log.debug("======================");
 1087           }
 1088   
 1089           // Make our application available if no problems were encountered
 1090           if (ok)
 1091               context.setConfigured(true);
 1092           else {
 1093               log.error(sm.getString("contextConfig.unavailable"));
 1094               context.setConfigured(false);
 1095           }
 1096   
 1097       }
 1098   
 1099   
 1100       /**
 1101        * Process a "stop" event for this Context.
 1102        */
 1103       protected synchronized void stop() {
 1104   
 1105           if (log.isDebugEnabled())
 1106               log.debug(sm.getString("contextConfig.stop"));
 1107   
 1108           int i;
 1109   
 1110           // Removing children
 1111           Container[] children = context.findChildren();
 1112           for (i = 0; i < children.length; i++) {
 1113               context.removeChild(children[i]);
 1114           }
 1115   
 1116           // Removing application parameters
 1117           /*
 1118           ApplicationParameter[] applicationParameters =
 1119               context.findApplicationParameters();
 1120           for (i = 0; i < applicationParameters.length; i++) {
 1121               context.removeApplicationParameter
 1122                   (applicationParameters[i].getName());
 1123           }
 1124           */
 1125   
 1126           // Removing security constraints
 1127           SecurityConstraint[] securityConstraints = context.findConstraints();
 1128           for (i = 0; i < securityConstraints.length; i++) {
 1129               context.removeConstraint(securityConstraints[i]);
 1130           }
 1131   
 1132           // Removing Ejbs
 1133           /*
 1134           ContextEjb[] contextEjbs = context.findEjbs();
 1135           for (i = 0; i < contextEjbs.length; i++) {
 1136               context.removeEjb(contextEjbs[i].getName());
 1137           }
 1138           */
 1139   
 1140           // Removing environments
 1141           /*
 1142           ContextEnvironment[] contextEnvironments = context.findEnvironments();
 1143           for (i = 0; i < contextEnvironments.length; i++) {
 1144               context.removeEnvironment(contextEnvironments[i].getName());
 1145           }
 1146           */
 1147   
 1148           // Removing errors pages
 1149           ErrorPage[] errorPages = context.findErrorPages();
 1150           for (i = 0; i < errorPages.length; i++) {
 1151               context.removeErrorPage(errorPages[i]);
 1152           }
 1153   
 1154           // Removing filter defs
 1155           FilterDef[] filterDefs = context.findFilterDefs();
 1156           for (i = 0; i < filterDefs.length; i++) {
 1157               context.removeFilterDef(filterDefs[i]);
 1158           }
 1159   
 1160           // Removing filter maps
 1161           FilterMap[] filterMaps = context.findFilterMaps();
 1162           for (i = 0; i < filterMaps.length; i++) {
 1163               context.removeFilterMap(filterMaps[i]);
 1164           }
 1165   
 1166           // Removing local ejbs
 1167           /*
 1168           ContextLocalEjb[] contextLocalEjbs = context.findLocalEjbs();
 1169           for (i = 0; i < contextLocalEjbs.length; i++) {
 1170               context.removeLocalEjb(contextLocalEjbs[i].getName());
 1171           }
 1172           */
 1173   
 1174           // Removing Mime mappings
 1175           String[] mimeMappings = context.findMimeMappings();
 1176           for (i = 0; i < mimeMappings.length; i++) {
 1177               context.removeMimeMapping(mimeMappings[i]);
 1178           }
 1179   
 1180           // Removing parameters
 1181           String[] parameters = context.findParameters();
 1182           for (i = 0; i < parameters.length; i++) {
 1183               context.removeParameter(parameters[i]);
 1184           }
 1185   
 1186           // Removing resource env refs
 1187           /*
 1188           String[] resourceEnvRefs = context.findResourceEnvRefs();
 1189           for (i = 0; i < resourceEnvRefs.length; i++) {
 1190               context.removeResourceEnvRef(resourceEnvRefs[i]);
 1191           }
 1192           */
 1193   
 1194           // Removing resource links
 1195           /*
 1196           ContextResourceLink[] contextResourceLinks =
 1197               context.findResourceLinks();
 1198           for (i = 0; i < contextResourceLinks.length; i++) {
 1199               context.removeResourceLink(contextResourceLinks[i].getName());
 1200           }
 1201           */
 1202   
 1203           // Removing resources
 1204           /*
 1205           ContextResource[] contextResources = context.findResources();
 1206           for (i = 0; i < contextResources.length; i++) {
 1207               context.removeResource(contextResources[i].getName());
 1208           }
 1209           */
 1210   
 1211           // Removing sercurity role
 1212           String[] securityRoles = context.findSecurityRoles();
 1213           for (i = 0; i < securityRoles.length; i++) {
 1214               context.removeSecurityRole(securityRoles[i]);
 1215           }
 1216   
 1217           // Removing servlet mappings
 1218           String[] servletMappings = context.findServletMappings();
 1219           for (i = 0; i < servletMappings.length; i++) {
 1220               context.removeServletMapping(servletMappings[i]);
 1221           }
 1222   
 1223           // FIXME : Removing status pages
 1224   
 1225           // Removing taglibs
 1226           String[] taglibs = context.findTaglibs();
 1227           for (i = 0; i < taglibs.length; i++) {
 1228               context.removeTaglib(taglibs[i]);
 1229           }
 1230   
 1231           // Removing welcome files
 1232           String[] welcomeFiles = context.findWelcomeFiles();
 1233           for (i = 0; i < welcomeFiles.length; i++) {
 1234               context.removeWelcomeFile(welcomeFiles[i]);
 1235           }
 1236   
 1237           // Removing wrapper lifecycles
 1238           String[] wrapperLifecycles = context.findWrapperLifecycles();
 1239           for (i = 0; i < wrapperLifecycles.length; i++) {
 1240               context.removeWrapperLifecycle(wrapperLifecycles[i]);
 1241           }
 1242   
 1243           // Removing wrapper listeners
 1244           String[] wrapperListeners = context.findWrapperListeners();
 1245           for (i = 0; i < wrapperListeners.length; i++) {
 1246               context.removeWrapperListener(wrapperListeners[i]);
 1247           }
 1248   
 1249           // Remove (partially) folders and files created by antiLocking
 1250           Host host = (Host) context.getParent();
 1251           String appBase = host.getAppBase();
 1252           String docBase = context.getDocBase();
 1253           if ((docBase != null) && (originalDocBase != null)) {
 1254               File docBaseFile = new File(docBase);
 1255               if (!docBaseFile.isAbsolute()) {
 1256                   docBaseFile = new File(appBase, docBase);
 1257               }
 1258               ExpandWar.delete(docBaseFile);
 1259           }
 1260           
 1261           ok = true;
 1262   
 1263       }
 1264       
 1265       
 1266       /**
 1267        * Process a "destroy" event for this Context.
 1268        */
 1269       protected synchronized void destroy() {
 1270           // Called from StandardContext.destroy()
 1271           if (log.isDebugEnabled())
 1272               log.debug(sm.getString("contextConfig.destroy"));
 1273   
 1274           // Changed to getWorkPath per Bugzilla 35819.
 1275           String workDir = ((StandardContext) context).getWorkPath();
 1276           if (workDir != null)
 1277               ExpandWar.delete(new File(workDir));
 1278       }
 1279       
 1280       
 1281       /**
 1282        * Validate the usage of security role names in the web application
 1283        * deployment descriptor.  If any problems are found, issue warning
 1284        * messages (for backwards compatibility) and add the missing roles.
 1285        * (To make these problems fatal instead, simply set the <code>ok</code>
 1286        * instance variable to <code>false</code> as well).
 1287        */
 1288       protected void validateSecurityRoles() {
 1289   
 1290           // Check role names used in <security-constraint> elements
 1291           SecurityConstraint constraints[] = context.findConstraints();
 1292           for (int i = 0; i < constraints.length; i++) {
 1293               String roles[] = constraints[i].findAuthRoles();
 1294               for (int j = 0; j < roles.length; j++) {
 1295                   if (!"*".equals(roles[j]) &&
 1296                       !context.findSecurityRole(roles[j])) {
 1297                       log.info(sm.getString("contextConfig.role.auth", roles[j]));
 1298                       context.addSecurityRole(roles[j]);
 1299                   }
 1300               }
 1301           }
 1302   
 1303           // Check role names used in <servlet> elements
 1304           Container wrappers[] = context.findChildren();
 1305           for (int i = 0; i < wrappers.length; i++) {
 1306               Wrapper wrapper = (Wrapper) wrappers[i];
 1307               String runAs = wrapper.getRunAs();
 1308               if ((runAs != null) && !context.findSecurityRole(runAs)) {
 1309                   log.info(sm.getString("contextConfig.role.runas", runAs));
 1310                   context.addSecurityRole(runAs);
 1311               }
 1312               String names[] = wrapper.findSecurityReferences();
 1313               for (int j = 0; j < names.length; j++) {
 1314                   String link = wrapper.findSecurityReference(names[j]);
 1315                   if ((link != null) && !context.findSecurityRole(link)) {
 1316                       log.info(sm.getString("contextConfig.role.link", link));
 1317                       context.addSecurityRole(link);
 1318                   }
 1319               }
 1320           }
 1321   
 1322       }
 1323   
 1324   
 1325       /**
 1326        * Get config base.
 1327        */
 1328       protected File getConfigBase() {
 1329           File configBase = 
 1330               new File(System.getProperty("catalina.base"), "conf");
 1331           if (!configBase.exists()) {
 1332               return null;
 1333           } else {
 1334               return configBase;
 1335           }
 1336       }  
 1337   
 1338       
 1339       protected String getHostConfigPath(String resourceName) {
 1340           StringBuffer result = new StringBuffer();
 1341           Container container = context;
 1342           Container host = null;
 1343           Container engine = null;
 1344           while (container != null) {
 1345               if (container instanceof Host)
 1346                   host = container;
 1347               if (container instanceof Engine)
 1348                   engine = container;
 1349               container = container.getParent();
 1350           }
 1351           if (engine != null) {
 1352               result.append(engine.getName()).append('/');
 1353           }
 1354           if (host != null) {
 1355               result.append(host.getName()).append('/');
 1356           }
 1357           result.append(resourceName);
 1358           return result.toString();
 1359       }
 1360   
 1361   
 1362       protected class ContextErrorHandler
 1363           implements ErrorHandler {
 1364   
 1365           public void error(SAXParseException exception) {
 1366               parseException = exception;
 1367           }
 1368   
 1369           public void fatalError(SAXParseException exception) {
 1370               parseException = exception;
 1371           }
 1372   
 1373           public void warning(SAXParseException exception) {
 1374               parseException = exception;
 1375           }
 1376   
 1377       }
 1378   
 1379   
 1380   }

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