KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > startup > ContextConfig


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 JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileNotFoundException JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Properties JavaDoc;
30
31 import javax.servlet.ServletContext JavaDoc;
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 JavaDoc;
58 import org.xml.sax.InputSource JavaDoc;
59 import org.xml.sax.SAXParseException JavaDoc;
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: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
68  */

69
70 public class ContextConfig
71     implements LifecycleListener {
72
73     protected static org.apache.commons.logging.Log log=
74         org.apache.commons.logging.LogFactory.getLog( ContextConfig.class );
75
76     // ----------------------------------------------------- Instance Variables
77

78
79     /**
80      * Custom mappings of login methods to authenticators
81      */

82     protected Map JavaDoc 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 JavaDoc authenticators = null;
91
92
93     /**
94      * The Context we are associated with.
95      */

96     protected Context JavaDoc context = null;
97
98
99     /**
100      * The default web application's context file location.
101      */

102     protected String JavaDoc defaultContextXml = null;
103     
104     
105     /**
106      * The default web application's deployment descriptor location.
107      */

108     protected String JavaDoc 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 JavaDoc parseException = null;
121
122     
123     /**
124      * Original docBase.
125      */

126     protected String JavaDoc 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 JavaDoc 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 JavaDoc path) {
199
200         this.defaultWebXml = path;
201
202     }
203
204
205     /**
206      * Return the location of the default context file
207      */

