Source Code Cross Referenced for ContainerBase.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » catalina » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Rimfaxe Web Server » org.apache.catalina.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ContainerBase.java,v 1.21 2002/06/09 02:19:42 remm Exp $
0003:         * $Revision: 1.21 $
0004:         * $Date: 2002/06/09 02:19:42 $
0005:         *
0006:         * ====================================================================
0007:         *
0008:         * The Apache Software License, Version 1.1
0009:         *
0010:         * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
0011:         * reserved.
0012:         *
0013:         * Redistribution and use in source and binary forms, with or without
0014:         * modification, are permitted provided that the following conditions
0015:         * are met:
0016:         *
0017:         * 1. Redistributions of source code must retain the above copyright
0018:         *    notice, this list of conditions and the following disclaimer.
0019:         *
0020:         * 2. Redistributions in binary form must reproduce the above copyright
0021:         *    notice, this list of conditions and the following disclaimer in
0022:         *    the documentation and/or other materials provided with the
0023:         *    distribution.
0024:         *
0025:         * 3. The end-user documentation included with the redistribution, if
0026:         *    any, must include the following acknowlegement:
0027:         *       "This product includes software developed by the
0028:         *        Apache Software Foundation (http://www.apache.org/)."
0029:         *    Alternately, this acknowlegement may appear in the software itself,
0030:         *    if and wherever such third-party acknowlegements normally appear.
0031:         *
0032:         * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0033:         *    Foundation" must not be used to endorse or promote products derived
0034:         *    from this software without prior written permission. For written
0035:         *    permission, please contact apache@apache.org.
0036:         *
0037:         * 5. Products derived from this software may not be called "Apache"
0038:         *    nor may "Apache" appear in their names without prior written
0039:         *    permission of the Apache Group.
0040:         *
0041:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0042:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0043:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0044:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0045:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0046:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0047:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0048:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0049:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0050:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0051:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0052:         * SUCH DAMAGE.
0053:         * ====================================================================
0054:         *
0055:         * This software consists of voluntary contributions made by many
0056:         * individuals on behalf of the Apache Software Foundation.  For more
0057:         * information on the Apache Software Foundation, please see
0058:         * <http://www.apache.org/>.
0059:         *
0060:         * [Additional notices, if required by prior licensing conditions]
0061:         *
0062:         */
0063:
0064:        package org.apache.catalina.core;
0065:
0066:        import java.beans.PropertyChangeListener;
0067:        import java.beans.PropertyChangeSupport;
0068:        import java.io.IOException;
0069:        import java.security.AccessController;
0070:        import java.security.PrivilegedAction;
0071:        import java.util.ArrayList;
0072:        import java.util.HashMap;
0073:        import java.util.Hashtable;
0074:        import java.util.Iterator;
0075:        import javax.servlet.ServletException;
0076:        import javax.naming.directory.DirContext;
0077:        import org.apache.naming.resources.ProxyDirContext;
0078:        import org.apache.catalina.Cluster;
0079:        import org.apache.catalina.Container;
0080:        import org.apache.catalina.ContainerEvent;
0081:        import org.apache.catalina.ContainerListener;
0082:        import org.apache.catalina.Lifecycle;
0083:        import org.apache.catalina.LifecycleEvent;
0084:        import org.apache.catalina.LifecycleException;
0085:        import org.apache.catalina.LifecycleListener;
0086:        import org.apache.catalina.Loader;
0087:        import org.apache.catalina.Logger;
0088:        import org.apache.catalina.Manager;
0089:        import org.apache.catalina.Mapper;
0090:        import org.apache.catalina.Pipeline;
0091:        import org.apache.catalina.Realm;
0092:        import org.apache.catalina.Request;
0093:        import org.apache.catalina.Response;
0094:        import org.apache.catalina.Valve;
0095:        import org.apache.catalina.util.LifecycleSupport;
0096:        import org.apache.catalina.util.StringManager;
0097:
0098:        /**
0099:         * Abstract implementation of the <b>Container</b> interface, providing common
0100:         * functionality required by nearly every implementation.  Classes extending
0101:         * this base class must implement <code>getInfo()</code>, and may implement
0102:         * a replacement for <code>invoke()</code>.
0103:         * <p>
0104:         * All subclasses of this abstract base class will include support for a
0105:         * Pipeline object that defines the processing to be performed for each request
0106:         * received by the <code>invoke()</code> method of this class, utilizing the
0107:         * "Chain of Responsibility" design pattern.  A subclass should encapsulate its
0108:         * own processing functionality as a <code>Valve</code>, and configure this
0109:         * Valve into the pipeline by calling <code>setBasic()</code>.
0110:         * <p>
0111:         * This implementation fires property change events, per the JavaBeans design
0112:         * pattern, for changes in singleton properties.  In addition, it fires the
0113:         * following <code>ContainerEvent</code> events to listeners who register
0114:         * themselves with <code>addContainerListener()</code>:
0115:         * <table border=1>
0116:         *   <tr>
0117:         *     <th>Type</th>
0118:         *     <th>Data</th>
0119:         *     <th>Description</th>
0120:         *   </tr>
0121:         *   <tr>
0122:         *     <td align=center><code>addChild</code></td>
0123:         *     <td align=center><code>Container</code></td>
0124:         *     <td>Child container added to this Container.</td>
0125:         *   </tr>
0126:         *   <tr>
0127:         *     <td align=center><code>addValve</code></td>
0128:         *     <td align=center><code>Valve</code></td>
0129:         *     <td>Valve added to this Container.</td>
0130:         *   </tr>
0131:         *   <tr>
0132:         *     <td align=center><code>removeChild</code></td>
0133:         *     <td align=center><code>Container</code></td>
0134:         *     <td>Child container removed from this Container.</td>
0135:         *   </tr>
0136:         *   <tr>
0137:         *     <td align=center><code>removeValve</code></td>
0138:         *     <td align=center><code>Valve</code></td>
0139:         *     <td>Valve removed from this Container.</td>
0140:         *   </tr>
0141:         *   <tr>
0142:         *     <td align=center><code>start</code></td>
0143:         *     <td align=center><code>null</code></td>
0144:         *     <td>Container was started.</td>
0145:         *   </tr>
0146:         *   <tr>
0147:         *     <td align=center><code>stop</code></td>
0148:         *     <td align=center><code>null</code></td>
0149:         *     <td>Container was stopped.</td>
0150:         *   </tr>
0151:         * </table>
0152:         * Subclasses that fire additional events should document them in the
0153:         * class comments of the implementation class.
0154:         *
0155:         * @author Craig R. McClanahan
0156:         * @version $Revision: 1.21 $ $Date: 2002/06/09 02:19:42 $
0157:         */
0158:
0159:        public abstract class ContainerBase implements  Container, Lifecycle,
0160:                Pipeline {
0161:
0162:            /**
0163:             * Perform addChild with the permissions of this class.
0164:             * addChild can be called with the XML parser on the stack,
0165:             * this allows the XML parser to have fewer privileges than
0166:             * Tomcat.
0167:             */
0168:            protected class PrivilegedAddChild implements  PrivilegedAction {
0169:
0170:                private Container child;
0171:
0172:                PrivilegedAddChild(Container child) {
0173:                    this .child = child;
0174:                }
0175:
0176:                public Object run() {
0177:                    addChildInternal(child);
0178:                    return null;
0179:                }
0180:
0181:            }
0182:
0183:            // ----------------------------------------------------- Instance Variables
0184:
0185:            /**
0186:             * The child Containers belonging to this Container, keyed by name.
0187:             */
0188:            protected HashMap children = new HashMap();
0189:
0190:            /**
0191:             * The debugging detail level for this component.
0192:             */
0193:            protected int debug = 0;
0194:
0195:            /**
0196:             * The lifecycle event support for this component.
0197:             */
0198:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0199:
0200:            /**
0201:             * The container event listeners for this Container.
0202:             */
0203:            protected ArrayList listeners = new ArrayList();
0204:
0205:            /**
0206:             * The Loader implementation with which this Container is associated.
0207:             */
0208:            protected Loader loader = null;
0209:
0210:            /**
0211:             * The Logger implementation with which this Container is associated.
0212:             */
0213:            protected Logger logger = null;
0214:
0215:            /**
0216:             * The Manager implementation with which this Container is associated.
0217:             */
0218:            protected Manager manager = null;
0219:
0220:            /**
0221:             * The cluster with which this Container is associated.
0222:             */
0223:            protected Cluster cluster = null;
0224:
0225:            /**
0226:             * The one and only Mapper associated with this Container, if any.
0227:             */
0228:            protected Mapper mapper = null;
0229:
0230:            /**
0231:             * The set of Mappers associated with this Container, keyed by protocol.
0232:             */
0233:            protected HashMap mappers = new HashMap();
0234:
0235:            /**
0236:             * The Java class name of the default Mapper class for this Container.
0237:             */
0238:            protected String mapperClass = null;
0239:
0240:            /**
0241:             * The human-readable name of this Container.
0242:             */
0243:            protected String name = null;
0244:
0245:            /**
0246:             * The parent Container to which this Container is a child.
0247:             */
0248:            protected Container parent = null;
0249:
0250:            /**
0251:             * The parent class loader to be configured when we install a Loader.
0252:             */
0253:            protected ClassLoader parentClassLoader = null;
0254:
0255:            /**
0256:             * The Pipeline object with which this Container is associated.
0257:             */
0258:            protected Pipeline pipeline = new StandardPipeline(this );
0259:
0260:            /**
0261:             * The Realm with which this Container is associated.
0262:             */
0263:            protected Realm realm = null;
0264:
0265:            /**
0266:             * The resources DirContext object with which this Container is associated.
0267:             */
0268:            protected DirContext resources = null;
0269:
0270:            /**
0271:             * The string manager for this package.
0272:             */
0273:            protected static StringManager sm = StringManager
0274:                    .getManager(Constants.Package);
0275:
0276:            /**
0277:             * Has this component been started?
0278:             */
0279:            protected boolean started = false;
0280:
0281:            /**
0282:             * The property change support for this component.
0283:             */
0284:            protected PropertyChangeSupport support = new PropertyChangeSupport(
0285:                    this );
0286:
0287:            // ------------------------------------------------------------- Properties
0288:
0289:            /**
0290:             * Return the debugging detail level for this component.
0291:             */
0292:            public int getDebug() {
0293:
0294:                return (this .debug);
0295:
0296:            }
0297:
0298:            /**
0299:             * Set the debugging detail level for this component.
0300:             *
0301:             * @param debug The new debugging detail level
0302:             */
0303:            public void setDebug(int debug) {
0304:
0305:                int oldDebug = this .debug;
0306:                this .debug = debug;
0307:                support.firePropertyChange("debug", new Integer(oldDebug),
0308:                        new Integer(this .debug));
0309:
0310:            }
0311:
0312:            /**
0313:             * Return descriptive information about this Container implementation and
0314:             * the corresponding version number, in the format
0315:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0316:             */
0317:            public abstract String getInfo();
0318:
0319:            /**
0320:             * Return the Loader with which this Container is associated.  If there is
0321:             * no associated Loader, return the Loader associated with our parent
0322:             * Container (if any); otherwise, return <code>null</code>.
0323:             */
0324:            public Loader getLoader() {
0325:
0326:                if (loader != null)
0327:                    return (loader);
0328:                if (parent != null)
0329:                    return (parent.getLoader());
0330:                return (null);
0331:
0332:            }
0333:
0334:            /**
0335:             * Set the Loader with which this Container is associated.
0336:             *
0337:             * @param loader The newly associated loader
0338:             */
0339:            public synchronized void setLoader(Loader loader) {
0340:
0341:                // Change components if necessary
0342:                Loader oldLoader = this .loader;
0343:                if (oldLoader == loader)
0344:                    return;
0345:                this .loader = loader;
0346:
0347:                // Stop the old component if necessary
0348:                if (started && (oldLoader != null)
0349:                        && (oldLoader instanceof  Lifecycle)) {
0350:                    try {
0351:                        ((Lifecycle) oldLoader).stop();
0352:                    } catch (LifecycleException e) {
0353:                        log("ContainerBase.setLoader: stop: ", e);
0354:                    }
0355:                }
0356:
0357:                // Start the new component if necessary
0358:                if (loader != null)
0359:                    loader.setContainer(this );
0360:                if (started && (loader != null)
0361:                        && (loader instanceof  Lifecycle)) {
0362:                    try {
0363:                        ((Lifecycle) loader).start();
0364:                    } catch (LifecycleException e) {
0365:                        log("ContainerBase.setLoader: start: ", e);
0366:                    }
0367:                }
0368:
0369:                // Report this property change to interested listeners
0370:                support.firePropertyChange("loader", oldLoader, this .loader);
0371:
0372:            }
0373:
0374:            /**
0375:             * Return the Logger with which this Container is associated.  If there is
0376:             * no associated Logger, return the Logger associated with our parent
0377:             * Container (if any); otherwise return <code>null</code>.
0378:             */
0379:            public Logger getLogger() {
0380:
0381:                if (logger != null)
0382:                    return (logger);
0383:                if (parent != null)
0384:                    return (parent.getLogger());
0385:                return (null);
0386:
0387:            }
0388:
0389:            /**
0390:             * Set the Logger with which this Container is associated.
0391:             *
0392:             * @param logger The newly associated Logger
0393:             */
0394:            public synchronized void setLogger(Logger logger) {
0395:
0396:                // Change components if necessary
0397:                Logger oldLogger = this .logger;
0398:                if (oldLogger == logger)
0399:                    return;
0400:                this .logger = logger;
0401:
0402:                // Stop the old component if necessary
0403:                if (started && (oldLogger != null)
0404:                        && (oldLogger instanceof  Lifecycle)) {
0405:                    try {
0406:                        ((Lifecycle) oldLogger).stop();
0407:                    } catch (LifecycleException e) {
0408:                        log("ContainerBase.setLogger: stop: ", e);
0409:                    }
0410:                }
0411:
0412:                // Start the new component if necessary
0413:                if (logger != null)
0414:                    logger.setContainer(this );
0415:                if (started && (logger != null)
0416:                        && (logger instanceof  Lifecycle)) {
0417:                    try {
0418:                        ((Lifecycle) logger).start();
0419:                    } catch (LifecycleException e) {
0420:                        log("ContainerBase.setLogger: start: ", e);
0421:                    }
0422:                }
0423:
0424:                // Report this property change to interested listeners
0425:                support.firePropertyChange("logger", oldLogger, this .logger);
0426:
0427:            }
0428:
0429:            /**
0430:             * Return the Manager with which this Container is associated.  If there is
0431:             * no associated Manager, return the Manager associated with our parent
0432:             * Container (if any); otherwise return <code>null</code>.
0433:             */
0434:            public Manager getManager() {
0435:
0436:                if (manager != null)
0437:                    return (manager);
0438:                if (parent != null)
0439:                    return (parent.getManager());
0440:                return (null);
0441:
0442:            }
0443:
0444:            /**
0445:             * Set the Manager with which this Container is associated.
0446:             *
0447:             * @param manager The newly associated Manager
0448:             */
0449:            public synchronized void setManager(Manager manager) {
0450:
0451:                // Change components if necessary
0452:                Manager oldManager = this .manager;
0453:                if (oldManager == manager)
0454:                    return;
0455:                this .manager = manager;
0456:
0457:                // Stop the old component if necessary
0458:                if (started && (oldManager != null)
0459:                        && (oldManager instanceof  Lifecycle)) {
0460:                    try {
0461:                        ((Lifecycle) oldManager).stop();
0462:                    } catch (LifecycleException e) {
0463:                        log("ContainerBase.setManager: stop: ", e);
0464:                    }
0465:                }
0466:
0467:                // Start the new component if necessary
0468:                if (manager != null)
0469:                    manager.setContainer(this );
0470:                if (started && (manager != null)
0471:                        && (manager instanceof  Lifecycle)) {
0472:                    try {
0473:                        ((Lifecycle) manager).start();
0474:                    } catch (LifecycleException e) {
0475:                        log("ContainerBase.setManager: start: ", e);
0476:                    }
0477:                }
0478:
0479:                // Report this property change to interested listeners
0480:                support.firePropertyChange("manager", oldManager, this .manager);
0481:
0482:            }
0483:
0484:            /**
0485:             * Return the Cluster with which this Container is associated.  If there is
0486:             * no associated Cluster, return the Cluster associated with our parent
0487:             * Container (if any); otherwise return <code>null</code>.
0488:             */
0489:            public Cluster getCluster() {
0490:                if (cluster != null)
0491:                    return (cluster);
0492:
0493:                if (parent != null)
0494:                    return (parent.getCluster());
0495:
0496:                return (null);
0497:            }
0498:
0499:            /**
0500:             * Set the Cluster with which this Container is associated.
0501:             *
0502:             * @param manager The newly associated Cluster
0503:             */
0504:            public synchronized void setCluster(Cluster cluster) {
0505:                // Change components if necessary
0506:                Cluster oldCluster = this .cluster;
0507:                if (oldCluster == cluster)
0508:                    return;
0509:                this .cluster = cluster;
0510:
0511:                // Stop the old component if necessary
0512:                if (started && (oldCluster != null)
0513:                        && (oldCluster instanceof  Lifecycle)) {
0514:                    try {
0515:                        ((Lifecycle) oldCluster).stop();
0516:                    } catch (LifecycleException e) {
0517:                        log("ContainerBase.setCluster: stop: ", e);
0518:                    }
0519:                }
0520:
0521:                // Start the new component if necessary
0522:                if (cluster != null)
0523:                    cluster.setContainer(this );
0524:
0525:                if (started && (cluster != null)
0526:                        && (cluster instanceof  Lifecycle)) {
0527:                    try {
0528:                        ((Lifecycle) cluster).start();
0529:                    } catch (LifecycleException e) {
0530:                        log("ContainerBase.setCluster: start: ", e);
0531:                    }
0532:                }
0533:
0534:                // Report this property change to interested listeners
0535:                support.firePropertyChange("cluster", oldCluster, this .cluster);
0536:            }
0537:
0538:            /**
0539:             * Return a name string (suitable for use by humans) that describes this
0540:             * Container.  Within the set of child containers belonging to a particular
0541:             * parent, Container names must be unique.
0542:             */
0543:            public String getName() {
0544:
0545:                return (name);
0546:
0547:            }
0548:
0549:            /**
0550:             * Set a name string (suitable for use by humans) that describes this
0551:             * Container.  Within the set of child containers belonging to a particular
0552:             * parent, Container names must be unique.
0553:             *
0554:             * @param name New name of this container
0555:             *
0556:             * @exception IllegalStateException if this Container has already been
0557:             *  added to the children of a parent Container (after which the name
0558:             *  may not be changed)
0559:             */
0560:            public void setName(String name) {
0561:
0562:                String oldName = this .name;
0563:                this .name = name;
0564:                support.firePropertyChange("name", oldName, this .name);
0565:
0566:            }
0567:
0568:            /**
0569:             * Return the Container for which this Container is a child, if there is
0570:             * one.  If there is no defined parent, return <code>null</code>.
0571:             */
0572:            public Container getParent() {
0573:
0574:                return (parent);
0575:
0576:            }
0577:
0578:            /**
0579:             * Set the parent Container to which this Container is being added as a
0580:             * child.  This Container may refuse to become attached to the specified
0581:             * Container by throwing an exception.
0582:             *
0583:             * @param container Container to which this Container is being added
0584:             *  as a child
0585:             *
0586:             * @exception IllegalArgumentException if this Container refuses to become
0587:             *  attached to the specified Container
0588:             */
0589:            public void setParent(Container container) {
0590:
0591:                Container oldParent = this .parent;
0592:                this .parent = container;
0593:                support.firePropertyChange("parent", oldParent, this .parent);
0594:
0595:            }
0596:
0597:            /**
0598:             * Return the parent class loader (if any) for this web application.
0599:             * This call is meaningful only <strong>after</strong> a Loader has
0600:             * been configured.
0601:             */
0602:            public ClassLoader getParentClassLoader() {
0603:
0604:                if (parentClassLoader != null)
0605:                    return (parentClassLoader);
0606:                if (parent != null)
0607:                    return (parent.getParentClassLoader());
0608:                return (ClassLoader.getSystemClassLoader());
0609:
0610:            }
0611:
0612:            /**
0613:             * Set the parent class loader (if any) for this web application.
0614:             * This call is meaningful only <strong>before</strong> a Loader has
0615:             * been configured, and the specified value (if non-null) should be
0616:             * passed as an argument to the class loader constructor.
0617:             *
0618:             *
0619:             * @param parent The new parent class loader
0620:             */
0621:            public void setParentClassLoader(ClassLoader parent) {
0622:
0623:                ClassLoader oldParentClassLoader = this .parentClassLoader;
0624:                this .parentClassLoader = parent;
0625:                support.firePropertyChange("parentClassLoader",
0626:                        oldParentClassLoader, this .parentClassLoader);
0627:
0628:            }
0629:
0630:            /**
0631:             * Return the Pipeline object that manages the Valves associated with
0632:             * this Container.
0633:             */
0634:            public Pipeline getPipeline() {
0635:
0636:                return (this .pipeline);
0637:
0638:            }
0639:
0640:            /**
0641:             * Return the Realm with which this Container is associated.  If there is
0642:             * no associated Realm, return the Realm associated with our parent
0643:             * Container (if any); otherwise return <code>null</code>.
0644:             */
0645:            public Realm getRealm() {
0646:
0647:                if (realm != null)
0648:                    return (realm);
0649:                if (parent != null)
0650:                    return (parent.getRealm());
0651:                return (null);
0652:
0653:            }
0654:
0655:            /**
0656:             * Set the Realm with which this Container is associated.
0657:             *
0658:             * @param realm The newly associated Realm
0659:             */
0660:            public synchronized void setRealm(Realm realm) {
0661:
0662:                // Change components if necessary
0663:                Realm oldRealm = this .realm;
0664:                if (oldRealm == realm)
0665:                    return;
0666:                this .realm = realm;
0667:
0668:                // Stop the old component if necessary
0669:                if (started && (oldRealm != null)
0670:                        && (oldRealm instanceof  Lifecycle)) {
0671:                    try {
0672:                        ((Lifecycle) oldRealm).stop();
0673:                    } catch (LifecycleException e) {
0674:                        log("ContainerBase.setRealm: stop: ", e);
0675:                    }
0676:                }
0677:
0678:                // Start the new component if necessary
0679:                if (realm != null)
0680:                    realm.setContainer(this );
0681:                if (started && (realm != null) && (realm instanceof  Lifecycle)) {
0682:                    try {
0683:                        ((Lifecycle) realm).start();
0684:                    } catch (LifecycleException e) {
0685:                        log("ContainerBase.setRealm: start: ", e);
0686:                    }
0687:                }
0688:
0689:                // Report this property change to interested listeners
0690:                support.firePropertyChange("realm", oldRealm, this .realm);
0691:
0692:            }
0693:
0694:            /**
0695:             * Return the resources DirContext object with which this Container is
0696:             * associated.  If there is no associated resources object, return the
0697:             * resources associated with our parent Container (if any); otherwise
0698:             * return <code>null</code>.
0699:             */
0700:            public DirContext getResources() {
0701:
0702:                if (resources != null)
0703:                    return (resources);
0704:                if (parent != null)
0705:                    return (parent.getResources());
0706:                return (null);
0707:
0708:            }
0709:
0710:            /**
0711:             * Set the resources DirContext object with which this Container is
0712:             * associated.
0713:             *
0714:             * @param resources The newly associated DirContext
0715:             */
0716:            public synchronized void setResources(DirContext resources) {
0717:
0718:                // Change components if necessary
0719:                DirContext oldResources = this .resources;
0720:                if (oldResources == resources)
0721:                    return;
0722:                Hashtable env = new Hashtable();
0723:                if (getParent() != null)
0724:                    env.put(ProxyDirContext.HOST, getParent().getName());
0725:                env.put(ProxyDirContext.CONTEXT, getName());
0726:                this .resources = new ProxyDirContext(env, resources);
0727:                // Report this property change to interested listeners
0728:                support.firePropertyChange("resources", oldResources,
0729:                        this .resources);
0730:
0731:            }
0732:
0733:            // ------------------------------------------------------ Container Methods
0734:
0735:            /**
0736:             * Add a new child Container to those associated with this Container,
0737:             * if supported.  Prior to adding this Container to the set of children,
0738:             * the child's <code>setParent()</code> method must be called, with this
0739:             * Container as an argument.  This method may thrown an
0740:             * <code>IllegalArgumentException</code> if this Container chooses not
0741:             * to be attached to the specified Container, in which case it is not added
0742:             *
0743:             * @param child New child Container to be added
0744:             *
0745:             * @exception IllegalArgumentException if this exception is thrown by
0746:             *  the <code>setParent()</code> method of the child Container
0747:             * @exception IllegalArgumentException if the new child does not have
0748:             *  a name unique from that of existing children of this Container
0749:             * @exception IllegalStateException if this Container does not support
0750:             *  child Containers
0751:             */
0752:            public void addChild(Container child) {
0753:                if (System.getSecurityManager() != null) {
0754:                    PrivilegedAction dp = new PrivilegedAddChild(child);
0755:                    AccessController.doPrivileged(dp);
0756:                } else {
0757:                    addChildInternal(child);
0758:                }
0759:            }
0760:
0761:            private void addChildInternal(Container child) {
0762:
0763:                synchronized (children) {
0764:                    if (children.get(child.getName()) != null)
0765:                        throw new IllegalArgumentException(
0766:                                "addChild:  Child name '" + child.getName()
0767:                                        + "' is not unique");
0768:                    child.setParent((Container) this ); // May throw IAE
0769:                    if (started && (child instanceof  Lifecycle)) {
0770:                        try {
0771:                            ((Lifecycle) child).start();
0772:                        } catch (LifecycleException e) {
0773:                            log("ContainerBase.addChild: start: ", e);
0774:                            throw new IllegalStateException(
0775:                                    "ContainerBase.addChild: start: " + e);
0776:                        }
0777:                    }
0778:                    children.put(child.getName(), child);
0779:                    fireContainerEvent(ADD_CHILD_EVENT, child);
0780:                }
0781:
0782:            }
0783:
0784:            /**
0785:             * Add a container event listener to this component.
0786:             *
0787:             * @param listener The listener to add
0788:             */
0789:            public void addContainerListener(ContainerListener listener) {
0790:
0791:                synchronized (listeners) {
0792:                    listeners.add(listener);
0793:                }
0794:
0795:            }
0796:
0797:            /**
0798:             * Add the specified Mapper associated with this Container.
0799:             *
0800:             * @param mapper The corresponding Mapper implementation
0801:             *
0802:             * @exception IllegalArgumentException if this exception is thrown by
0803:             *  the <code>setContainer()</code> method of the Mapper
0804:             */
0805:            public void addMapper(Mapper mapper) {
0806:
0807:                synchronized (mappers) {
0808:                    if (mappers.get(mapper.getProtocol()) != null)
0809:                        throw new IllegalArgumentException(
0810:                                "addMapper:  Protocol '" + mapper.getProtocol()
0811:                                        + "' is not unique");
0812:                    mapper.setContainer((Container) this ); // May throw IAE
0813:                    if (started && (mapper instanceof  Lifecycle)) {
0814:                        try {
0815:                            ((Lifecycle) mapper).start();
0816:                        } catch (LifecycleException e) {
0817:                            log("ContainerBase.addMapper: start: ", e);
0818:                            throw new IllegalStateException(
0819:                                    "ContainerBase.addMapper: start: " + e);
0820:                        }
0821:                    }
0822:                    mappers.put(mapper.getProtocol(), mapper);
0823:                    if (mappers.size() == 1)
0824:                        this .mapper = mapper;
0825:                    else
0826:                        this .mapper = null;
0827:                    fireContainerEvent(ADD_MAPPER_EVENT, mapper);
0828:                }
0829:
0830:            }
0831:
0832:            /**
0833:             * Add a property change listener to this component.
0834:             *
0835:             * @param listener The listener to add
0836:             */
0837:            public void addPropertyChangeListener(
0838:                    PropertyChangeListener listener) {
0839:
0840:                support.addPropertyChangeListener(listener);
0841:
0842:            }
0843:
0844:            /**
0845:             * Return the child Container, associated with this Container, with
0846:             * the specified name (if any); otherwise, return <code>null</code>
0847:             *
0848:             * @param name Name of the child Container to be retrieved
0849:             */
0850:            public Container findChild(String name) {
0851:
0852:                if (name == null)
0853:                    return (null);
0854:                synchronized (children) { // Required by post-start changes
0855:                    return ((Container) children.get(name));
0856:                }
0857:
0858:            }
0859:
0860:            /**
0861:             * Return the set of children Containers associated with this Container.
0862:             * If this Container has no children, a zero-length array is returned.
0863:             */
0864:            public Container[] findChildren() {
0865:
0866:                synchronized (children) {
0867:                    Container results[] = new Container[children.size()];
0868:                    return ((Container[]) children.values().toArray(results));
0869:                }
0870:
0871:            }
0872:
0873:            /**
0874:             * Return the set of container listeners associated with this Container.
0875:             * If this Container has no registered container listeners, a zero-length
0876:             * array is returned.
0877:             */
0878:            public ContainerListener[] findContainerListeners() {
0879:
0880:                synchronized (listeners) {
0881:                    ContainerListener[] results = new ContainerListener[listeners
0882:                            .size()];
0883:                    return ((ContainerListener[]) listeners.toArray(results));
0884:                }
0885:
0886:            }
0887:
0888:            /**
0889:             * Return the Mapper associated with the specified protocol, if there
0890:             * is one.  If there is only one defined Mapper, use it for all protocols.
0891:             * If there is no matching Mapper, return <code>null</code>.
0892:             *
0893:             * @param protocol Protocol for which to find a Mapper
0894:             */
0895:            public Mapper findMapper(String protocol) {
0896:
0897:                if (mapper != null)
0898:                    return (mapper);
0899:                else
0900:                    synchronized (mappers) {
0901:                        return ((Mapper) mappers.get(protocol));
0902:                    }
0903:
0904:            }
0905:
0906:            /**
0907:             * Return the set of Mappers associated with this Container.  If this
0908:             * Container has no Mappers, a zero-length array is returned.
0909:             */
0910:            public Mapper[] findMappers() {
0911:
0912:                synchronized (mappers) {
0913:                    Mapper results[] = new Mapper[mappers.size()];
0914:                    return ((Mapper[]) mappers.values().toArray(results));
0915:                }
0916:
0917:            }
0918:
0919:            /**
0920:             * Process the specified Request, to produce the corresponding Response,
0921:             * by invoking the first Valve in our pipeline (if any), or the basic
0922:             * Valve otherwise.
0923:             *
0924:             * @param request Request to be processed
0925:             * @param response Response to be produced
0926:             *
0927:             * @exception IllegalStateException if neither a pipeline or a basic
0928:             *  Valve have been configured for this Container
0929:             * @exception IOException if an input/output error occurred while
0930:             *  processing
0931:             * @exception ServletException if a ServletException was thrown
0932:             *  while processing this request
0933:             */
0934:            public void invoke(Request request, Response response)
0935:                    throws IOException, ServletException {
0936:
0937:                pipeline.invoke(request, response);
0938:
0939:            }
0940:
0941:            /**
0942:             * Return the child Container that should be used to process this Request,
0943:             * based upon its characteristics.  If no such child Container can be
0944:             * identified, return <code>null</code> instead.
0945:             *
0946:             * @param request Request being processed
0947:             * @param update Update the Request to reflect the mapping selection?
0948:             */
0949:            public Container map(Request request, boolean update) {
0950:
0951:                // Select the Mapper we will use
0952:                Mapper mapper = findMapper(request.getRequest().getProtocol());
0953:                if (mapper == null)
0954:                    return (null);
0955:
0956:                // Use this Mapper to perform this mapping
0957:                return (mapper.map(request, update));
0958:
0959:            }
0960:
0961:            /**
0962:             * Remove an existing child Container from association with this parent
0963:             * Container.
0964:             *
0965:             * @param child Existing child Container to be removed
0966:             */
0967:            public void removeChild(Container child) {
0968:
0969:                synchronized (children) {
0970:                    if (children.get(child.getName()) == null)
0971:                        return;
0972:                    children.remove(child.getName());
0973:                }
0974:                if (started && (child instanceof  Lifecycle)) {
0975:                    try {
0976:                        ((Lifecycle) child).stop();
0977:                    } catch (LifecycleException e) {
0978:                        log("ContainerBase.removeChild: stop: ", e);
0979:                    }
0980:                }
0981:                fireContainerEvent(REMOVE_CHILD_EVENT, child);
0982:                child.setParent(null);
0983:
0984:            }
0985:
0986:            /**
0987:             * Remove a container event listener from this component.
0988:             *
0989:             * @param listener The listener to remove
0990:             */
0991:            public void removeContainerListener(ContainerListener listener) {
0992:
0993:                synchronized (listeners) {
0994:                    listeners.remove(listener);
0995:                }
0996:
0997:            }
0998:
0999:            /**
1000:             * Remove a Mapper associated with this Container, if any.
1001:             *
1002:             * @param mapper The Mapper to be removed
1003:             */
1004:            public void removeMapper(Mapper mapper) {
1005:
1006:                synchronized (mappers) {
1007:
1008:                    if (mappers.get(mapper.getProtocol()) == null)
1009:                        return;
1010:                    mappers.remove(mapper.getProtocol());
1011:                    if (started && (mapper instanceof  Lifecycle)) {
1012:                        try {
1013:                            ((Lifecycle) mapper).stop();
1014:                        } catch (LifecycleException e) {
1015:                            log("ContainerBase.removeMapper: stop: ", e);
1016:                            throw new IllegalStateException(
1017:                                    "ContainerBase.removeMapper: stop: " + e);
1018:                        }
1019:                    }
1020:                    if (mappers.size() != 1)
1021:                        this .mapper = null;
1022:                    else {
1023:                        Iterator values = mappers.values().iterator();
1024:                        this .mapper = (Mapper) values.next();
1025:                    }
1026:                    fireContainerEvent(REMOVE_MAPPER_EVENT, mapper);
1027:                }
1028:
1029:            }
1030:
1031:            /**
1032:             * Remove a property change listener from this component.
1033:             *
1034:             * @param listener The listener to remove
1035:             */
1036:            public void removePropertyChangeListener(
1037:                    PropertyChangeListener listener) {
1038:
1039:                support.removePropertyChangeListener(listener);
1040:
1041:            }
1042:
1043:            // ------------------------------------------------------ Lifecycle Methods
1044:
1045:            /**
1046:             * Add a lifecycle event listener to this component.
1047:             *
1048:             * @param listener The listener to add
1049:             */
1050:            public void addLifecycleListener(LifecycleListener listener) {
1051:
1052:                lifecycle.addLifecycleListener(listener);
1053:
1054:            }
1055:
1056:            /**
1057:             * Get the lifecycle listeners associated with this lifecycle. If this 
1058:             * Lifecycle has no listeners registered, a zero-length array is returned.
1059:             */
1060:            public LifecycleListener[] findLifecycleListeners() {
1061:
1062:                return lifecycle.findLifecycleListeners();
1063:
1064:            }
1065:
1066:            /**
1067:             * Remove a lifecycle event listener from this component.
1068:             *
1069:             * @param listener The listener to remove
1070:             */
1071:            public void removeLifecycleListener(LifecycleListener listener) {
1072:
1073:                lifecycle.removeLifecycleListener(listener);
1074:
1075:            }
1076:
1077:            /**
1078:             * Prepare for active use of the public methods of this Component.
1079:             *
1080:             * @exception LifecycleException if this component detects a fatal error
1081:             *  that prevents it from being started
1082:             */
1083:            public synchronized void start() throws LifecycleException {
1084:
1085:                // Validate and update our current component state
1086:                if (started)
1087:                    throw new LifecycleException(sm.getString(
1088:                            "containerBase.alreadyStarted", logName()));
1089:
1090:                // Notify our interested LifecycleListeners
1091:                lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
1092:
1093:                addDefaultMapper(this .mapperClass);
1094:                started = true;
1095:
1096:                // Start our subordinate components, if any
1097:                if ((loader != null) && (loader instanceof  Lifecycle))
1098:                    ((Lifecycle) loader).start();
1099:                if ((logger != null) && (logger instanceof  Lifecycle))
1100:                    ((Lifecycle) logger).start();
1101:                if ((manager != null) && (manager instanceof  Lifecycle))
1102:                    ((Lifecycle) manager).start();
1103:                if ((cluster != null) && (cluster instanceof  Lifecycle))
1104:                    ((Lifecycle) cluster).start();
1105:                if ((realm != null) && (realm instanceof  Lifecycle))
1106:                    ((Lifecycle) realm).start();
1107:                if ((resources != null) && (resources instanceof  Lifecycle))
1108:                    ((Lifecycle) resources).start();
1109:
1110:                // Start our Mappers, if any
1111:                Mapper mappers[] = findMappers();
1112:                for (int i = 0; i < mappers.length; i++) {
1113:                    if (mappers[i] instanceof  Lifecycle)
1114:                        ((Lifecycle) mappers[i]).start();
1115:                }
1116:
1117:                // Start our child containers, if any
1118:                Container children[] = findChildren();
1119:                for (int i = 0; i < children.length; i++) {
1120:                    if (children[i] instanceof  Lifecycle)
1121:                        ((Lifecycle) children[i]).start();
1122:                }
1123:
1124:                // Start the Valves in our pipeline (including the basic), if any
1125:                if (pipeline instanceof  Lifecycle)
1126:                    ((Lifecycle) pipeline).start();
1127:
1128:                // Notify our interested LifecycleListeners
1129:                lifecycle.fireLifecycleEvent(START_EVENT, null);
1130:
1131:                // Notify our interested LifecycleListeners
1132:                lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
1133:
1134:            }
1135:
1136:            /**
1137:             * Gracefully shut down active use of the public methods of this Component.
1138:             *
1139:             * @exception LifecycleException if this component detects a fatal error
1140:             *  that needs to be reported
1141:             */
1142:            public synchronized void stop() throws LifecycleException {
1143:
1144:                // Validate and update our current component state
1145:                if (!started)
1146:                    throw new LifecycleException(sm.getString(
1147:                            "containerBase.notStarted", logName()));
1148:
1149:                // Notify our interested LifecycleListeners
1150:                lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
1151:
1152:                // Notify our interested LifecycleListeners
1153:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
1154:                started = false;
1155:
1156:                // Stop the Valves in our pipeline (including the basic), if any
1157:                if (pipeline instanceof  Lifecycle) {
1158:                    ((Lifecycle) pipeline).stop();
1159:                }
1160:
1161:                // Stop our child containers, if any
1162:                Container children[] = findChildren();
1163:                for (int i = 0; i < children.length; i++) {
1164:                    if (children[i] instanceof  Lifecycle)
1165:                        ((Lifecycle) children[i]).stop();
1166:                }
1167:
1168:                // Stop our Mappers, if any
1169:                Mapper mappers[] = findMappers();
1170:                for (int i = 0; i < mappers.length; i++) {
1171:                    if (mappers[(mappers.length - 1) - i] instanceof  Lifecycle)
1172:                        ((Lifecycle) mappers[(mappers.length - 1) - i]).stop();
1173:                }
1174:
1175:                // Stop our subordinate components, if any
1176:                if ((resources != null) && (resources instanceof  Lifecycle)) {
1177:                    ((Lifecycle) resources).stop();
1178:                }
1179:                if ((realm != null) && (realm instanceof  Lifecycle)) {
1180:                    ((Lifecycle) realm).stop();
1181:                }
1182:                if ((cluster != null) && (cluster instanceof  Lifecycle)) {
1183:                    ((Lifecycle) cluster).stop();
1184:                }
1185:                if ((manager != null) && (manager instanceof  Lifecycle)) {
1186:                    ((Lifecycle) manager).stop();
1187:                }
1188:                if ((logger != null) && (logger instanceof  Lifecycle)) {
1189:                    ((Lifecycle) logger).stop();
1190:                }
1191:                if ((loader != null) && (loader instanceof  Lifecycle)) {
1192:                    ((Lifecycle) loader).stop();
1193:                }
1194:
1195:                // Notify our interested LifecycleListeners
1196:                lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
1197:
1198:            }
1199:
1200:            // ------------------------------------------------------- Pipeline Methods
1201:
1202:            /**
1203:             * Add a new Valve to the end of the pipeline associated with this
1204:             * Container.  Prior to adding the Valve, the Valve's
1205:             * <code>setContainer</code> method must be called, with this Container
1206:             * as an argument.  The method may throw an
1207:             * <code>IllegalArgumentException</code> if this Valve chooses not to
1208:             * be associated with this Container, or <code>IllegalStateException</code>
1209:             * if it is already associated with a different Container.
1210:             *
1211:             * @param valve Valve to be added
1212:             *
1213:             * @exception IllegalArgumentException if this Container refused to
1214:             *  accept the specified Valve
1215:             * @exception IllegalArgumentException if the specifie Valve refuses to be
1216:             *  associated with this Container
1217:             * @exception IllegalStateException if the specified Valve is already
1218:             *  associated with a different Container
1219:             */
1220:            public synchronized void addValve(Valve valve) {
1221:
1222:                pipeline.addValve(valve);
1223:                fireContainerEvent(ADD_VALVE_EVENT, valve);
1224:
1225:            }
1226:
1227:            /**
1228:             * <p>Return the Valve instance that has been distinguished as the basic
1229:             * Valve for this Pipeline (if any).
1230:             */
1231:            public Valve getBasic() {
1232:
1233:                return (pipeline.getBasic());
1234:
1235:            }
1236:
1237:            /**
1238:             * Return the set of Valves in the pipeline associated with this
1239:             * Container, including the basic Valve (if any).  If there are no
1240:             * such Valves, a zero-length array is returned.
1241:             */
1242:            public Valve[] getValves() {
1243:
1244:                return (pipeline.getValves());
1245:
1246:            }
1247:
1248:            /**
1249:             * Remove the specified Valve from the pipeline associated with this
1250:             * Container, if it is found; otherwise, do nothing.
1251:             *
1252:             * @param valve Valve to be removed
1253:             */
1254:            public synchronized void removeValve(Valve valve) {
1255:
1256:                pipeline.removeValve(valve);
1257:                fireContainerEvent(REMOVE_VALVE_EVENT, valve);
1258:
1259:            }
1260:
1261:            /**
1262:             * <p>Set the Valve instance that has been distinguished as the basic
1263:             * Valve for this Pipeline (if any).  Prioer to setting the basic Valve,
1264:             * the Valve's <code>setContainer()</code> will be called, if it
1265:             * implements <code>Contained</code>, with the owning Container as an
1266:             * argument.  The method may throw an <code>IllegalArgumentException</code>
1267:             * if this Valve chooses not to be associated with this Container, or
1268:             * <code>IllegalStateException</code> if it is already associated with
1269:             * a different Container.</p>
1270:             *
1271:             * @param valve Valve to be distinguished as the basic Valve
1272:             */
1273:            public void setBasic(Valve valve) {
1274:
1275:                pipeline.setBasic(valve);
1276:
1277:            }
1278:
1279:            // ------------------------------------------------------ Protected Methods
1280:
1281:            /**
1282:             * Add a default Mapper implementation if none have been configured
1283:             * explicitly.
1284:             *
1285:             * @param mapperClass Java class name of the default Mapper
1286:             */
1287:            protected void addDefaultMapper(String mapperClass) {
1288:
1289:                // Do we need a default Mapper?
1290:                if (mapperClass == null)
1291:                    return;
1292:                if (mappers.size() >= 1)
1293:                    return;
1294:
1295:                // Instantiate and add a default Mapper
1296:                try {
1297:                    Class clazz = Class.forName(mapperClass);
1298:                    Mapper mapper = (Mapper) clazz.newInstance();
1299:                    mapper.setProtocol("http");
1300:                    addMapper(mapper);
1301:                } catch (Exception e) {
1302:                    log(sm.getString("containerBase.addDefaultMapper",
1303:                            mapperClass), e);
1304:                }
1305:
1306:            }
1307:
1308:            /**
1309:             * Notify all container event listeners that a particular event has
1310:             * occurred for this Container.  The default implementation performs
1311:             * this notification synchronously using the calling thread.
1312:             *
1313:             * @param type Event type
1314:             * @param data Event data
1315:             */
1316:            public void fireContainerEvent(String type, Object data) {
1317:
1318:                if (listeners.size() < 1)
1319:                    return;
1320:                ContainerEvent event = new ContainerEvent(this , type, data);
1321:                ContainerListener list[] = new ContainerListener[0];
1322:                synchronized (listeners) {
1323:                    list = (ContainerListener[]) listeners.toArray(list);
1324:                }
1325:                for (int i = 0; i < list.length; i++)
1326:                    ((ContainerListener) list[i]).containerEvent(event);
1327:
1328:            }
1329:
1330:            /**
1331:             * Log the specified message to our current Logger (if any).
1332:             *
1333:             * @param message Message to be logged
1334:             */
1335:            protected void log(String message) {
1336:
1337:                Logger logger = getLogger();
1338:                if (logger != null)
1339:                    logger.log(logName() + ": " + message);
1340:                else
1341:                    System.out.println(logName() + ": " + message);
1342:
1343:            }
1344:
1345:            /**
1346:             * Log the specified message and exception to our current Logger
1347:             * (if any).
1348:             *
1349:             * @param message Message to be logged
1350:             * @param throwable Related exception
1351:             */
1352:            protected void log(String message, Throwable throwable) {
1353:
1354:                Logger logger = getLogger();
1355:                if (logger != null)
1356:                    logger.log(logName() + ": " + message, throwable);
1357:                else {
1358:                    System.out.println(logName() + ": " + message + ": "
1359:                            + throwable);
1360:                    throwable.printStackTrace(System.out);
1361:                }
1362:
1363:            }
1364:
1365:            /**
1366:             * Return the abbreviated name of this container for logging messsages
1367:             */
1368:            protected String logName() {
1369:
1370:                String className = this .getClass().getName();
1371:                int period = className.lastIndexOf(".");
1372:                if (period >= 0)
1373:                    className = className.substring(period + 1);
1374:                return (className + "[" + getName() + "]");
1375:
1376:            }
1377:
1378:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.