001: /*
002: * Copyright 1999-2001,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.startup;
018:
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.net.URL;
024: import java.util.Properties;
025:
026: import javax.servlet.ServletContext;
027:
028: import org.apache.catalina.Authenticator;
029: import org.apache.catalina.Container;
030: import org.apache.catalina.Context;
031: import org.apache.catalina.Engine;
032: import org.apache.catalina.Host;
033: import org.apache.catalina.Lifecycle;
034: import org.apache.catalina.LifecycleEvent;
035: import org.apache.catalina.LifecycleListener;
036: import org.apache.catalina.Logger;
037: import org.apache.catalina.Pipeline;
038: import org.apache.catalina.Valve;
039: import org.apache.catalina.Wrapper;
040: import org.apache.catalina.core.ContainerBase;
041: import org.apache.catalina.core.StandardContext;
042: import org.apache.catalina.core.StandardEngine;
043: import org.apache.catalina.deploy.ErrorPage;
044: import org.apache.catalina.deploy.FilterDef;
045: import org.apache.catalina.deploy.FilterMap;
046: import org.apache.catalina.deploy.LoginConfig;
047: import org.apache.catalina.deploy.SecurityConstraint;
048: import org.apache.catalina.session.StandardManager;
049: import org.apache.catalina.util.StringManager;
050: import org.apache.commons.digester.Digester;
051: import org.xml.sax.ErrorHandler;
052: import org.xml.sax.InputSource;
053: import org.xml.sax.SAXParseException;
054:
055: /**
056: * Startup event listener for a <b>Context</b> that configures the properties
057: * of that Context, and the associated defined servlets.
058: *
059: * @author Craig R. McClanahan
060: * @author Jean-Francois Arcand
061: * @version $Revision: 1.44 $ $Date: 2004/04/09 21:47:04 $
062: */
063:
064: public final class ContextConfig implements LifecycleListener {
065:
066: private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
067: .getLog(ContextConfig.class);
068:
069: // ----------------------------------------------------- Instance Variables
070:
071: /**
072: * The set of Authenticators that we know how to configure. The key is
073: * the name of the implemented authentication method, and the value is
074: * the fully qualified Java class name of the corresponding Valve.
075: */
076: private static Properties authenticators = null;
077:
078: /**
079: * The Context we are associated with.
080: */
081: private Context context = null;
082:
083: /**
084: * The debugging detail level for this component.
085: */
086: private int debug = 0;
087:
088: /**
089: * The default web application's deployment descriptor location.
090: */
091: private String defaultWebXml = null;
092:
093: /**
094: * Track any fatal errors during startup configuration processing.
095: */
096: private boolean ok = false;
097:
098: /**
099: * Any parse error which occurred while parsing XML descriptors.
100: */
101: private SAXParseException parseException = null;
102:
103: /**
104: * The string resources for this package.
105: */
106: private static final StringManager sm = StringManager
107: .getManager(Constants.Package);
108:
109: /**
110: * The <code>Digester</code> we will use to process web application
111: * deployment descriptor files.
112: */
113: private static Digester webDigester = null;
114:
115: /**
116: * The <code>Rule</code> used to parse the web.xml
117: */
118: private static WebRuleSet webRuleSet = new WebRuleSet();
119:
120: /**
121: * Attribute value used to turn on/off XML validation
122: */
123: private static boolean xmlValidation = false;
124:
125: /**
126: * Attribute value used to turn on/off XML namespace awarenes.
127: */
128: private static boolean xmlNamespaceAware = false;
129:
130: // ------------------------------------------------------------- Properties
131:
132: /**
133: * Return the debugging detail level for this component.
134: */
135: public int getDebug() {
136:
137: return (this .debug);
138:
139: }
140:
141: /**
142: * Set the debugging detail level for this component.
143: *
144: * @param debug The new debugging detail level
145: */
146: public void setDebug(int debug) {
147:
148: this .debug = debug;
149:
150: }
151:
152: /**
153: * Return the location of the default deployment descriptor
154: */
155: public String getDefaultWebXml() {
156: if (defaultWebXml == null)
157: defaultWebXml = Constants.DefaultWebXml;
158: return (this .defaultWebXml);
159:
160: }
161:
162: /**
163: * Set the location of the default deployment descriptor
164: *
165: * @param path Absolute/relative path to the default web.xml
166: */
167: public void setDefaultWebXml(String path) {
168:
169: this .defaultWebXml = path;
170:
171: }
172:
173: // --------------------------------------------------------- Public Methods
174:
175: /**
176: * Process the START event for an associated Context.
177: *
178: * @param event The lifecycle event that has occurred
179: */
180: public void lifecycleEvent(LifecycleEvent event) {
181:
182: // Identify the context we are associated with
183: try {
184: context = (Context) event.getLifecycle();
185: // if (context instanceof StandardContext) {
186: // int contextDebug = ((StandardContext) context).getDebug();
187: // if (contextDebug > this.debug)
188: // this.debug = contextDebug;
189: // }
190: } catch (ClassCastException e) {
191: log.error(sm.getString("contextConfig.cce", event
192: .getLifecycle()), e);
193: return;
194: }
195:
196: // Called from ContainerBase.addChild() -> StandardContext.start()
197: // Process the event that has occurred
198: if (event.getType().equals(Lifecycle.START_EVENT))
199: start();
200: else if (event.getType().equals(Lifecycle.STOP_EVENT))
201: stop();
202:
203: }
204:
205: // -------------------------------------------------------- Private Methods
206:
207: /**
208: * Process the application configuration file, if it exists.
209: */
210: private void applicationConfig() {
211:
212: // Open the application web.xml file, if it exists
213: InputStream stream = null;
214: ServletContext servletContext = context.getServletContext();
215: if (servletContext != null)
216: stream = servletContext
217: .getResourceAsStream(Constants.ApplicationWebXml);
218: if (stream == null) {
219: log.info(sm.getString("contextConfig.applicationMissing")
220: + " " + context);
221: return;
222: }
223:
224: long t1 = System.currentTimeMillis();
225:
226: if (webDigester == null) {
227: webDigester = createWebDigester();
228: }
229:
230: URL url = null;
231: // Process the application web.xml file
232: synchronized (webDigester) {
233: try {
234: url = servletContext
235: .getResource(Constants.ApplicationWebXml);
236: if (url != null) {
237: InputSource is = new InputSource(url
238: .toExternalForm());
239: is.setByteStream(stream);
240: webDigester.clear();
241: if (context instanceof StandardContext) {
242: ((StandardContext) context)
243: .setReplaceWelcomeFiles(true);
244: }
245: webDigester.push(context);
246: webDigester
247: .setErrorHandler(new ContextErrorHandler());
248: webDigester.parse(is);
249: if (parseException != null) {
250: ok = false;
251: }
252: } else {
253: log.info("No web.xml, using defaults " + context);
254: }
255: } catch (SAXParseException e) {
256: log
257: .error(
258: sm
259: .getString("contextConfig.applicationParse"),
260: e);
261: log.error(sm.getString(
262: "contextConfig.applicationPosition", ""
263: + e.getLineNumber(), ""
264: + e.getColumnNumber()));
265: ok = false;
266: } catch (Exception e) {
267: log
268: .error(
269: sm
270: .getString("contextConfig.applicationParse"),
271: e);
272: ok = false;
273: } finally {
274: parseException = null;
275: try {
276: if (stream != null) {
277: stream.close();
278: }
279: } catch (IOException e) {
280: log
281: .error(
282: sm
283: .getString("contextConfig.applicationClose"),
284: e);
285: }
286: webDigester.push(null);
287: }
288: }
289: webRuleSet.recycle();
290:
291: long t2 = System.currentTimeMillis();
292: if (context instanceof StandardContext) {
293: ((StandardContext) context).setStartupTime(t2 - t1);
294: }
295: }
296:
297: /**
298: * Set up a manager.
299: */
300: private synchronized void managerConfig() {
301:
302: if (context.getManager() == null) {
303: if ((context.getCluster() != null)
304: && context.getDistributable()) {
305: try {
306: context.setManager(context.getCluster()
307: .createManager(context.getName()));
308: } catch (Exception ex) {
309: log.error("contextConfig.clusteringInit", ex);
310: ok = false;
311: }
312: } else {
313: context.setManager(new StandardManager());
314: }
315: }
316:
317: }
318:
319: /**
320: * Set up an Authenticator automatically if required, and one has not
321: * already been configured.
322: */
323: private synchronized void authenticatorConfig() {
324:
325: // Does this Context require an Authenticator?
326: SecurityConstraint constraints[] = context.findConstraints();
327: if ((constraints == null) || (constraints.length == 0))
328: return;
329: LoginConfig loginConfig = context.getLoginConfig();
330: if (loginConfig == null) {
331: loginConfig = new LoginConfig("NONE", null, null, null);
332: context.setLoginConfig(loginConfig);
333: }
334:
335: // Has an authenticator been configured already?
336: if (context instanceof Authenticator)
337: return;
338: if (context instanceof ContainerBase) {
339: Pipeline pipeline = ((ContainerBase) context).getPipeline();
340: if (pipeline != null) {
341: Valve basic = pipeline.getBasic();
342: if ((basic != null) && (basic instanceof Authenticator))
343: return;
344: Valve valves[] = pipeline.getValves();
345: for (int i = 0; i < valves.length; i++) {
346: if (valves[i] instanceof Authenticator)
347: return;
348: }
349: }
350: } else {
351: return; // Cannot install a Valve even if it would be needed
352: }
353:
354: // Has a Realm been configured for us to authenticate against?
355: if (context.getRealm() == null) {
356: log.error(sm.getString("contextConfig.missingRealm"));
357: ok = false;
358: return;
359: }
360:
361: // Load our mapping properties if necessary
362: if (authenticators == null) {
363: try {
364: InputStream is = this
365: .getClass()
366: .getClassLoader()
367: .getResourceAsStream(
368: "org/apache/catalina/startup/Authenticators.properties");
369: if (is != null) {
370: authenticators = new Properties();
371: authenticators.load(is);
372: } else {
373: log
374: .error(sm
375: .getString("contextConfig.authenticatorResources"));
376: ok = false;
377: return;
378: }
379: } catch (IOException e) {
380: log
381: .error(
382: sm
383: .getString("contextConfig.authenticatorResources"),
384: e);
385: ok = false;
386: return;
387: }
388: }
389:
390: // Identify the class name of the Valve we should configure
391: String authenticatorName = null;
392: authenticatorName = authenticators.getProperty(loginConfig
393: .getAuthMethod());
394: if (authenticatorName == null) {
395: log.error(sm.getString(
396: "contextConfig.authenticatorMissing", loginConfig
397: .getAuthMethod()));
398: ok = false;
399: return;
400: }
401:
402: // Instantiate and install an Authenticator of the requested class
403: Valve authenticator = null;
404: try {
405: Class authenticatorClass = Class.forName(authenticatorName);
406: authenticator = (Valve) authenticatorClass.newInstance();
407: if (context instanceof ContainerBase) {
408: Pipeline pipeline = ((ContainerBase) context)
409: .getPipeline();
410: if (pipeline != null) {
411: ((ContainerBase) context).addValve(authenticator);
412: if (log.isDebugEnabled())
413: log
414: .debug(sm
415: .getString(
416: "contextConfig.authenticatorConfigured",
417: loginConfig
418: .getAuthMethod()));
419: }
420: }
421: } catch (Throwable t) {
422: log.error(sm.getString(
423: "contextConfig.authenticatorInstantiate",
424: authenticatorName), t);
425: ok = false;
426: }
427:
428: }
429:
430: /**
431: * Create (if necessary) and return a Digester configured to process the
432: * web application deployment descriptor (web.xml).
433: */
434: private static Digester createWebDigester() {
435: Digester webDigester = createWebXmlDigester(xmlNamespaceAware,
436: xmlValidation);
437: return webDigester;
438: }
439:
440: /*
441: * Create (if necessary) and return a Digester configured to process the
442: * web application deployment descriptor (web.xml).
443: */
444: public static Digester createWebXmlDigester(boolean namespaceAware,
445: boolean validation) {
446:
447: Digester webDigester = DigesterFactory.newDigester(
448: xmlValidation, xmlNamespaceAware, webRuleSet);
449: return webDigester;
450: }
451:
452: private String getBaseDir() {
453: Container engineC = context.getParent().getParent();
454: if (engineC instanceof StandardEngine) {
455: return ((StandardEngine) engineC).getBaseDir();
456: }
457: return System.getProperty("catalina.base");
458: }
459:
460: /**
461: * Process the default configuration file, if it exists.
462: * The default config must be read with the container loader - so
463: * container servlets can be loaded
464: */
465: private void defaultConfig() {
466: long t1 = System.currentTimeMillis();
467:
468: // Open the default web.xml file, if it exists
469: if (defaultWebXml == null && context instanceof StandardContext) {
470: defaultWebXml = ((StandardContext) context)
471: .getDefaultWebXml();
472: }
473: // set the default if we don't have any overrides
474: if (defaultWebXml == null)
475: getDefaultWebXml();
476:
477: File file = new File(this .defaultWebXml);
478: if (!file.isAbsolute()) {
479: file = new File(getBaseDir(), this .defaultWebXml);
480: }
481:
482: InputStream stream = null;
483: InputSource source = null;
484:
485: try {
486: if (!file.exists()) {
487: // Use getResource and getResourceAsStream
488: stream = getClass().getClassLoader()
489: .getResourceAsStream(defaultWebXml);
490: if (stream != null) {
491: source = new InputSource(getClass()
492: .getClassLoader()
493: .getResource(defaultWebXml).toString());
494: } else {
495: log.info("No default web.xml");
496: // no default web.xml
497: return;
498: }
499: } else {
500: source = new InputSource("file://"
501: + file.getAbsolutePath());
502: stream = new FileInputStream(file);
503: }
504: } catch (Exception e) {
505: log.error(sm.getString("contextConfig.defaultMissing")
506: + " " + defaultWebXml + " " + file, e);
507: return;
508: }
509:
510: if (webDigester == null) {
511: webDigester = createWebDigester();
512: }
513:
514: // Process the default web.xml file
515: synchronized (webDigester) {
516: try {
517: source.setByteStream(stream);
518:
519: if (context instanceof StandardContext)
520: ((StandardContext) context)
521: .setReplaceWelcomeFiles(true);
522: webDigester.clear();
523: webDigester.setClassLoader(this .getClass()
524: .getClassLoader());
525: //log.info( "Using cl: " + webDigester.getClassLoader());
526: webDigester.setUseContextClassLoader(false);
527: webDigester.push(context);
528: webDigester.setErrorHandler(new ContextErrorHandler());
529: webDigester.parse(source);
530: if (parseException != null) {
531: ok = false;
532: }
533: } catch (SAXParseException e) {
534: log
535: .error(
536: sm
537: .getString("contextConfig.defaultParse"),
538: e);
539: log.error(sm.getString("contextConfig.defaultPosition",
540: "" + e.getLineNumber(), ""
541: + e.getColumnNumber()));
542: ok = false;
543: } catch (Exception e) {
544: log
545: .error(
546: sm
547: .getString("contextConfig.defaultParse"),
548: e);
549: ok = false;
550: } finally {
551: parseException = null;
552: try {
553: if (stream != null) {
554: stream.close();
555: }
556: } catch (IOException e) {
557: log
558: .error(
559: sm
560: .getString("contextConfig.defaultClose"),
561: e);
562: }
563: }
564: }
565: webRuleSet.recycle();
566:
567: long t2 = System.currentTimeMillis();
568: if ((t2 - t1) > 200)
569: log.debug("Processed default web.xml " + file + " "
570: + (t2 - t1));
571: }
572:
573: /**
574: * Log a message on the Logger associated with our Context (if any)
575: *
576: * @param message Message to be logged
577: */
578: private void log(String message) {
579:
580: Logger logger = null;
581: if (context != null)
582: logger = context.getLogger();
583: if (logger != null)
584: logger.log("ContextConfig[" + context.getName() + "]: "
585: + message);
586: else
587: log.info(message);
588: }
589:
590: /**
591: * Log a message on the Logger associated with our Context (if any)
592: *
593: * @param message Message to be logged
594: * @param throwable Associated exception
595: */
596: private void log(String message, Throwable throwable) {
597:
598: Logger logger = null;
599: if (context != null)
600: logger = context.getLogger();
601: if (logger != null)
602: logger.log("ContextConfig[" + context.getName() + "] "
603: + message, throwable);
604: else {
605: log.error(message, throwable);
606: }
607:
608: }
609:
610: /**
611: * Process a "start" event for this Context - in background
612: */
613: private synchronized void start() {
614: // Called from StandardContext.start()
615:
616: if (log.isDebugEnabled())
617: log.debug(sm.getString("contextConfig.start"));
618: context.setConfigured(false);
619: ok = true;
620:
621: // Set properties based on DefaultContext
622: Container container = context.getParent();
623: if (!context.getOverride()) {
624: if (container instanceof Host) {
625: ((Host) container).importDefaultContext(context);
626:
627: // Reset the value only if the attribute wasn't
628: // set on the context.
629: xmlValidation = context.getXmlValidation();
630: if (!xmlValidation) {
631: xmlValidation = ((Host) container)
632: .getXmlValidation();
633: }
634:
635: xmlNamespaceAware = context.getXmlNamespaceAware();
636: if (!xmlNamespaceAware) {
637: xmlNamespaceAware = ((Host) container)
638: .getXmlNamespaceAware();
639: }
640:
641: container = container.getParent();
642: }
643: if (container instanceof Engine) {
644: ((Engine) container).importDefaultContext(context);
645: }
646: }
647:
648: // Process the default and application web.xml files
649: defaultConfig();
650: applicationConfig();
651: if (ok) {
652: validateSecurityRoles();
653: }
654:
655: // Configure an authenticator if we need one
656: if (ok)
657: authenticatorConfig();
658:
659: // Configure a manager
660: if (ok)
661: managerConfig();
662:
663: // Dump the contents of this pipeline if requested
664: if ((log.isDebugEnabled())
665: && (context instanceof ContainerBase)) {
666: log.debug("Pipline Configuration:");
667: Pipeline pipeline = ((ContainerBase) context).getPipeline();
668: Valve valves[] = null;
669: if (pipeline != null)
670: valves = pipeline.getValves();
671: if (valves != null) {
672: for (int i = 0; i < valves.length; i++) {
673: log.debug(" " + valves[i].getInfo());
674: }
675: }
676: log.debug("======================");
677: }
678:
679: // Make our application available if no problems were encountered
680: if (ok)
681: context.setConfigured(true);
682: else {
683: log.error(sm.getString("contextConfig.unavailable"));
684: context.setConfigured(false);
685: }
686:
687: }
688:
689: /**
690: * Process a "stop" event for this Context.
691: */
692: private synchronized void stop() {
693:
694: if (log.isDebugEnabled())
695: log.debug(sm.getString("contextConfig.stop"));
696:
697: int i;
698:
699: // Removing children
700: Container[] children = context.findChildren();
701: for (i = 0; i < children.length; i++) {
702: context.removeChild(children[i]);
703: }
704:
705: // Removing application parameters
706: /*
707: ApplicationParameter[] applicationParameters =
708: context.findApplicationParameters();
709: for (i = 0; i < applicationParameters.length; i++) {
710: context.removeApplicationParameter
711: (applicationParameters[i].getName());
712: }
713: */
714:
715: // Removing security constraints
716: SecurityConstraint[] securityConstraints = context
717: .findConstraints();
718: for (i = 0; i < securityConstraints.length; i++) {
719: context.removeConstraint(securityConstraints[i]);
720: }
721:
722: // Removing Ejbs
723: /*
724: ContextEjb[] contextEjbs = context.findEjbs();
725: for (i = 0; i < contextEjbs.length; i++) {
726: context.removeEjb(contextEjbs[i].getName());
727: }
728: */
729:
730: // Removing environments
731: /*
732: ContextEnvironment[] contextEnvironments = context.findEnvironments();
733: for (i = 0; i < contextEnvironments.length; i++) {
734: context.removeEnvironment(contextEnvironments[i].getName());
735: }
736: */
737:
738: // Removing errors pages
739: ErrorPage[] errorPages = context.findErrorPages();
740: for (i = 0; i < errorPages.length; i++) {
741: context.removeErrorPage(errorPages[i]);
742: }
743:
744: // Removing filter defs
745: FilterDef[] filterDefs = context.findFilterDefs();
746: for (i = 0; i < filterDefs.length; i++) {
747: context.removeFilterDef(filterDefs[i]);
748: }
749:
750: // Removing filter maps
751: FilterMap[] filterMaps = context.findFilterMaps();
752: for (i = 0; i < filterMaps.length; i++) {
753: context.removeFilterMap(filterMaps[i]);
754: }
755:
756: // Removing local ejbs
757: /*
758: ContextLocalEjb[] contextLocalEjbs = context.findLocalEjbs();
759: for (i = 0; i < contextLocalEjbs.length; i++) {
760: context.removeLocalEjb(contextLocalEjbs[i].getName());
761: }
762: */
763:
764: // Removing Mime mappings
765: String[] mimeMappings = context.findMimeMappings();
766: for (i = 0; i < mimeMappings.length; i++) {
767: context.removeMimeMapping(mimeMappings[i]);
768: }
769:
770: // Removing parameters
771: String[] parameters = context.findParameters();
772: for (i = 0; i < parameters.length; i++) {
773: context.removeParameter(parameters[i]);
774: }
775:
776: // Removing resource env refs
777: /*
778: String[] resourceEnvRefs = context.findResourceEnvRefs();
779: for (i = 0; i < resourceEnvRefs.length; i++) {
780: context.removeResourceEnvRef(resourceEnvRefs[i]);
781: }
782: */
783:
784: // Removing resource links
785: /*
786: ContextResourceLink[] contextResourceLinks =
787: context.findResourceLinks();
788: for (i = 0; i < contextResourceLinks.length; i++) {
789: context.removeResourceLink(contextResourceLinks[i].getName());
790: }
791: */
792:
793: // Removing resources
794: /*
795: ContextResource[] contextResources = context.findResources();
796: for (i = 0; i < contextResources.length; i++) {
797: context.removeResource(contextResources[i].getName());
798: }
799: */
800:
801: // Removing sercurity role
802: String[] securityRoles = context.findSecurityRoles();
803: for (i = 0; i < securityRoles.length; i++) {
804: context.removeSecurityRole(securityRoles[i]);
805: }
806:
807: // Removing servlet mappings
808: String[] servletMappings = context.findServletMappings();
809: for (i = 0; i < servletMappings.length; i++) {
810: context.removeServletMapping(servletMappings[i]);
811: }
812:
813: // FIXME : Removing status pages
814:
815: // Removing taglibs
816: String[] taglibs = context.findTaglibs();
817: for (i = 0; i < taglibs.length; i++) {
818: context.removeTaglib(taglibs[i]);
819: }
820:
821: // Removing welcome files
822: String[] welcomeFiles = context.findWelcomeFiles();
823: for (i = 0; i < welcomeFiles.length; i++) {
824: context.removeWelcomeFile(welcomeFiles[i]);
825: }
826:
827: // Removing wrapper lifecycles
828: String[] wrapperLifecycles = context.findWrapperLifecycles();
829: for (i = 0; i < wrapperLifecycles.length; i++) {
830: context.removeWrapperLifecycle(wrapperLifecycles[i]);
831: }
832:
833: // Removing wrapper listeners
834: String[] wrapperListeners = context.findWrapperListeners();
835: for (i = 0; i < wrapperListeners.length; i++) {
836: context.removeWrapperListener(wrapperListeners[i]);
837: }
838:
839: ok = true;
840:
841: }
842:
843: /**
844: * Validate the usage of security role names in the web application
845: * deployment descriptor. If any problems are found, issue warning
846: * messages (for backwards compatibility) and add the missing roles.
847: * (To make these problems fatal instead, simply set the <code>ok</code>
848: * instance variable to <code>false</code> as well).
849: */
850: private void validateSecurityRoles() {
851:
852: // Check role names used in <security-constraint> elements
853: SecurityConstraint constraints[] = context.findConstraints();
854: for (int i = 0; i < constraints.length; i++) {
855: String roles[] = constraints[i].findAuthRoles();
856: for (int j = 0; j < roles.length; j++) {
857: if (!"*".equals(roles[j])
858: && !context.findSecurityRole(roles[j])) {
859: log.info(sm.getString("contextConfig.role.auth",
860: roles[j]));
861: context.addSecurityRole(roles[j]);
862: }
863: }
864: }
865:
866: // Check role names used in <servlet> elements
867: Container wrappers[] = context.findChildren();
868: for (int i = 0; i < wrappers.length; i++) {
869: Wrapper wrapper = (Wrapper) wrappers[i];
870: String runAs = wrapper.getRunAs();
871: if ((runAs != null) && !context.findSecurityRole(runAs)) {
872: log.info(sm
873: .getString("contextConfig.role.runas", runAs));
874: context.addSecurityRole(runAs);
875: }
876: String names[] = wrapper.findSecurityReferences();
877: for (int j = 0; j < names.length; j++) {
878: String link = wrapper.findSecurityReference(names[j]);
879: if ((link != null) && !context.findSecurityRole(link)) {
880: log.info(sm.getString("contextConfig.role.link",
881: link));
882: context.addSecurityRole(link);
883: }
884: }
885: }
886:
887: }
888:
889: private class ContextErrorHandler implements ErrorHandler {
890:
891: public void error(SAXParseException exception) {
892: parseException = exception;
893: }
894:
895: public void fatalError(SAXParseException exception) {
896: parseException = exception;
897: }
898:
899: public void warning(SAXParseException exception) {
900: parseException = exception;
901: }
902:
903: }
904:
905: }
|