208     public String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc) event.getLifecycle();
254         } catch (ClassCastException JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc altDDName = null;
313
314         // Open the application web.xml file, if it exists
315
InputStream JavaDoc stream = null;
316         ServletContext JavaDoc servletContext = context.getServletContext();
317         if (servletContext != null) {
318             altDDName = (String JavaDoc)servletContext.getAttribute(
319                                                         Globals.ALT_DD_ATTR);
320             if (altDDName != null) {
321                 try {
322                     stream = new FileInputStream JavaDoc(altDDName);
323                 } catch (FileNotFoundException JavaDoc 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 JavaDoc url=null;
347         // Process the application web.xml file
348
synchronized (webDigester) {
349             try {
350                 if (altDDName != null) {
351                     url = new File JavaDoc(altDDName).toURL();
352                 } else {
353                     url = servletContext.getResource(
354                                                 Constants.ApplicationWebXml);
355                 }
356                 if( url!=null ) {
357                     InputSource JavaDoc is = new InputSource JavaDoc(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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc is=this.getClass().getClassLoader().getResourceAsStream("org/apache/catalina/startup/Authenticators.properties");
464                     if( is!=null ) {
465                         authenticators = new Properties JavaDoc();
466                         authenticators.load(is);
467                     } else {
468                         log.error(sm.getString(
469                                 "contextConfig.authenticatorResources"));
470                         ok=false;
471                         return;
472                     }
473                 } catch (IOException JavaDoc 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 JavaDoc 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 JavaDoc authenticatorClass = Class.forName(authenticatorName);
495                 authenticator = (Valve) authenticatorClass.newInstance();
496             } catch (Throwable JavaDoc 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 JavaDoc 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 JavaDoc file = new File JavaDoc(this.defaultWebXml);
584         if (!file.isAbsolute()) {
585             file = new File JavaDoc(getBaseDir(),
586                             this.defaultWebXml);
587         }
588
589         InputStream JavaDoc stream = null;
590         InputSource JavaDoc 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 JavaDoc
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 JavaDoc
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 JavaDoc("file://" + file.getAbsolutePath());
619                 stream = new FileInputStream JavaDoc(file);
620                 context.addWatchedResource(file.getAbsolutePath());
621             }
622         } catch (Exception JavaDoc 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 JavaDoc resourceName = getHostConfigPath(Constants.HostWebXml);
644         file = new File JavaDoc(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 JavaDoc
653                             (getClass().getClassLoader()
654                             .getResource(resourceName).toString());
655                 }
656             } else {
657                 source =
658                     new InputSource JavaDoc("file://" + file.getAbsolutePath());
659                 stream = new FileInputStream JavaDoc(file);
660             }
661         } catch (Exception JavaDoc 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 JavaDoc stream,
678             InputSource JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc(getBaseDir()), defaultContextXml);
737             processContextConfig(getConfigBase(), getHostConfigPath(Constants.HostContextXml));
738         }
739         if (context.getConfigFile() != null)
740             processContextConfig(new File JavaDoc(context.getConfigFile()), null);
741         
742     }
743
744     
745     /**
746      * Process a context.xml.
747      */

748     protected void processContextConfig(File JavaDoc baseDir, String JavaDoc resourceName) {
749         
750         if (log.isDebugEnabled())
751             log.debug("Processing context [" + context.getName()
752                     + "] configuration file " + baseDir + " " + resourceName);
753
754         InputSource JavaDoc source = null;
755         InputStream JavaDoc stream = null;
756
757         File JavaDoc file = baseDir;
758         if (resourceName != null) {
759             file = new File JavaDoc(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 JavaDoc
770                             (getClass().getClassLoader()
771                             .getResource(resourceName).toString());
772                     }
773                 }
774             } else {
775                 source =
776                     new InputSource JavaDoc("file://" + file.getAbsolutePath());
777                 stream = new FileInputStream JavaDoc(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 JavaDoc e) {
783             log.error(sm.getString("contextConfig.defaultMissing")
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 JavaDoc e) {
808                 log.error(sm.getString("contextConfig.defaultParse"), e);
809                 log.error(sm.getString("contextConfig.defaultPosition",
810                                  "" + e.getLineNumber(),
811                                  "" + e.getColumnNumber()));
812                 ok = false;
813             } catch (Exception JavaDoc e) {
814                 log.error(sm.getString("contextConfig.defaultParse"), e);
815                 ok = false;
816             } finally {
817                 contextDigester.reset();
818                 parseException = null;
819                 try {
820                     if (stream != null) {
821                         stream.close();
822                     }
823                 } catch (IOException JavaDoc e) {
824                     log.error(sm.getString("contextConfig.defaultClose"), e);
825                 }
826             }
827         }
828     }
829
830     
831     /**
832      * Adjust docBase.
833      */

834     protected void fixDocBase()
835         throws IOException JavaDoc {
836         
837         Host host = (Host) context.getParent();
838         String JavaDoc appBase = host.getAppBase();
839
840         boolean unpackWARs = true;
841         if (host instanceof StandardHost) {
842             unpackWARs = ((StandardHost) host).isUnpackWARs()
843                 && ((StandardContext) context).getUnpackWAR();
844         }
845
846         File JavaDoc canonicalAppBase = new File JavaDoc(appBase);
847         if (canonicalAppBase.isAbsolute()) {
848             canonicalAppBase = canonicalAppBase.getCanonicalFile();
849         } else {
850             canonicalAppBase =
851                 new File JavaDoc(System.getProperty("catalina.base"), appBase)
852                 .getCanonicalFile();
853         }
854
855         String JavaDoc docBase = context.getDocBase();
856         if (docBase == null) {
857             // Trying to guess the docBase according to the path
858
String JavaDoc path = context.getPath();
859             if (path == null) {
860                 return;
861             }
862             if (path.equals("")) {
863                 docBase = "ROOT";
864             } else {
865                 if (path.startsWith("/")) {
866                     docBase = path.substring(1);
867                 } else {
868                     docBase = path;
869                 }
870             }
871         }
872
873         File JavaDoc file = new File JavaDoc(docBase);
874         if (!file.isAbsolute()) {
875             docBase = (new File JavaDoc(canonicalAppBase, docBase)).getPath();
876         } else {
877             docBase = file.getCanonicalPath();
878         }
879         file = new File JavaDoc(docBase);
880         String JavaDoc origDocBase = docBase;
881         
882         if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
883             URL JavaDoc war = new URL JavaDoc("jar:" + (new File JavaDoc(docBase)).toURL() + "!/");
884             String JavaDoc contextPath = context.getPath();
885             if (contextPath.equals("")) {
886                 contextPath = "ROOT";
887             }
888             docBase = ExpandWar.expand(host, war, contextPath);
889             file = new File JavaDoc(docBase);
890             docBase = file.getCanonicalPath();
891             if (context instanceof StandardContext) {
892                 ((StandardContext) context).setOriginalDocBase(origDocBase);
893             }
894         } else {
895             File JavaDoc docDir = new File JavaDoc(docBase);
896             if (!docDir.exists()) {
897                 File JavaDoc warFile = new File JavaDoc(docBase + ".war");
898                 if (warFile.exists()) {
899                     if (unpackWARs) {
900                         URL JavaDoc war = new URL JavaDoc("jar:" + warFile.toURL() + "!/");
901                         docBase = ExpandWar.expand(host, war, context.getPath());
902                         file = new File JavaDoc(docBase);
903                         docBase = file.getCanonicalPath();
904                     } else {
905                         docBase = warFile.getCanonicalPath();
906                     }
907                 }
908                 if (context instanceof StandardContext) {
909                     ((StandardContext) context).setOriginalDocBase(origDocBase);
910                 }
911             }
912         }
913
914         if (docBase.startsWith(canonicalAppBase.getPath())) {
915             docBase = docBase.substring(canonicalAppBase.getPath().length());
916             docBase = docBase.replace(File.separatorChar, '/');
917             if (docBase.startsWith("/")) {
918                 docBase = docBase.substring(1);
919             }
920         } else {
921             docBase = docBase.replace(File.separatorChar, '/');
922         }
923
924         context.setDocBase(docBase);
925
926     }
927     
928     
929     protected void antiLocking()
930         throws IOException JavaDoc {
931
932         if ((context instanceof StandardContext)
933             && ((StandardContext) context).getAntiResourceLocking()) {
934             
935             Host host = (Host) context.getParent();
936             String JavaDoc appBase = host.getAppBase();
937             String JavaDoc docBase = context.getDocBase();
938             if (docBase == null)
939                 return;
940             if (originalDocBase == null) {
941                 originalDocBase = docBase;
942             } else {
943                 docBase = originalDocBase;
944             }
945             File JavaDoc docBaseFile = new File JavaDoc(docBase);
946             if (!docBaseFile.isAbsolute()) {
947                 File JavaDoc file = new File JavaDoc(appBase);
948                 if (!file.isAbsolute()) {
949                     file = new File JavaDoc(System.getProperty("catalina.base"), appBase);
950                 }
951                 docBaseFile = new File JavaDoc(file, docBase);
952             }
953             
954             String JavaDoc path = context.getPath();
955             if (path == null) {
956                 return;
957             }
958             if (path.equals("")) {
959                 docBase = "ROOT";
960             } else {
961                 if (path.startsWith("/")) {
962                     docBase = path.substring(1);
963                 } else {
964                     docBase = path;
965                 }
966             }
967
968             File JavaDoc file = null;
969             if (docBase.toLowerCase().endsWith(".war")) {
970                 file = new File JavaDoc(System.getProperty("java.io.tmpdir"),
971                         deploymentCount++ + "-" + docBase + ".war");
972             } else {
973                 file = new File JavaDoc(System.getProperty("java.io.tmpdir"),
974                         deploymentCount++ + "-" + docBase);
975             }
976             
977             if (log.isDebugEnabled())
978                 log.debug("Anti locking context[" + context.getPath()
979                         + "] setting docBase to " + file);
980             
981             // Cleanup just in case an old deployment is lying around
982
ExpandWar.delete(file);
983             if (ExpandWar.copy(docBaseFile, file)) {
984                 context.setDocBase(file.getAbsolutePath());
985             }
986             
987         }
988         
989     }
990     
991
992     /**
993      * Process a "init" event for this Context.
994      */

995     protected void init() {
996         // Called from StandardContext.init()
997

998         if (log.isDebugEnabled())
999             log.debug(sm.getString("contextConfig.init"));
1000        context.setConfigured(false);
1001        ok = true;
1002        
1003        contextConfig();
1004        
1005        try {
1006            fixDocBase();
1007        } catch (IOException JavaDoc e) {
1008            log.error(sm.getString("contextConfig.fixDocBase"), e);
1009        }
1010        
1011    }
1012    
1013    
1014    /**
1015     * Process a "before start" event for this Context.
1016     */

1017    protected synchronized void beforeStart() {
1018        
1019        try {
1020            antiLocking();
1021        } catch (IOException JavaDoc e) {
1022            log.error(sm.getString("contextConfig.antiLocking"), e);
1023        }
1024        
1025    }
1026    
1027    
1028    /**
1029     * Process a "start" event for this Context.
1030     */

1031    protected synchronized void start() {
1032        // Called from StandardContext.start()
1033

1034        if (log.isDebugEnabled())
1035            log.debug(sm.getString("contextConfig.start"));
1036
1037        // Set properties based on DefaultContext
1038
Container container = context.getParent();
1039        if( !context.getOverride() ) {
1040            if( container instanceof Host ) {
1041                // Reset the value only if the attribute wasn't
1042
// set on the context.
1043
xmlValidation = context.getXmlValidation();
1044                if (!xmlValidation) {
1045                    xmlValidation = ((Host)container).getXmlValidation();
1046                }
1047                
1048                xmlNamespaceAware = context.getXmlNamespaceAware();
1049                if (!xmlNamespaceAware){
1050                    xmlNamespaceAware
1051                                = ((Host)container).getXmlNamespaceAware();
1052                }
1053
1054                container = container.getParent();
1055            }
1056        }
1057
1058        // Process the default and application web.xml files
1059
defaultWebConfig();
1060        applicationWebConfig();
1061        if (!context.getIgnoreAnnotations()) {
1062            applicationAnnotationsConfig();
1063        }
1064        if (ok) {
1065            validateSecurityRoles();
1066        }
1067
1068        // Configure an authenticator if we need one
1069
if (ok)
1070            authenticatorConfig();
1071
1072        // Dump the contents of this pipeline if requested
1073
if ((log.isDebugEnabled()) && (context instanceof ContainerBase)) {
1074            log.debug("Pipeline Configuration:");
1075            Pipeline pipeline = ((ContainerBase) context).getPipeline();
1076            Valve valves[] = null;
1077            if (pipeline != null)
1078                valves = pipeline.getValves();
1079            if (valves != null) {
1080                for (int i = 0; i < valves.length; i++) {
1081                    log.debug(" " + valves[i].getInfo());
1082                }
1083            }
1084            log.debug("======================");
1085        }
1086
1087        // Make our application available if no problems were encountered
1088
if (ok)
1089            context.setConfigured(true);
1090        else {
1091            log.error(sm.getString("contextConfig.unavailable"));
1092            context.setConfigured(false);
1093        }
1094
1095    }
1096
1097
1098    /**
1099     * Process a "stop" event for this Context.
1100     */

1101    protected synchronized void stop() {
1102
1103        if (log.isDebugEnabled())
1104            log.debug(sm.getString("contextConfig.stop"));
1105
1106        int i;
1107
1108        // Removing children
1109
Container[] children = context.findChildren();
1110        for (i = 0; i < children.length; i++) {
1111            context.removeChild(children[i]);
1112        }
1113
1114        // Removing application parameters
1115
/*
1116        ApplicationParameter[] applicationParameters =
1117            context.findApplicationParameters();
1118        for (i = 0; i < applicationParameters.length; i++) {
1119            context.removeApplicationParameter
1120                (applicationParameters[i].getName());
1121        }
1122        */

1123
1124        // Removing security constraints
1125
SecurityConstraint[] securityConstraints = context.findConstraints();
1126        for (i = 0; i < securityConstraints.length; i++) {
1127            context.removeConstraint(securityConstraints[i]);
1128        }
1129
1130        // Removing Ejbs
1131
/*
1132        ContextEjb[] contextEjbs = context.findEjbs();
1133        for (i = 0; i < contextEjbs.length; i++) {
1134            context.removeEjb(contextEjbs[i].getName());
1135        }
1136        */

1137
1138        // Removing environments
1139
/*
1140        ContextEnvironment[] contextEnvironments = context.findEnvironments();
1141        for (i = 0; i < contextEnvironments.length; i++) {
1142            context.removeEnvironment(contextEnvironments[i].getName());
1143        }
1144        */

1145
1146        // Removing errors pages
1147
ErrorPage[] errorPages = context.findErrorPages();
1148        for (i = 0; i < errorPages.length; i++) {
1149            context.removeErrorPage(errorPages[i]);
1150        }
1151
1152        // Removing filter defs
1153
FilterDef[] filterDefs = context.findFilterDefs();
1154        for (i = 0; i < filterDefs.length; i++) {
1155            context.removeFilterDef(filterDefs[i]);
1156        }
1157
1158        // Removing filter maps
1159
FilterMap[] filterMaps = context.findFilterMaps();
1160        for (i = 0; i < filterMaps.length; i++) {
1161            context.removeFilterMap(filterMaps[i]);
1162        }
1163
1164        // Removing local ejbs
1165
/*
1166        ContextLocalEjb[] contextLocalEjbs = context.findLocalEjbs();
1167        for (i = 0; i < contextLocalEjbs.length; i++) {
1168            context.removeLocalEjb(contextLocalEjbs[i].getName());
1169        }
1170        */

1171
1172        // Removing Mime mappings
1173
String JavaDoc[] mimeMappings = context.findMimeMappings();
1174        for (i = 0; i < mimeMappings.length; i++) {
1175            context.removeMimeMapping(mimeMappings[i]);
1176        }
1177
1178        // Removing parameters
1179
String JavaDoc[] parameters = context.findParameters();
1180        for (i = 0; i < parameters.length; i++) {
1181            context.removeParameter(parameters[i]);
1182        }
1183
1184        // Removing resource env refs
1185
/*
1186        String[] resourceEnvRefs = context.findResourceEnvRefs();
1187        for (i = 0; i < resourceEnvRefs.length; i++) {
1188            context.removeResourceEnvRef(resourceEnvRefs[i]);
1189        }
1190        */

1191
1192        // Removing resource links
1193
/*
1194        ContextResourceLink[] contextResourceLinks =
1195            context.findResourceLinks();
1196        for (i = 0; i < contextResourceLinks.length; i++) {
1197            context.removeResourceLink(contextResourceLinks[i].getName());
1198        }
1199        */

1200
1201        // Removing resources
1202
/*
1203        ContextResource[] contextResources = context.findResources();
1204        for (i = 0; i < contextResources.length; i++) {
1205            context.removeResource(contextResources[i].getName());
1206        }
1207        */

1208
1209        // Removing sercurity role
1210
String JavaDoc[] securityRoles = context.findSecurityRoles();
1211        for (i = 0; i < securityRoles.length; i++) {
1212            context.removeSecurityRole(securityRoles[i]);
1213        }
1214
1215        // Removing servlet mappings
1216
String JavaDoc[] servletMappings = context.findServletMappings();
1217        for (i = 0; i < servletMappings.length; i++) {
1218            context.removeServletMapping(servletMappings[i]);
1219        }
1220
1221        // FIXME : Removing status pages
1222

1223        // Removing taglibs
1224
String JavaDoc[] taglibs = context.findTaglibs();
1225        for (i = 0; i < taglibs.length; i++) {
1226            context.removeTaglib(taglibs[i]);
1227        }
1228
1229        // Removing welcome files
1230
String JavaDoc[] welcomeFiles = context.findWelcomeFiles();
1231        for (i = 0; i < welcomeFiles.length; i++) {
1232            context.removeWelcomeFile(welcomeFiles[i]);
1233        }
1234
1235        // Removing wrapper lifecycles
1236
String JavaDoc[] wrapperLifecycles = context.findWrapperLifecycles();
1237        for (i = 0; i < wrapperLifecycles.length; i++) {
1238            context.removeWrapperLifecycle(wrapperLifecycles[i]);
1239        }
1240
1241        // Removing wrapper listeners
1242
String JavaDoc[] wrapperListeners = context.findWrapperListeners();
1243        for (i = 0; i < wrapperListeners.length; i++) {
1244            context.removeWrapperListener(wrapperListeners[i]);
1245        }
1246
1247        // Remove (partially) folders and files created by antiLocking
1248
Host host = (Host) context.getParent();
1249        String JavaDoc appBase = host.getAppBase();
1250        String JavaDoc docBase = context.getDocBase();
1251        if ((docBase != null) && (originalDocBase != null)) {
1252            File JavaDoc docBaseFile = new File JavaDoc(docBase);
1253            if (!docBaseFile.isAbsolute()) {
1254                docBaseFile = new File JavaDoc(appBase, docBase);
1255            }
1256            ExpandWar.delete(docBaseFile);
1257        }
1258        
1259        ok = true;
1260
1261    }
1262    
1263    
1264    /**
1265     * Process a "destroy" event for this Context.
1266     */

1267    protected synchronized void destroy() {
1268        // Called from StandardContext.destroy()
1269
if (log.isDebugEnabled())
1270            log.debug(sm.getString("contextConfig.destroy"));
1271
1272        // Changed to getWorkPath per Bugzilla 35819.
1273
String JavaDoc workDir = ((StandardContext) context).getWorkPath();
1274        if (workDir != null)
1275            ExpandWar.delete(new File JavaDoc(workDir));
1276    }
1277    
1278    
1279    /**
1280     * Validate the usage of security role names in the web application
1281     * deployment descriptor. If any problems are found, issue warning
1282     * messages (for backwards compatibility) and add the missing roles.
1283     * (To make these problems fatal instead, simply set the <code>ok</code>
1284     * instance variable to <code>false</code> as well).
1285     */

1286    protected void validateSecurityRoles() {
1287
1288        // Check role names used in <security-constraint> elements
1289
SecurityConstraint constraints[] = context.findConstraints();
1290        for (int i = 0; i < constraints.length; i++) {
1291            String JavaDoc roles[] = constraints[i].findAuthRoles();
1292            for (int j = 0; j < roles.length; j++) {
1293                if (!"*".equals(roles[j]) &&
1294                    !context.findSecurityRole(roles[j])) {
1295                    log.info(sm.getString("contextConfig.role.auth", roles[j]));
1296                    context.addSecurityRole(roles[j]);
1297                }
1298            }
1299        }
1300
1301        // Check role names used in <servlet> elements
1302
Container wrappers[] = context.findChildren();
1303        for (int i = 0; i < wrappers.length; i++) {
1304            Wrapper wrapper = (Wrapper) wrappers[i];
1305            String JavaDoc runAs = wrapper.getRunAs();
1306            if ((runAs != null) && !context.findSecurityRole(runAs)) {
1307                log.info(sm.getString("contextConfig.role.runas", runAs));
1308                context.addSecurityRole(runAs);
1309            }
1310            String JavaDoc names[] = wrapper.findSecurityReferences();
1311            for (int j = 0; j < names.length; j++) {
1312                String JavaDoc link = wrapper.findSecurityReference(names[j]);
1313                if ((link != null) && !context.findSecurityRole(link)) {
1314                    log.info(sm.getString("contextConfig.role.link", link));
1315                    context.addSecurityRole(link);
1316                }
1317            }
1318        }
1319
1320    }
1321
1322
1323    /**
1324     * Get config base.
1325     */

1326    protected File JavaDoc getConfigBase() {
1327        File JavaDoc configBase =
1328            new File JavaDoc(System.getProperty("catalina.base"), "conf");
1329        if (!configBase.exists()) {
1330            return null;
1331        } else {
1332            return configBase;
1333        }
1334    }
1335
1336    
1337    protected String JavaDoc getHostConfigPath(String JavaDoc resourceName) {
1338        StringBuffer JavaDoc result = new StringBuffer JavaDoc();
1339        Container container = context;
1340        Container host = null;
1341        Container engine = null;
1342        while (container != null) {
1343            if (container instanceof Host)
1344                host = container;
1345            if (container instanceof Engine)
1346                engine = container;
1347            container = container.getParent();
1348        }
1349        if (engine != null) {
1350            result.append(engine.getName()).append('/');
1351        }
1352        if (host != null) {
1353            result.append(host.getName()).append('/');
1354        }
1355        result.append(resourceName);
1356        return result.toString();
1357    }
1358
1359
1360    protected class ContextErrorHandler
1361        implements ErrorHandler JavaDoc {
1362
1363        public void error(SAXParseException JavaDoc exception) {
1364            parseException = exception;
1365        }
1366
1367        public void fatalError(SAXParseException JavaDoc exception) {
1368            parseException = exception;
1369        }
1370
1371        public void warning(SAXParseException JavaDoc exception) {
1372            parseException = exception;
1373        }
1374
1375    }
1376
1377
1378}
1379
Popular Tags