Save This Page
Home » apache-tomcat-6.0.26-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: 892815 $ $Date: 2009-12-21 14:27:57 +0100 (Mon, 21 Dec 2009) $
   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           URL url=null;
  343           // Process the application web.xml file
  344           synchronized (webDigester) {
  345               try {
  346                   if (altDDName != null) {
  347                       url = new File(altDDName).toURL();
  348                   } else {
  349                       url = servletContext.getResource(
  350                                                   Constants.ApplicationWebXml);
  351                   }
  352                   if( url!=null ) {
  353                       InputSource is = new InputSource(url.toExternalForm());
  354                       is.setByteStream(stream);
  355                       if (context instanceof StandardContext) {
  356                           ((StandardContext) context).setReplaceWelcomeFiles(true);
  357                       }
  358                       webDigester.push(context);
  359                       webDigester.setErrorHandler(new ContextErrorHandler());
  360   
  361                       if(log.isDebugEnabled()) {
  362                           log.debug("Parsing application web.xml file at " + url.toExternalForm());
  363                       }
  364   
  365                       webDigester.parse(is);
  366   
  367                       if (parseException != null) {
  368                           ok = false;
  369                       }
  370                   } else {
  371                       log.info("No web.xml, using defaults " + context );
  372                   }
  373               } catch (SAXParseException e) {
  374                   log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
  375                   log.error(sm.getString("contextConfig.applicationPosition",
  376                                    "" + e.getLineNumber(),
  377                                    "" + e.getColumnNumber()));
  378                   ok = false;
  379               } catch (Exception e) {
  380                   log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
  381                   ok = false;
  382               } finally {
  383                   webDigester.reset();
  384                   parseException = null;
  385                   try {
  386                       if (stream != null) {
  387                           stream.close();
  388                       }
  389                   } catch (IOException e) {
  390                       log.error(sm.getString("contextConfig.applicationClose"), e);
  391                   }
  392               }
  393           }
  394           webRuleSet.recycle();
  395   
  396           long t2=System.currentTimeMillis();
  397           if (context instanceof StandardContext) {
  398               ((StandardContext) context).setStartupTime(t2-t1);
  399           }
  400       }
  401   
  402   
  403       /**
  404        * Set up an Authenticator automatically if required, and one has not
  405        * already been configured.
  406        */
  407       protected synchronized void authenticatorConfig() {
  408   
  409           // Does this Context require an Authenticator?
  410           SecurityConstraint constraints[] = context.findConstraints();
  411           if ((constraints == null) || (constraints.length == 0))
  412               return;
  413           LoginConfig loginConfig = context.getLoginConfig();
  414           if (loginConfig == null) {
  415               loginConfig = DUMMY_LOGIN_CONFIG;
  416               context.setLoginConfig(loginConfig);
  417           }
  418   
  419           // Has an authenticator been configured already?
  420           if (context instanceof Authenticator)
  421               return;
  422           if (context instanceof ContainerBase) {
  423               Pipeline pipeline = ((ContainerBase) context).getPipeline();
  424               if (pipeline != null) {
  425                   Valve basic = pipeline.getBasic();
  426                   if ((basic != null) && (basic instanceof Authenticator))
  427                       return;
  428                   Valve valves[] = pipeline.getValves();
  429                   for (int i = 0; i < valves.length; i++) {
  430                       if (valves[i] instanceof Authenticator)
  431                           return;
  432                   }
  433               }
  434           } else {
  435               return;     // Cannot install a Valve even if it would be needed
  436           }
  437   
  438           // Has a Realm been configured for us to authenticate against?
  439           if (context.getRealm() == null) {
  440               log.error(sm.getString("contextConfig.missingRealm"));
  441               ok = false;
  442               return;
  443           }
  444   
  445           /*
  446            * First check to see if there is a custom mapping for the login
  447            * method. If so, use it. Otherwise, check if there is a mapping in
  448            * org/apache/catalina/startup/Authenticators.properties.
  449            */
  450           Valve authenticator = null;
  451           if (customAuthenticators != null) {
  452               authenticator = (Valve)
  453                   customAuthenticators.get(loginConfig.getAuthMethod());
  454           }
  455           if (authenticator == null) {
  456               // Load our mapping properties if necessary
  457               if (authenticators == null) {
  458                   try {
  459                       InputStream is=this.getClass().getClassLoader().getResourceAsStream("org/apache/catalina/startup/Authenticators.properties");
  460                       if( is!=null ) {
  461                           authenticators = new Properties();
  462                           authenticators.load(is);
  463                       } else {
  464                           log.error(sm.getString(
  465                                   "contextConfig.authenticatorResources"));
  466                           ok=false;
  467                           return;
  468                       }
  469                   } catch (IOException e) {
  470                       log.error(sm.getString(
  471                                   "contextConfig.authenticatorResources"), e);
  472                       ok = false;
  473                       return;
  474                   }
  475               }
  476   
  477               // Identify the class name of the Valve we should configure
  478               String authenticatorName = null;
  479               authenticatorName =
  480                       authenticators.getProperty(loginConfig.getAuthMethod());
  481               if (authenticatorName == null) {
  482                   log.error(sm.getString("contextConfig.authenticatorMissing",
  483                                    loginConfig.getAuthMethod()));
  484                   ok = false;
  485                   return;
  486               }
  487   
  488               // Instantiate and install an Authenticator of the requested class
  489               try {
  490                   Class authenticatorClass = Class.forName(authenticatorName);
  491                   authenticator = (Valve) authenticatorClass.newInstance();
  492               } catch (Throwable t) {
  493                   log.error(sm.getString(
  494                                       "contextConfig.authenticatorInstantiate",
  495                                       authenticatorName),
  496                             t);
  497                   ok = false;
  498               }
  499           }
  500   
  501           if (authenticator != null && context instanceof ContainerBase) {
  502               Pipeline pipeline = ((ContainerBase) context).getPipeline();
  503               if (pipeline != null) {
  504                   ((ContainerBase) context).addValve(authenticator);
  505                   if (log.isDebugEnabled()) {
  506                       log.debug(sm.getString(
  507                                       "contextConfig.authenticatorConfigured",
  508                                       loginConfig.getAuthMethod()));
  509                   }
  510               }
  511           }
  512   
  513       }
  514   
  515   
  516       /**
  517        * Create (if necessary) and return a Digester configured to process the
  518        * web application deployment descriptor (web.xml).
  519        */
  520       protected static Digester createWebDigester() {
  521           Digester webDigester =
  522               createWebXmlDigester(xmlNamespaceAware, xmlValidation);
  523           return webDigester;
  524       }
  525   
  526   
  527       /**
  528        * Create (if necessary) and return a Digester configured to process the
  529        * web application deployment descriptor (web.xml).
  530        */
  531       public static Digester createWebXmlDigester(boolean namespaceAware,
  532                                                   boolean validation) {
  533           
  534           Digester webDigester =  DigesterFactory.newDigester(xmlValidation,
  535                                                               xmlNamespaceAware,
  536                                                               webRuleSet);
  537           return webDigester;
  538       }
  539   
  540       
  541       /**
  542        * Create (if necessary) and return a Digester configured to process the
  543        * context configuration descriptor for an application.
  544        */
  545       protected Digester createContextDigester() {
  546           Digester digester = new Digester();
  547           digester.setValidating(false);
  548           RuleSet contextRuleSet = new ContextRuleSet("", false);
  549           digester.addRuleSet(contextRuleSet);
  550           RuleSet namingRuleSet = new NamingRuleSet("Context/");
  551           digester.addRuleSet(namingRuleSet);
  552           return digester;
  553       }
  554   
  555   
  556       protected String getBaseDir() {
  557           Container engineC=context.getParent().getParent();
  558           if( engineC instanceof StandardEngine ) {
  559               return ((StandardEngine)engineC).getBaseDir();
  560           }
  561           return System.getProperty("catalina.base");
  562       }
  563   
  564       /**
  565        * Process the default configuration file, if it exists.
  566        * The default config must be read with the container loader - so
  567        * container servlets can be loaded
  568        */
  569       protected void defaultWebConfig() {
  570           long t1=System.currentTimeMillis();
  571   
  572           // Open the default web.xml file, if it exists
  573           if( defaultWebXml==null && context instanceof StandardContext ) {
  574               defaultWebXml=((StandardContext)context).getDefaultWebXml();
  575           }
  576           // set the default if we don't have any overrides
  577           if( defaultWebXml==null ) getDefaultWebXml();
  578   
  579           File file = new File(this.defaultWebXml);
  580           if (!file.isAbsolute()) {
  581               file = new File(getBaseDir(),
  582                               this.defaultWebXml);
  583           }
  584   
  585           InputStream stream = null;
  586           InputSource source = null;
  587   
  588           try {
  589               if ( ! file.exists() ) {
  590                   // Use getResource and getResourceAsStream
  591                   stream = getClass().getClassLoader()
  592                       .getResourceAsStream(defaultWebXml);
  593                   if( stream != null ) {
  594                       source = new InputSource
  595                               (getClass().getClassLoader()
  596                               .getResource(defaultWebXml).toString());
  597                   } 
  598                   if( stream== null ) { 
  599                       // maybe embedded
  600                       stream = getClass().getClassLoader()
  601                           .getResourceAsStream("web-embed.xml");
  602                       if( stream != null ) {
  603                           source = new InputSource
  604                           (getClass().getClassLoader()
  605                                   .getResource("web-embed.xml").toString());
  606                       }                                         
  607                   }
  608                   
  609                   if( stream== null ) {
  610                       log.info("No default web.xml");
  611                   }
  612               } else {
  613                   source =
  614                       new InputSource("file://" + file.getAbsolutePath());
  615                   stream = new FileInputStream(file);
  616                   context.addWatchedResource(file.getAbsolutePath());
  617               }
  618           } catch (Exception e) {
  619               log.error(sm.getString("contextConfig.defaultMissing") 
  620                         + " " + defaultWebXml + " " + file , e);
  621           }
  622   
  623           if (stream != null) {
  624               processDefaultWebConfig(webDigester, stream, source);
  625               webRuleSet.recycle();
  626           }
  627   
  628           long t2=System.currentTimeMillis();
  629           if( (t2-t1) > 200 )
  630               log.debug("Processed default web.xml " + file + " "  + ( t2-t1));
  631   
  632           stream = null;
  633           source = null;
  634   
  635           String resourceName = getHostConfigPath(Constants.HostWebXml);
  636           file = new File(getConfigBase(), resourceName);
  637           
  638           try {
  639               if ( ! file.exists() ) {
  640                   // Use getResource and getResourceAsStream
  641                   stream = getClass().getClassLoader()
  642                       .getResourceAsStream(resourceName);
  643                   if( stream != null ) {
  644                       source = new InputSource
  645                               (getClass().getClassLoader()
  646                               .getResource(resourceName).toString());
  647                   }
  648               } else {
  649                   source =
  650                       new InputSource("file://" + file.getAbsolutePath());
  651                   stream = new FileInputStream(file);
  652               }
  653           } catch (Exception e) {
  654               log.error(sm.getString("contextConfig.defaultMissing") 
  655                         + " " + resourceName + " " + file , e);
  656           }
  657   
  658           if (stream != null) {
  659               processDefaultWebConfig(webDigester, stream, source);
  660               webRuleSet.recycle();
  661           }
  662   
  663       }
  664   
  665   
  666       /**
  667        * Process a default web.xml.
  668        */
  669       protected void processDefaultWebConfig(Digester digester, InputStream stream, 
  670               InputSource source) {
  671   
  672           if (log.isDebugEnabled())
  673               log.debug("Processing context [" + context.getName() 
  674                       + "] web configuration resource " + source.getSystemId());
  675   
  676           // Process the default web.xml file
  677           synchronized (digester) {
  678               try {
  679                   source.setByteStream(stream);
  680                   
  681                   if (context instanceof StandardContext)
  682                       ((StandardContext) context).setReplaceWelcomeFiles(true);
  683                   digester.setClassLoader(this.getClass().getClassLoader());
  684                   digester.setUseContextClassLoader(false);
  685                   digester.push(context);
  686                   digester.setErrorHandler(new ContextErrorHandler());
  687                   digester.parse(source);
  688                   if (parseException != null) {
  689                       ok = false;
  690                   }
  691               } catch (SAXParseException e) {
  692                   log.error(sm.getString("contextConfig.defaultParse"), e);
  693                   log.error(sm.getString("contextConfig.defaultPosition",
  694                                    "" + e.getLineNumber(),
  695                                    "" + e.getColumnNumber()));
  696                   ok = false;
  697               } catch (Exception e) {
  698                   log.error(sm.getString("contextConfig.defaultParse"), e);
  699                   ok = false;
  700               } finally {
  701                   digester.reset();
  702                   parseException = null;
  703                   try {
  704                       if (stream != null) {
  705                           stream.close();
  706                       }
  707                   } catch (IOException e) {
  708                       log.error(sm.getString("contextConfig.defaultClose"), e);
  709                   }
  710               }
  711           }
  712       }
  713   
  714   
  715       /**
  716        * Process the default configuration file, if it exists.
  717        */
  718       protected void contextConfig() {
  719           
  720           // Open the default web.xml file, if it exists
  721           if( defaultContextXml==null && context instanceof StandardContext ) {
  722               defaultContextXml = ((StandardContext)context).getDefaultContextXml();
  723           }
  724           // set the default if we don't have any overrides
  725           if( defaultContextXml==null ) getDefaultContextXml();
  726   
  727           if (!context.getOverride()) {
  728               processContextConfig(new File(getBaseDir()), defaultContextXml);
  729               processContextConfig(getConfigBase(), getHostConfigPath(Constants.HostContextXml));
  730           }
  731           if (context.getConfigFile() != null)
  732               processContextConfig(new File(context.getConfigFile()), null);
  733           
  734       }
  735   
  736       
  737       /**
  738        * Process a context.xml.
  739        */
  740       protected void processContextConfig(File baseDir, String resourceName) {
  741           
  742           if (log.isDebugEnabled())
  743               log.debug("Processing context [" + context.getName() 
  744                       + "] configuration file " + baseDir + " " + resourceName);
  745   
  746           InputSource source = null;
  747           InputStream stream = null;
  748   
  749           File file = baseDir;
  750           if (resourceName != null) {
  751               file = new File(baseDir, resourceName);
  752           }
  753           
  754           try {
  755               if ( !file.exists() ) {
  756                   if (resourceName != null) {
  757                       // Use getResource and getResourceAsStream
  758                       stream = getClass().getClassLoader()
  759                           .getResourceAsStream(resourceName);
  760                       if( stream != null ) {
  761                           source = new InputSource
  762                               (getClass().getClassLoader()
  763                               .getResource(resourceName).toString());
  764                       }
  765                   }
  766               } else {
  767                   source =
  768                       new InputSource("file://" + file.getAbsolutePath());
  769                   stream = new FileInputStream(file);
  770                   // Add as watched resource so that cascade reload occurs if a default
  771                   // config file is modified/added/removed
  772                   context.addWatchedResource(file.getAbsolutePath());
  773               }
  774           } catch (Exception e) {
  775               log.error(sm.getString("contextConfig.contextMissing",  
  776                         resourceName + " " + file) , e);
  777           }
  778           
  779           if (source == null)
  780               return;
  781           synchronized (contextDigester) {
  782               try {
  783                   source.setByteStream(stream);
  784                   contextDigester.setClassLoader(this.getClass().getClassLoader());
  785                   contextDigester.setUseContextClassLoader(false);
  786                   contextDigester.push(context.getParent());
  787                   contextDigester.push(context);
  788                   contextDigester.setErrorHandler(new ContextErrorHandler());
  789                   contextDigester.parse(source);
  790                   if (parseException != null) {
  791                       ok = false;
  792                   }
  793                   if (log.isDebugEnabled())
  794                       log.debug("Successfully processed context [" + context.getName() 
  795                               + "] configuration file " + baseDir + " " + resourceName);
  796               } catch (SAXParseException e) {
  797                   log.error(sm.getString("contextConfig.contextParse",
  798                           context.getName()), e);
  799                   log.error(sm.getString("contextConfig.defaultPosition",
  800                                    "" + e.getLineNumber(),
  801                                    "" + e.getColumnNumber()));
  802                   ok = false;
  803               } catch (Exception e) {
  804                   log.error(sm.getString("contextConfig.contextParse",
  805                           context.getName()), e);
  806                   ok = false;
  807               } finally {
  808                   contextDigester.reset();
  809                   parseException = null;
  810                   try {
  811                       if (stream != null) {
  812                           stream.close();
  813                       }
  814                   } catch (IOException e) {
  815                       log.error(sm.getString("contextConfig.contextClose"), e);
  816                   }
  817               }
  818           }
  819       }
  820   
  821       
  822       /**
  823        * Adjust docBase.
  824        */
  825       protected void fixDocBase()
  826           throws IOException {
  827           
  828           Host host = (Host) context.getParent();
  829           String appBase = host.getAppBase();
  830   
  831           boolean unpackWARs = true;
  832           if (host instanceof StandardHost) {
  833               unpackWARs = ((StandardHost) host).isUnpackWARs() 
  834                   && ((StandardContext) context).getUnpackWAR();
  835           }
  836   
  837           File canonicalAppBase = new File(appBase);
  838           if (canonicalAppBase.isAbsolute()) {
  839               canonicalAppBase = canonicalAppBase.getCanonicalFile();
  840           } else {
  841               canonicalAppBase = 
  842                   new File(System.getProperty("catalina.base"), appBase)
  843                   .getCanonicalFile();
  844           }
  845   
  846           String docBase = context.getDocBase();
  847           if (docBase == null) {
  848               // Trying to guess the docBase according to the path
  849               String path = context.getPath();
  850               if (path == null) {
  851                   return;
  852               }
  853               if (path.equals("")) {
  854                   docBase = "ROOT";
  855               } else {
  856                   if (path.startsWith("/")) {
  857                       docBase = path.substring(1).replace('/', '#');
  858                   } else {
  859                       docBase = path.replace('/', '#');
  860                   }
  861               }
  862           }
  863   
  864           File file = new File(docBase);
  865           if (!file.isAbsolute()) {
  866               docBase = (new File(canonicalAppBase, docBase)).getPath();
  867           } else {
  868               docBase = file.getCanonicalPath();
  869           }
  870           file = new File(docBase);
  871           String origDocBase = docBase;
  872           
  873           String pathName = context.getPath();
  874           if (pathName.equals("")) {
  875               pathName = "ROOT";
  876           } else {
  877               // Context path must start with '/'
  878               pathName = pathName.substring(1).replace('/', '#');
  879           }
  880           if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
  881               URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/");
  882               docBase = ExpandWar.expand(host, war, pathName);
  883               file = new File(docBase);
  884               docBase = file.getCanonicalPath();
  885               if (context instanceof StandardContext) {
  886                   ((StandardContext) context).setOriginalDocBase(origDocBase);
  887               }
  888           } else if (docBase.toLowerCase().endsWith(".war") &&
  889                   !file.isDirectory() && !unpackWARs) {
  890               URL war =
  891                   new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/");
  892               ExpandWar.validate(host, war, pathName);
  893           } else {
  894               File docDir = new File(docBase);
  895               if (!docDir.exists()) {
  896                   File warFile = new File(docBase + ".war");
  897                   if (warFile.exists()) {
  898                       URL war =
  899                           new URL("jar:" + warFile.toURI().toURL() + "!/");
  900                       if (unpackWARs) {
  901                           docBase = ExpandWar.expand(host, war, pathName);
  902                           file = new File(docBase);
  903                           docBase = file.getCanonicalPath();
  904                       } else {
  905                           docBase = warFile.getCanonicalPath();
  906                           ExpandWar.validate(host, war, pathName);
  907                       }
  908                   }
  909                   if (context instanceof StandardContext) {
  910                       ((StandardContext) context).setOriginalDocBase(origDocBase);
  911                   }
  912               }
  913           }
  914   
  915           if (docBase.startsWith(canonicalAppBase.getPath() + File.separatorChar)) {
  916               docBase = docBase.substring(canonicalAppBase.getPath().length());
  917               docBase = docBase.replace(File.separatorChar, '/');
  918               if (docBase.startsWith("/")) {
  919                   docBase = docBase.substring(1);
  920               }
  921           } else {
  922               docBase = docBase.replace(File.separatorChar, '/');
  923           }
  924   
  925           context.setDocBase(docBase);
  926   
  927       }
  928       
  929       
  930       protected void antiLocking()
  931           throws IOException {
  932   
  933           if ((context instanceof StandardContext) 
  934               && ((StandardContext) context).getAntiResourceLocking()) {
  935               
  936               Host host = (Host) context.getParent();
  937               String appBase = host.getAppBase();
  938               String docBase = context.getDocBase();
  939               if (docBase == null)
  940                   return;
  941               if (originalDocBase == null) {
  942                   originalDocBase = docBase;
  943               } else {
  944                   docBase = originalDocBase;
  945               }
  946               File docBaseFile = new File(docBase);
  947               if (!docBaseFile.isAbsolute()) {
  948                   File file = new File(appBase);
  949                   if (!file.isAbsolute()) {
  950                       file = new File(System.getProperty("catalina.base"), appBase);
  951                   }
  952                   docBaseFile = new File(file, docBase);
  953               }
  954               
  955               String path = context.getPath();
  956               if (path == null) {
  957                   return;
  958               }
  959               if (path.equals("")) {
  960                   docBase = "ROOT";
  961               } else {
  962                   if (path.startsWith("/")) {
  963                       docBase = path.substring(1);
  964                   } else {
  965                       docBase = path;
  966                   }
  967               }
  968   
  969               File file = null;
  970               if (docBase.toLowerCase().endsWith(".war")) {
  971                   file = new File(System.getProperty("java.io.tmpdir"),
  972                           deploymentCount++ + "-" + docBase + ".war");
  973               } else {
  974                   file = new File(System.getProperty("java.io.tmpdir"), 
  975                           deploymentCount++ + "-" + docBase);
  976               }
  977               
  978               if (log.isDebugEnabled())
  979                   log.debug("Anti locking context[" + context.getPath() 
  980                           + "] setting docBase to " + file);
  981               
  982               // Cleanup just in case an old deployment is lying around
  983               ExpandWar.delete(file);
  984               if (ExpandWar.copy(docBaseFile, file)) {
  985                   context.setDocBase(file.getAbsolutePath());
  986               }
  987               
  988           }
  989           
  990       }
  991       
  992   
  993       /**
  994        * Process a "init" event for this Context.
  995        */
  996       protected void init() {
  997           // Called from StandardContext.init()
  998   
  999           if (webDigester == null){
 1000               webDigester = createWebDigester();
 1001               webDigester.getParser();
 1002           }
 1003           
 1004           if (contextDigester == null){
 1005               contextDigester = createContextDigester();
 1006               contextDigester.getParser();
 1007           }
 1008   
 1009           if (log.isDebugEnabled())
 1010               log.debug(sm.getString("contextConfig.init"));
 1011           context.setConfigured(false);
 1012           ok = true;
 1013           
 1014           contextConfig();
 1015           
 1016           try {
 1017               fixDocBase();
 1018           } catch (IOException e) {
 1019               log.error(sm.getString(
 1020                       "contextConfig.fixDocBase", context.getPath()), e);
 1021           }
 1022           
 1023       }
 1024       
 1025       
 1026       /**
 1027        * Process a "before start" event for this Context.
 1028        */
 1029       protected synchronized void beforeStart() {
 1030           
 1031           try {
 1032               antiLocking();
 1033           } catch (IOException e) {
 1034               log.error(sm.getString("contextConfig.antiLocking"), e);
 1035           }
 1036           
 1037       }
 1038       
 1039       
 1040       /**
 1041        * Process a "start" event for this Context.
 1042        */
 1043       protected synchronized void start() {
 1044           // Called from StandardContext.start()
 1045   
 1046           if (log.isDebugEnabled())
 1047               log.debug(sm.getString("contextConfig.start"));
 1048   
 1049           // Set properties based on DefaultContext
 1050           Container container = context.getParent();
 1051           if( !context.getOverride() ) {
 1052               if( container instanceof Host ) {
 1053                   // Reset the value only if the attribute wasn't
 1054                   // set on the context.
 1055                   xmlValidation = context.getXmlValidation();
 1056                   if (!xmlValidation) {
 1057                       xmlValidation = ((Host)container).getXmlValidation();
 1058                   }
 1059                   
 1060                   xmlNamespaceAware = context.getXmlNamespaceAware();
 1061                   if (!xmlNamespaceAware){
 1062                       xmlNamespaceAware 
 1063                                   = ((Host)container).getXmlNamespaceAware();
 1064                   }
 1065   
 1066                   container = container.getParent();
 1067               }
 1068           }
 1069   
 1070           // Process the default and application web.xml files
 1071           defaultWebConfig();
 1072           applicationWebConfig();
 1073           if (!context.getIgnoreAnnotations()) {
 1074               applicationAnnotationsConfig();
 1075           }
 1076           if (ok) {
 1077               validateSecurityRoles();
 1078           }
 1079   
 1080           // Configure an authenticator if we need one
 1081           if (ok)
 1082               authenticatorConfig();
 1083   
 1084           // Dump the contents of this pipeline if requested
 1085           if ((log.isDebugEnabled()) && (context instanceof ContainerBase)) {
 1086               log.debug("Pipeline Configuration:");
 1087               Pipeline pipeline = ((ContainerBase) context).getPipeline();
 1088               Valve valves[] = null;
 1089               if (pipeline != null)
 1090                   valves = pipeline.getValves();
 1091               if (valves != null) {
 1092                   for (int i = 0; i < valves.length; i++) {
 1093                       log.debug("  " + valves[i].getInfo());
 1094                   }
 1095               }
 1096               log.debug("======================");
 1097           }
 1098   
 1099           // Make our application available if no problems were encountered
 1100           if (ok)
 1101               context.setConfigured(true);
 1102           else {
 1103               log.error(sm.getString("contextConfig.unavailable"));
 1104               context.setConfigured(false);
 1105           }
 1106   
 1107       }
 1108   
 1109   
 1110       /**
 1111        * Process a "stop" event for this Context.
 1112        */
 1113       protected synchronized void stop() {
 1114   
 1115           if (log.isDebugEnabled())
 1116               log.debug(sm.getString("contextConfig.stop"));
 1117   
 1118           int i;
 1119   
 1120           // Removing children
 1121           Container[] children = context.findChildren();
 1122           for (i = 0; i < children.length; i++) {
 1123               context.removeChild(children[i]);
 1124           }
 1125   
 1126           // Removing application parameters
 1127           /*
 1128           ApplicationParameter[] applicationParameters =
 1129               context.findApplicationParameters();
 1130           for (i = 0; i < applicationParameters.length; i++) {
 1131               context.removeApplicationParameter
 1132                   (applicationParameters[i].getName());
 1133           }
 1134           */
 1135   
 1136           // Removing security constraints
 1137           SecurityConstraint[] securityConstraints = context.findConstraints();
 1138           for (i = 0; i < securityConstraints.length; i++) {
 1139               context.removeConstraint(securityConstraints[i]);
 1140           }
 1141   
 1142           // Removing Ejbs
 1143           /*
 1144           ContextEjb[] contextEjbs = context.findEjbs();
 1145           for (i = 0; i < contextEjbs.length; i++) {
 1146               context.removeEjb(contextEjbs[i].getName());
 1147           }
 1148           */
 1149   
 1150           // Removing environments
 1151           /*
 1152           ContextEnvironment[] contextEnvironments = context.findEnvironments();
 1153           for (i = 0; i < contextEnvironments.length; i++) {
 1154               context.removeEnvironment(contextEnvironments[i].getName());
 1155           }
 1156           */
 1157   
 1158           // Removing errors pages
 1159           ErrorPage[] errorPages = context.findErrorPages();
 1160           for (i = 0; i < errorPages.length; i++) {
 1161               context.removeErrorPage(errorPages[i]);
 1162           }
 1163   
 1164           // Removing filter defs
 1165           FilterDef[] filterDefs = context.findFilterDefs();
 1166           for (i = 0; i < filterDefs.length; i++) {
 1167               context.removeFilterDef(filterDefs[i]);
 1168           }
 1169   
 1170           // Removing filter maps
 1171           FilterMap[] filterMaps = context.findFilterMaps();
 1172           for (i = 0; i < filterMaps.length; i++) {
 1173               context.removeFilterMap(filterMaps[i]);
 1174           }
 1175   
 1176           // Removing local ejbs
 1177           /*
 1178           ContextLocalEjb[] contextLocalEjbs = context.findLocalEjbs();
 1179           for (i = 0; i < contextLocalEjbs.length; i++) {
 1180               context.removeLocalEjb(contextLocalEjbs[i].getName());
 1181           }
 1182           */
 1183   
 1184           // Removing Mime mappings
 1185           String[] mimeMappings = context.findMimeMappings();
 1186           for (i = 0; i < mimeMappings.length; i++) {
 1187               context.removeMimeMapping(mimeMappings[i]);
 1188           }
 1189   
 1190           // Removing parameters
 1191           String[] parameters = context.findParameters();
 1192           for (i = 0; i < parameters.length; i++) {
 1193               context.removeParameter(parameters[i]);
 1194           }
 1195   
 1196           // Removing resource env refs
 1197           /*
 1198           String[] resourceEnvRefs = context.findResourceEnvRefs();
 1199           for (i = 0; i < resourceEnvRefs.length; i++) {
 1200               context.removeResourceEnvRef(resourceEnvRefs[i]);
 1201           }
 1202           */
 1203   
 1204           // Removing resource links
 1205           /*
 1206           ContextResourceLink[] contextResourceLinks =
 1207               context.findResourceLinks();
 1208           for (i = 0; i < contextResourceLinks.length; i++) {
 1209               context.removeResourceLink(contextResourceLinks[i].getName());
 1210           }
 1211           */
 1212   
 1213           // Removing resources
 1214           /*
 1215           ContextResource[] contextResources = context.findResources();
 1216           for (i = 0; i < contextResources.length; i++) {
 1217               context.removeResource(contextResources[i].getName());
 1218           }
 1219           */
 1220   
 1221           // Removing sercurity role
 1222           String[] securityRoles = context.findSecurityRoles();
 1223           for (i = 0; i < securityRoles.length; i++) {
 1224               context.removeSecurityRole(securityRoles[i]);
 1225           }
 1226   
 1227           // Removing servlet mappings
 1228           String[] servletMappings = context.findServletMappings();
 1229           for (i = 0; i < servletMappings.length; i++) {
 1230               context.removeServletMapping(servletMappings[i]);
 1231           }
 1232   
 1233           // FIXME : Removing status pages
 1234   
 1235           // Removing taglibs
 1236           String[] taglibs = context.findTaglibs();
 1237           for (i = 0; i < taglibs.length; i++) {
 1238               context.removeTaglib(taglibs[i]);
 1239           }
 1240   
 1241           // Removing welcome files
 1242           String[] welcomeFiles = context.findWelcomeFiles();
 1243           for (i = 0; i < welcomeFiles.length; i++) {
 1244               context.removeWelcomeFile(welcomeFiles[i]);
 1245           }
 1246   
 1247           // Removing wrapper lifecycles
 1248           String[] wrapperLifecycles = context.findWrapperLifecycles();
 1249           for (i = 0; i < wrapperLifecycles.length; i++) {
 1250               context.removeWrapperLifecycle(wrapperLifecycles[i]);
 1251           }
 1252   
 1253           // Removing wrapper listeners
 1254           String[] wrapperListeners = context.findWrapperListeners();
 1255           for (i = 0; i < wrapperListeners.length; i++) {
 1256               context.removeWrapperListener(wrapperListeners[i]);
 1257           }
 1258   
 1259           // Remove (partially) folders and files created by antiLocking
 1260           Host host = (Host) context.getParent();
 1261           String appBase = host.getAppBase();
 1262           String docBase = context.getDocBase();
 1263           if ((docBase != null) && (originalDocBase != null)) {
 1264               File docBaseFile = new File(docBase);
 1265               if (!docBaseFile.isAbsolute()) {
 1266                   docBaseFile = new File(appBase, docBase);
 1267               }
 1268               // No need to log failure - it is expected in this case
 1269               ExpandWar.delete(docBaseFile, false);
 1270           }
 1271           
 1272           ok = true;
 1273   
 1274       }
 1275       
 1276       
 1277       /**
 1278        * Process a "destroy" event for this Context.
 1279        */
 1280       protected synchronized void destroy() {
 1281           // Called from StandardContext.destroy()
 1282           if (log.isDebugEnabled())
 1283               log.debug(sm.getString("contextConfig.destroy"));
 1284   
 1285           // Changed to getWorkPath per Bugzilla 35819.
 1286           String workDir = ((StandardContext) context).getWorkPath();
 1287           if (workDir != null)
 1288               ExpandWar.delete(new File(workDir));
 1289       }
 1290       
 1291       
 1292       /**
 1293        * Validate the usage of security role names in the web application
 1294        * deployment descriptor.  If any problems are found, issue warning
 1295        * messages (for backwards compatibility) and add the missing roles.
 1296        * (To make these problems fatal instead, simply set the <code>ok</code>
 1297        * instance variable to <code>false</code> as well).
 1298        */
 1299       protected void validateSecurityRoles() {
 1300   
 1301           // Check role names used in <security-constraint> elements
 1302           SecurityConstraint constraints[] = context.findConstraints();
 1303           for (int i = 0; i < constraints.length; i++) {
 1304               String roles[] = constraints[i].findAuthRoles();
 1305               for (int j = 0; j < roles.length; j++) {
 1306                   if (!"*".equals(roles[j]) &&
 1307                       !context.findSecurityRole(roles[j])) {
 1308                       log.info(sm.getString("contextConfig.role.auth", roles[j]));
 1309                       context.addSecurityRole(roles[j]);
 1310                   }
 1311               }
 1312           }
 1313   
 1314           // Check role names used in <servlet> elements
 1315           Container wrappers[] = context.findChildren();
 1316           for (int i = 0; i < wrappers.length; i++) {
 1317               Wrapper wrapper = (Wrapper) wrappers[i];
 1318               String runAs = wrapper.getRunAs();
 1319               if ((runAs != null) && !context.findSecurityRole(runAs)) {
 1320                   log.info(sm.getString("contextConfig.role.runas", runAs));
 1321                   context.addSecurityRole(runAs);
 1322               }
 1323               String names[] = wrapper.findSecurityReferences();
 1324               for (int j = 0; j < names.length; j++) {
 1325                   String link = wrapper.findSecurityReference(names[j]);
 1326                   if ((link != null) && !context.findSecurityRole(link)) {
 1327                       log.info(sm.getString("contextConfig.role.link", link));
 1328                       context.addSecurityRole(link);
 1329                   }
 1330               }
 1331           }
 1332   
 1333       }
 1334   
 1335   
 1336       /**
 1337        * Get config base.
 1338        */
 1339       protected File getConfigBase() {
 1340           File configBase = 
 1341               new File(System.getProperty("catalina.base"), "conf");
 1342           if (!configBase.exists()) {
 1343               return null;
 1344           } else {
 1345               return configBase;
 1346           }
 1347       }  
 1348   
 1349       
 1350       protected String getHostConfigPath(String resourceName) {
 1351           StringBuffer result = new StringBuffer();
 1352           Container container = context;
 1353           Container host = null;
 1354           Container engine = null;
 1355           while (container != null) {
 1356               if (container instanceof Host)
 1357                   host = container;
 1358               if (container instanceof Engine)
 1359                   engine = container;
 1360               container = container.getParent();
 1361           }
 1362           if (engine != null) {
 1363               result.append(engine.getName()).append('/');
 1364           }
 1365           if (host != null) {
 1366               result.append(host.getName()).append('/');
 1367           }
 1368           result.append(resourceName);
 1369           return result.toString();
 1370       }
 1371   
 1372   
 1373       protected class ContextErrorHandler
 1374           implements ErrorHandler {
 1375   
 1376           public void error(SAXParseException exception) {
 1377               parseException = exception;
 1378           }
 1379   
 1380           public void fatalError(SAXParseException exception) {
 1381               parseException = exception;
 1382           }
 1383   
 1384           public void warning(SAXParseException exception) {
 1385               parseException = exception;
 1386           }
 1387   
 1388       }
 1389   
 1390   
 1391   }

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