Source Code Cross Referenced for ContainerBase.java in  » Sevlet-Container » apache-tomcat-6.0.14 » 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 » Sevlet Container » apache tomcat 6.0.14 » org.apache.catalina.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.catalina.core;
0019:
0020:        import java.beans.PropertyChangeListener;
0021:        import java.beans.PropertyChangeSupport;
0022:        import java.io.IOException;
0023:        import java.io.Serializable;
0024:        import java.security.AccessController;
0025:        import java.security.PrivilegedAction;
0026:        import java.util.ArrayList;
0027:        import java.util.HashMap;
0028:        import java.util.Hashtable;
0029:        import java.util.Iterator;
0030:
0031:        import javax.management.MBeanRegistration;
0032:        import javax.management.MBeanServer;
0033:        import javax.management.MalformedObjectNameException;
0034:        import javax.management.ObjectName;
0035:        import javax.naming.directory.DirContext;
0036:        import javax.servlet.ServletException;
0037:
0038:        import org.apache.catalina.Cluster;
0039:        import org.apache.catalina.Container;
0040:        import org.apache.catalina.ContainerEvent;
0041:        import org.apache.catalina.ContainerListener;
0042:        import org.apache.catalina.Globals;
0043:        import org.apache.catalina.Lifecycle;
0044:        import org.apache.catalina.LifecycleException;
0045:        import org.apache.catalina.LifecycleListener;
0046:        import org.apache.catalina.Loader;
0047:        import org.apache.catalina.Manager;
0048:        import org.apache.catalina.Pipeline;
0049:        import org.apache.catalina.Realm;
0050:        import org.apache.catalina.Valve;
0051:        import org.apache.catalina.connector.Request;
0052:        import org.apache.catalina.connector.Response;
0053:        import org.apache.catalina.util.LifecycleSupport;
0054:        import org.apache.catalina.util.StringManager;
0055:        import org.apache.juli.logging.Log;
0056:        import org.apache.juli.logging.LogFactory;
0057:        import org.apache.naming.resources.ProxyDirContext;
0058:        import org.apache.tomcat.util.modeler.Registry;
0059:
0060:        /**
0061:         * Abstract implementation of the <b>Container</b> interface, providing common
0062:         * functionality required by nearly every implementation.  Classes extending
0063:         * this base class must implement <code>getInfo()</code>, and may implement
0064:         * a replacement for <code>invoke()</code>.
0065:         * <p>
0066:         * All subclasses of this abstract base class will include support for a
0067:         * Pipeline object that defines the processing to be performed for each request
0068:         * received by the <code>invoke()</code> method of this class, utilizing the
0069:         * "Chain of Responsibility" design pattern.  A subclass should encapsulate its
0070:         * own processing functionality as a <code>Valve</code>, and configure this
0071:         * Valve into the pipeline by calling <code>setBasic()</code>.
0072:         * <p>
0073:         * This implementation fires property change events, per the JavaBeans design
0074:         * pattern, for changes in singleton properties.  In addition, it fires the
0075:         * following <code>ContainerEvent</code> events to listeners who register
0076:         * themselves with <code>addContainerListener()</code>:
0077:         * <table border=1>
0078:         *   <tr>
0079:         *     <th>Type</th>
0080:         *     <th>Data</th>
0081:         *     <th>Description</th>
0082:         *   </tr>
0083:         *   <tr>
0084:         *     <td align=center><code>addChild</code></td>
0085:         *     <td align=center><code>Container</code></td>
0086:         *     <td>Child container added to this Container.</td>
0087:         *   </tr>
0088:         *   <tr>
0089:         *     <td align=center><code>addValve</code></td>
0090:         *     <td align=center><code>Valve</code></td>
0091:         *     <td>Valve added to this Container.</td>
0092:         *   </tr>
0093:         *   <tr>
0094:         *     <td align=center><code>removeChild</code></td>
0095:         *     <td align=center><code>Container</code></td>
0096:         *     <td>Child container removed from this Container.</td>
0097:         *   </tr>
0098:         *   <tr>
0099:         *     <td align=center><code>removeValve</code></td>
0100:         *     <td align=center><code>Valve</code></td>
0101:         *     <td>Valve removed from this Container.</td>
0102:         *   </tr>
0103:         *   <tr>
0104:         *     <td align=center><code>start</code></td>
0105:         *     <td align=center><code>null</code></td>
0106:         *     <td>Container was started.</td>
0107:         *   </tr>
0108:         *   <tr>
0109:         *     <td align=center><code>stop</code></td>
0110:         *     <td align=center><code>null</code></td>
0111:         *     <td>Container was stopped.</td>
0112:         *   </tr>
0113:         * </table>
0114:         * Subclasses that fire additional events should document them in the
0115:         * class comments of the implementation class.
0116:         *
0117:         * @author Craig R. McClanahan
0118:         */
0119:
0120:        public abstract class ContainerBase implements  Container, Lifecycle,
0121:                Pipeline, MBeanRegistration, Serializable {
0122:
0123:            private static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
0124:                    .getLog(ContainerBase.class);
0125:
0126:            /**
0127:             * Perform addChild with the permissions of this class.
0128:             * addChild can be called with the XML parser on the stack,
0129:             * this allows the XML parser to have fewer privileges than
0130:             * Tomcat.
0131:             */
0132:            protected class PrivilegedAddChild implements  PrivilegedAction {
0133:
0134:                private Container child;
0135:
0136:                PrivilegedAddChild(Container child) {
0137:                    this .child = child;
0138:                }
0139:
0140:                public Object run() {
0141:                    addChildInternal(child);
0142:                    return null;
0143:                }
0144:
0145:            }
0146:
0147:            // ----------------------------------------------------- Instance Variables
0148:
0149:            /**
0150:             * The child Containers belonging to this Container, keyed by name.
0151:             */
0152:            protected HashMap children = new HashMap();
0153:
0154:            /**
0155:             * The processor delay for this component.
0156:             */
0157:            protected int backgroundProcessorDelay = -1;
0158:
0159:            /**
0160:             * The lifecycle event support for this component.
0161:             */
0162:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0163:
0164:            /**
0165:             * The container event listeners for this Container.
0166:             */
0167:            protected ArrayList listeners = new ArrayList();
0168:
0169:            /**
0170:             * The Loader implementation with which this Container is associated.
0171:             */
0172:            protected Loader loader = null;
0173:
0174:            /**
0175:             * The Logger implementation with which this Container is associated.
0176:             */
0177:            protected Log logger = null;
0178:
0179:            /**
0180:             * Associated logger name.
0181:             */
0182:            protected String logName = null;
0183:
0184:            /**
0185:             * The Manager implementation with which this Container is associated.
0186:             */
0187:            protected Manager manager = null;
0188:
0189:            /**
0190:             * The cluster with which this Container is associated.
0191:             */
0192:            protected Cluster cluster = null;
0193:
0194:            /**
0195:             * The human-readable name of this Container.
0196:             */
0197:            protected String name = null;
0198:
0199:            /**
0200:             * The parent Container to which this Container is a child.
0201:             */
0202:            protected Container parent = null;
0203:
0204:            /**
0205:             * The parent class loader to be configured when we install a Loader.
0206:             */
0207:            protected ClassLoader parentClassLoader = null;
0208:
0209:            /**
0210:             * The Pipeline object with which this Container is associated.
0211:             */
0212:            protected Pipeline pipeline = new StandardPipeline(this );
0213:
0214:            /**
0215:             * The Realm with which this Container is associated.
0216:             */
0217:            protected Realm realm = null;
0218:
0219:            /**
0220:             * The resources DirContext object with which this Container is associated.
0221:             */
0222:            protected DirContext resources = null;
0223:
0224:            /**
0225:             * The string manager for this package.
0226:             */
0227:            protected static StringManager sm = StringManager
0228:                    .getManager(Constants.Package);
0229:
0230:            /**
0231:             * Has this component been started?
0232:             */
0233:            protected boolean started = false;
0234:
0235:            protected boolean initialized = false;
0236:
0237:            /**
0238:             * Will children be started automatically when they are added.
0239:             */
0240:            protected boolean startChildren = true;
0241:
0242:            /**
0243:             * The property change support for this component.
0244:             */
0245:            protected PropertyChangeSupport support = new PropertyChangeSupport(
0246:                    this );
0247:
0248:            /**
0249:             * The background thread.
0250:             */
0251:            private Thread thread = null;
0252:
0253:            /**
0254:             * The background thread completion semaphore.
0255:             */
0256:            private boolean threadDone = false;
0257:
0258:            // ------------------------------------------------------------- Properties
0259:
0260:            /**
0261:             * Get the delay between the invocation of the backgroundProcess method on
0262:             * this container and its children. Child containers will not be invoked
0263:             * if their delay value is not negative (which would mean they are using 
0264:             * their own thread). Setting this to a positive value will cause 
0265:             * a thread to be spawn. After waiting the specified amount of time, 
0266:             * the thread will invoke the executePeriodic method on this container 
0267:             * and all its children.
0268:             */
0269:            public int getBackgroundProcessorDelay() {
0270:                return backgroundProcessorDelay;
0271:            }
0272:
0273:            /**
0274:             * Set the delay between the invocation of the execute method on this
0275:             * container and its children.
0276:             * 
0277:             * @param delay The delay in seconds between the invocation of 
0278:             *              backgroundProcess methods
0279:             */
0280:            public void setBackgroundProcessorDelay(int delay) {
0281:                backgroundProcessorDelay = delay;
0282:            }
0283:
0284:            /**
0285:             * Return descriptive information about this Container implementation and
0286:             * the corresponding version number, in the format
0287:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0288:             */
0289:            public String getInfo() {
0290:                return this .getClass().getName();
0291:            }
0292:
0293:            /**
0294:             * Return the Loader with which this Container is associated.  If there is
0295:             * no associated Loader, return the Loader associated with our parent
0296:             * Container (if any); otherwise, return <code>null</code>.
0297:             */
0298:            public Loader getLoader() {
0299:
0300:                if (loader != null)
0301:                    return (loader);
0302:                if (parent != null)
0303:                    return (parent.getLoader());
0304:                return (null);
0305:
0306:            }
0307:
0308:            /**
0309:             * Set the Loader with which this Container is associated.
0310:             *
0311:             * @param loader The newly associated loader
0312:             */
0313:            public synchronized void setLoader(Loader loader) {
0314:
0315:                // Change components if necessary
0316:                Loader oldLoader = this .loader;
0317:                if (oldLoader == loader)
0318:                    return;
0319:                this .loader = loader;
0320:
0321:                // Stop the old component if necessary
0322:                if (started && (oldLoader != null)
0323:                        && (oldLoader instanceof  Lifecycle)) {
0324:                    try {
0325:                        ((Lifecycle) oldLoader).stop();
0326:                    } catch (LifecycleException e) {
0327:                        log.error("ContainerBase.setLoader: stop: ", e);
0328:                    }
0329:                }
0330:
0331:                // Start the new component if necessary
0332:                if (loader != null)
0333:                    loader.setContainer(this );
0334:                if (started && (loader != null)
0335:                        && (loader instanceof  Lifecycle)) {
0336:                    try {
0337:                        ((Lifecycle) loader).start();
0338:                    } catch (LifecycleException e) {
0339:                        log.error("ContainerBase.setLoader: start: ", e);
0340:                    }
0341:                }
0342:
0343:                // Report this property change to interested listeners
0344:                support.firePropertyChange("loader", oldLoader, this .loader);
0345:
0346:            }
0347:
0348:            /**
0349:             * Return the Logger with which this Container is associated.  If there is
0350:             * no associated Logger, return the Logger associated with our parent
0351:             * Container (if any); otherwise return <code>null</code>.
0352:             */
0353:            public Log getLogger() {
0354:
0355:                if (logger != null)
0356:                    return (logger);
0357:                logger = LogFactory.getLog(logName());
0358:                return (logger);
0359:
0360:            }
0361:
0362:            /**
0363:             * Return the Manager with which this Container is associated.  If there is
0364:             * no associated Manager, return the Manager associated with our parent
0365:             * Container (if any); otherwise return <code>null</code>.
0366:             */
0367:            public Manager getManager() {
0368:
0369:                if (manager != null)
0370:                    return (manager);
0371:                if (parent != null)
0372:                    return (parent.getManager());
0373:                return (null);
0374:
0375:            }
0376:
0377:            /**
0378:             * Set the Manager with which this Container is associated.
0379:             *
0380:             * @param manager The newly associated Manager
0381:             */
0382:            public synchronized void setManager(Manager manager) {
0383:
0384:                // Change components if necessary
0385:                Manager oldManager = this .manager;
0386:                if (oldManager == manager)
0387:                    return;
0388:                this .manager = manager;
0389:
0390:                // Stop the old component if necessary
0391:                if (started && (oldManager != null)
0392:                        && (oldManager instanceof  Lifecycle)) {
0393:                    try {
0394:                        ((Lifecycle) oldManager).stop();
0395:                    } catch (LifecycleException e) {
0396:                        log.error("ContainerBase.setManager: stop: ", e);
0397:                    }
0398:                }
0399:
0400:                // Start the new component if necessary
0401:                if (manager != null)
0402:                    manager.setContainer(this );
0403:                if (started && (manager != null)
0404:                        && (manager instanceof  Lifecycle)) {
0405:                    try {
0406:                        ((Lifecycle) manager).start();
0407:                    } catch (LifecycleException e) {
0408:                        log.error("ContainerBase.setManager: start: ", e);
0409:                    }
0410:                }
0411:
0412:                // Report this property change to interested listeners
0413:                support.firePropertyChange("manager", oldManager, this .manager);
0414:
0415:            }
0416:
0417:            /**
0418:             * Return an object which may be utilized for mapping to this component.
0419:             */
0420:            public Object getMappingObject() {
0421:                return this ;
0422:            }
0423:
0424:            /**
0425:             * Return the Cluster with which this Container is associated.  If there is
0426:             * no associated Cluster, return the Cluster associated with our parent
0427:             * Container (if any); otherwise return <code>null</code>.
0428:             */
0429:            public Cluster getCluster() {
0430:                if (cluster != null)
0431:                    return (cluster);
0432:
0433:                if (parent != null)
0434:                    return (parent.getCluster());
0435:
0436:                return (null);
0437:            }
0438:
0439:            /**
0440:             * Set the Cluster with which this Container is associated.
0441:             *
0442:             * @param cluster The newly associated Cluster
0443:             */
0444:            public synchronized void setCluster(Cluster cluster) {
0445:                // Change components if necessary
0446:                Cluster oldCluster = this .cluster;
0447:                if (oldCluster == cluster)
0448:                    return;
0449:                this .cluster = cluster;
0450:
0451:                // Stop the old component if necessary
0452:                if (started && (oldCluster != null)
0453:                        && (oldCluster instanceof  Lifecycle)) {
0454:                    try {
0455:                        ((Lifecycle) oldCluster).stop();
0456:                    } catch (LifecycleException e) {
0457:                        log.error("ContainerBase.setCluster: stop: ", e);
0458:                    }
0459:                }
0460:
0461:                // Start the new component if necessary
0462:                if (cluster != null)
0463:                    cluster.setContainer(this );
0464:
0465:                if (started && (cluster != null)
0466:                        && (cluster instanceof  Lifecycle)) {
0467:                    try {
0468:                        ((Lifecycle) cluster).start();
0469:                    } catch (LifecycleException e) {
0470:                        log.error("ContainerBase.setCluster: start: ", e);
0471:                    }
0472:                }
0473:
0474:                // Report this property change to interested listeners
0475:                support.firePropertyChange("cluster", oldCluster, this .cluster);
0476:            }
0477:
0478:            /**
0479:             * Return a name string (suitable for use by humans) that describes this
0480:             * Container.  Within the set of child containers belonging to a particular
0481:             * parent, Container names must be unique.
0482:             */
0483:            public String getName() {
0484:
0485:                return (name);
0486:
0487:            }
0488:
0489:            /**
0490:             * Set a name string (suitable for use by humans) that describes this
0491:             * Container.  Within the set of child containers belonging to a particular
0492:             * parent, Container names must be unique.
0493:             *
0494:             * @param name New name of this container
0495:             *
0496:             * @exception IllegalStateException if this Container has already been
0497:             *  added to the children of a parent Container (after which the name
0498:             *  may not be changed)
0499:             */
0500:            public void setName(String name) {
0501:
0502:                String oldName = this .name;
0503:                this .name = name;
0504:                support.firePropertyChange("name", oldName, this .name);
0505:            }
0506:
0507:            /**
0508:             * Return if children of this container will be started automatically when
0509:             * they are added to this container.
0510:             */
0511:            public boolean getStartChildren() {
0512:
0513:                return (startChildren);
0514:
0515:            }
0516:
0517:            /**
0518:             * Set if children of this container will be started automatically when
0519:             * they are added to this container.
0520:             *
0521:             * @param startChildren New value of the startChildren flag
0522:             */
0523:            public void setStartChildren(boolean startChildren) {
0524:
0525:                boolean oldStartChildren = this .startChildren;
0526:                this .startChildren = startChildren;
0527:                support.firePropertyChange("startChildren", oldStartChildren,
0528:                        this .startChildren);
0529:            }
0530:
0531:            /**
0532:             * Return the Container for which this Container is a child, if there is
0533:             * one.  If there is no defined parent, return <code>null</code>.
0534:             */
0535:            public Container getParent() {
0536:
0537:                return (parent);
0538:
0539:            }
0540:
0541:            /**
0542:             * Set the parent Container to which this Container is being added as a
0543:             * child.  This Container may refuse to become attached to the specified
0544:             * Container by throwing an exception.
0545:             *
0546:             * @param container Container to which this Container is being added
0547:             *  as a child
0548:             *
0549:             * @exception IllegalArgumentException if this Container refuses to become
0550:             *  attached to the specified Container
0551:             */
0552:            public void setParent(Container container) {
0553:
0554:                Container oldParent = this .parent;
0555:                this .parent = container;
0556:                support.firePropertyChange("parent", oldParent, this .parent);
0557:
0558:            }
0559:
0560:            /**
0561:             * Return the parent class loader (if any) for this web application.
0562:             * This call is meaningful only <strong>after</strong> a Loader has
0563:             * been configured.
0564:             */
0565:            public ClassLoader getParentClassLoader() {
0566:                if (parentClassLoader != null)
0567:                    return (parentClassLoader);
0568:                if (parent != null) {
0569:                    return (parent.getParentClassLoader());
0570:                }
0571:                return (ClassLoader.getSystemClassLoader());
0572:
0573:            }
0574:
0575:            /**
0576:             * Set the parent class loader (if any) for this web application.
0577:             * This call is meaningful only <strong>before</strong> a Loader has
0578:             * been configured, and the specified value (if non-null) should be
0579:             * passed as an argument to the class loader constructor.
0580:             *
0581:             *
0582:             * @param parent The new parent class loader
0583:             */
0584:            public void setParentClassLoader(ClassLoader parent) {
0585:                ClassLoader oldParentClassLoader = this .parentClassLoader;
0586:                this .parentClassLoader = parent;
0587:                support.firePropertyChange("parentClassLoader",
0588:                        oldParentClassLoader, this .parentClassLoader);
0589:
0590:            }
0591:
0592:            /**
0593:             * Return the Pipeline object that manages the Valves associated with
0594:             * this Container.
0595:             */
0596:            public Pipeline getPipeline() {
0597:
0598:                return (this .pipeline);
0599:
0600:            }
0601:
0602:            /**
0603:             * Return the Realm with which this Container is associated.  If there is
0604:             * no associated Realm, return the Realm associated with our parent
0605:             * Container (if any); otherwise return <code>null</code>.
0606:             */
0607:            public Realm getRealm() {
0608:
0609:                if (realm != null)
0610:                    return (realm);
0611:                if (parent != null)
0612:                    return (parent.getRealm());
0613:                return (null);
0614:
0615:            }
0616:
0617:            /**
0618:             * Set the Realm with which this Container is associated.
0619:             *
0620:             * @param realm The newly associated Realm
0621:             */
0622:            public synchronized void setRealm(Realm realm) {
0623:
0624:                // Change components if necessary
0625:                Realm oldRealm = this .realm;
0626:                if (oldRealm == realm)
0627:                    return;
0628:                this .realm = realm;
0629:
0630:                // Stop the old component if necessary
0631:                if (started && (oldRealm != null)
0632:                        && (oldRealm instanceof  Lifecycle)) {
0633:                    try {
0634:                        ((Lifecycle) oldRealm).stop();
0635:                    } catch (LifecycleException e) {
0636:                        log.error("ContainerBase.setRealm: stop: ", e);
0637:                    }
0638:                }
0639:
0640:                // Start the new component if necessary
0641:                if (realm != null)
0642:                    realm.setContainer(this );
0643:                if (started && (realm != null) && (realm instanceof  Lifecycle)) {
0644:                    try {
0645:                        ((Lifecycle) realm).start();
0646:                    } catch (LifecycleException e) {
0647:                        log.error("ContainerBase.setRealm: start: ", e);
0648:                    }
0649:                }
0650:
0651:                // Report this property change to interested listeners
0652:                support.firePropertyChange("realm", oldRealm, this .realm);
0653:
0654:            }
0655:
0656:            /**
0657:             * Return the resources DirContext object with which this Container is
0658:             * associated.  If there is no associated resources object, return the
0659:             * resources associated with our parent Container (if any); otherwise
0660:             * return <code>null</code>.
0661:             */
0662:            public DirContext getResources() {
0663:                if (resources != null)
0664:                    return (resources);
0665:                if (parent != null)
0666:                    return (parent.getResources());
0667:                return (null);
0668:
0669:            }
0670:
0671:            /**
0672:             * Set the resources DirContext object with which this Container is
0673:             * associated.
0674:             *
0675:             * @param resources The newly associated DirContext
0676:             */
0677:            public synchronized void setResources(DirContext resources) {
0678:                // Called from StandardContext.setResources()
0679:                //              <- StandardContext.start() 
0680:                //              <- ContainerBase.addChildInternal() 
0681:
0682:                // Change components if necessary
0683:                DirContext oldResources = this .resources;
0684:                if (oldResources == resources)
0685:                    return;
0686:                Hashtable env = new Hashtable();
0687:                if (getParent() != null)
0688:                    env.put(ProxyDirContext.HOST, getParent().getName());
0689:                env.put(ProxyDirContext.CONTEXT, getName());
0690:                this .resources = new ProxyDirContext(env, resources);
0691:                // Report this property change to interested listeners
0692:                support.firePropertyChange("resources", oldResources,
0693:                        this .resources);
0694:
0695:            }
0696:
0697:            // ------------------------------------------------------ Container Methods
0698:
0699:            /**
0700:             * Add a new child Container to those associated with this Container,
0701:             * if supported.  Prior to adding this Container to the set of children,
0702:             * the child's <code>setParent()</code> method must be called, with this
0703:             * Container as an argument.  This method may thrown an
0704:             * <code>IllegalArgumentException</code> if this Container chooses not
0705:             * to be attached to the specified Container, in which case it is not added
0706:             *
0707:             * @param child New child Container to be added
0708:             *
0709:             * @exception IllegalArgumentException if this exception is thrown by
0710:             *  the <code>setParent()</code> method of the child Container
0711:             * @exception IllegalArgumentException if the new child does not have
0712:             *  a name unique from that of existing children of this Container
0713:             * @exception IllegalStateException if this Container does not support
0714:             *  child Containers
0715:             */
0716:            public void addChild(Container child) {
0717:                if (Globals.IS_SECURITY_ENABLED) {
0718:                    PrivilegedAction dp = new PrivilegedAddChild(child);
0719:                    AccessController.doPrivileged(dp);
0720:                } else {
0721:                    addChildInternal(child);
0722:                }
0723:            }
0724:
0725:            private void addChildInternal(Container child) {
0726:
0727:                if (log.isDebugEnabled())
0728:                    log.debug("Add child " + child + " " + this );
0729:                synchronized (children) {
0730:                    if (children.get(child.getName()) != null)
0731:                        throw new IllegalArgumentException(
0732:                                "addChild:  Child name '" + child.getName()
0733:                                        + "' is not unique");
0734:                    child.setParent(this ); // May throw IAE
0735:                    children.put(child.getName(), child);
0736:
0737:                    // Start child
0738:                    if (started && startChildren
0739:                            && (child instanceof  Lifecycle)) {
0740:                        boolean success = false;
0741:                        try {
0742:                            ((Lifecycle) child).start();
0743:                            success = true;
0744:                        } catch (LifecycleException e) {
0745:                            log.error("ContainerBase.addChild: start: ", e);
0746:                            throw new IllegalStateException(
0747:                                    "ContainerBase.addChild: start: " + e);
0748:                        } finally {
0749:                            if (!success) {
0750:                                children.remove(child.getName());
0751:                            }
0752:                        }
0753:                    }
0754:
0755:                    fireContainerEvent(ADD_CHILD_EVENT, child);
0756:                }
0757:
0758:            }
0759:
0760:            /**
0761:             * Add a container event listener to this component.
0762:             *
0763:             * @param listener The listener to add
0764:             */
0765:            public void addContainerListener(ContainerListener listener) {
0766:
0767:                synchronized (listeners) {
0768:                    listeners.add(listener);
0769:                }
0770:
0771:            }
0772:
0773:            /**
0774:             * Add a property change listener to this component.
0775:             *
0776:             * @param listener The listener to add
0777:             */
0778:            public void addPropertyChangeListener(
0779:                    PropertyChangeListener listener) {
0780:
0781:                support.addPropertyChangeListener(listener);
0782:
0783:            }
0784:
0785:            /**
0786:             * Return the child Container, associated with this Container, with
0787:             * the specified name (if any); otherwise, return <code>null</code>
0788:             *
0789:             * @param name Name of the child Container to be retrieved
0790:             */
0791:            public Container findChild(String name) {
0792:
0793:                if (name == null)
0794:                    return (null);
0795:                synchronized (children) { // Required by post-start changes
0796:                    return ((Container) children.get(name));
0797:                }
0798:
0799:            }
0800:
0801:            /**
0802:             * Return the set of children Containers associated with this Container.
0803:             * If this Container has no children, a zero-length array is returned.
0804:             */
0805:            public Container[] findChildren() {
0806:
0807:                synchronized (children) {
0808:                    Container results[] = new Container[children.size()];
0809:                    return ((Container[]) children.values().toArray(results));
0810:                }
0811:
0812:            }
0813:
0814:            /**
0815:             * Return the set of container listeners associated with this Container.
0816:             * If this Container has no registered container listeners, a zero-length
0817:             * array is returned.
0818:             */
0819:            public ContainerListener[] findContainerListeners() {
0820:
0821:                synchronized (listeners) {
0822:                    ContainerListener[] results = new ContainerListener[listeners
0823:                            .size()];
0824:                    return ((ContainerListener[]) listeners.toArray(results));
0825:                }
0826:
0827:            }
0828:
0829:            /**
0830:             * Process the specified Request, to produce the corresponding Response,
0831:             * by invoking the first Valve in our pipeline (if any), or the basic
0832:             * Valve otherwise.
0833:             *
0834:             * @param request Request to be processed
0835:             * @param response Response to be produced
0836:             *
0837:             * @exception IllegalStateException if neither a pipeline or a basic
0838:             *  Valve have been configured for this Container
0839:             * @exception IOException if an input/output error occurred while
0840:             *  processing
0841:             * @exception ServletException if a ServletException was thrown
0842:             *  while processing this request
0843:             */
0844:            public void invoke(Request request, Response response)
0845:                    throws IOException, ServletException {
0846:
0847:                pipeline.getFirst().invoke(request, response);
0848:
0849:            }
0850:
0851:            /**
0852:             * Remove an existing child Container from association with this parent
0853:             * Container.
0854:             *
0855:             * @param child Existing child Container to be removed
0856:             */
0857:            public void removeChild(Container child) {
0858:
0859:                synchronized (children) {
0860:                    if (children.get(child.getName()) == null)
0861:                        return;
0862:                    children.remove(child.getName());
0863:                }
0864:
0865:                if (started && (child instanceof  Lifecycle)) {
0866:                    try {
0867:                        if (child instanceof  ContainerBase) {
0868:                            if (((ContainerBase) child).started) {
0869:                                ((Lifecycle) child).stop();
0870:                            }
0871:                        } else {
0872:                            ((Lifecycle) child).stop();
0873:                        }
0874:                    } catch (LifecycleException e) {
0875:                        log.error("ContainerBase.removeChild: stop: ", e);
0876:                    }
0877:                }
0878:
0879:                fireContainerEvent(REMOVE_CHILD_EVENT, child);
0880:
0881:                // child.setParent(null);
0882:
0883:            }
0884:
0885:            /**
0886:             * Remove a container event listener from this component.
0887:             *
0888:             * @param listener The listener to remove
0889:             */
0890:            public void removeContainerListener(ContainerListener listener) {
0891:
0892:                synchronized (listeners) {
0893:                    listeners.remove(listener);
0894:                }
0895:
0896:            }
0897:
0898:            /**
0899:             * Remove a property change listener from this component.
0900:             *
0901:             * @param listener The listener to remove
0902:             */
0903:            public void removePropertyChangeListener(
0904:                    PropertyChangeListener listener) {
0905:
0906:                support.removePropertyChangeListener(listener);
0907:
0908:            }
0909:
0910:            // ------------------------------------------------------ Lifecycle Methods
0911:
0912:            /**
0913:             * Add a lifecycle event listener to this component.
0914:             *
0915:             * @param listener The listener to add
0916:             */
0917:            public void addLifecycleListener(LifecycleListener listener) {
0918:
0919:                lifecycle.addLifecycleListener(listener);
0920:
0921:            }
0922:
0923:            /**
0924:             * Get the lifecycle listeners associated with this lifecycle. If this 
0925:             * Lifecycle has no listeners registered, a zero-length array is returned.
0926:             */
0927:            public LifecycleListener[] findLifecycleListeners() {
0928:
0929:                return lifecycle.findLifecycleListeners();
0930:
0931:            }
0932:
0933:            /**
0934:             * Remove a lifecycle event listener from this component.
0935:             *
0936:             * @param listener The listener to remove
0937:             */
0938:            public void removeLifecycleListener(LifecycleListener listener) {
0939:
0940:                lifecycle.removeLifecycleListener(listener);
0941:
0942:            }
0943:
0944:            /**
0945:             * Prepare for active use of the public methods of this Component.
0946:             *
0947:             * @exception LifecycleException if this component detects a fatal error
0948:             *  that prevents it from being started
0949:             */
0950:            public synchronized void start() throws LifecycleException {
0951:
0952:                // Validate and update our current component state
0953:                if (started) {
0954:                    if (log.isInfoEnabled())
0955:                        log.info(sm.getString("containerBase.alreadyStarted",
0956:                                logName()));
0957:                    return;
0958:                }
0959:
0960:                // Notify our interested LifecycleListeners
0961:                lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
0962:
0963:                started = true;
0964:
0965:                // Start our subordinate components, if any
0966:                if ((loader != null) && (loader instanceof  Lifecycle))
0967:                    ((Lifecycle) loader).start();
0968:                logger = null;
0969:                getLogger();
0970:                if ((logger != null) && (logger instanceof  Lifecycle))
0971:                    ((Lifecycle) logger).start();
0972:                if ((manager != null) && (manager instanceof  Lifecycle))
0973:                    ((Lifecycle) manager).start();
0974:                if ((cluster != null) && (cluster instanceof  Lifecycle))
0975:                    ((Lifecycle) cluster).start();
0976:                if ((realm != null) && (realm instanceof  Lifecycle))
0977:                    ((Lifecycle) realm).start();
0978:                if ((resources != null) && (resources instanceof  Lifecycle))
0979:                    ((Lifecycle) resources).start();
0980:
0981:                // Start our child containers, if any
0982:                Container children[] = findChildren();
0983:                for (int i = 0; i < children.length; i++) {
0984:                    if (children[i] instanceof  Lifecycle)
0985:                        ((Lifecycle) children[i]).start();
0986:                }
0987:
0988:                // Start the Valves in our pipeline (including the basic), if any
0989:                if (pipeline instanceof  Lifecycle)
0990:                    ((Lifecycle) pipeline).start();
0991:
0992:                // Notify our interested LifecycleListeners
0993:                lifecycle.fireLifecycleEvent(START_EVENT, null);
0994:
0995:                // Start our thread
0996:                threadStart();
0997:
0998:                // Notify our interested LifecycleListeners
0999:                lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
1000:
1001:            }
1002:
1003:            /**
1004:             * Gracefully shut down active use of the public methods of this Component.
1005:             *
1006:             * @exception LifecycleException if this component detects a fatal error
1007:             *  that needs to be reported
1008:             */
1009:            public synchronized void stop() throws LifecycleException {
1010:
1011:                // Validate and update our current component state
1012:                if (!started) {
1013:                    if (log.isInfoEnabled())
1014:                        log.info(sm.getString("containerBase.notStarted",
1015:                                logName()));
1016:                    return;
1017:                }
1018:
1019:                // Notify our interested LifecycleListeners
1020:                lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
1021:
1022:                // Stop our thread
1023:                threadStop();
1024:
1025:                // Notify our interested LifecycleListeners
1026:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
1027:                started = false;
1028:
1029:                // Stop the Valves in our pipeline (including the basic), if any
1030:                if (pipeline instanceof  Lifecycle) {
1031:                    ((Lifecycle) pipeline).stop();
1032:                }
1033:
1034:                // Stop our child containers, if any
1035:                Container children[] = findChildren();
1036:                for (int i = 0; i < children.length; i++) {
1037:                    if (children[i] instanceof  Lifecycle)
1038:                        ((Lifecycle) children[i]).stop();
1039:                }
1040:                // Remove children - so next start can work
1041:                children = findChildren();
1042:                for (int i = 0; i < children.length; i++) {
1043:                    removeChild(children[i]);
1044:                }
1045:
1046:                // Stop our subordinate components, if any
1047:                if ((resources != null) && (resources instanceof  Lifecycle)) {
1048:                    ((Lifecycle) resources).stop();
1049:                }
1050:                if ((realm != null) && (realm instanceof  Lifecycle)) {
1051:                    ((Lifecycle) realm).stop();
1052:                }
1053:                if ((cluster != null) && (cluster instanceof  Lifecycle)) {
1054:                    ((Lifecycle) cluster).stop();
1055:                }
1056:                if ((manager != null) && (manager instanceof  Lifecycle)) {
1057:                    ((Lifecycle) manager).stop();
1058:                }
1059:                if ((logger != null) && (logger instanceof  Lifecycle)) {
1060:                    ((Lifecycle) logger).stop();
1061:                }
1062:                if ((loader != null) && (loader instanceof  Lifecycle)) {
1063:                    ((Lifecycle) loader).stop();
1064:                }
1065:
1066:                // Notify our interested LifecycleListeners
1067:                lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
1068:
1069:            }
1070:
1071:            /** Init method, part of the MBean lifecycle.
1072:             *  If the container was added via JMX, it'll register itself with the 
1073:             * parent, using the ObjectName conventions to locate the parent.
1074:             * 
1075:             *  If the container was added directly and it doesn't have an ObjectName,
1076:             * it'll create a name and register itself with the JMX console. On destroy(), 
1077:             * the object will unregister.
1078:             * 
1079:             * @throws Exception
1080:             */
1081:            public void init() throws Exception {
1082:
1083:                if (this .getParent() == null) {
1084:                    // "Life" update
1085:                    ObjectName parentName = getParentName();
1086:
1087:                    //log.info("Register " + parentName );
1088:                    if (parentName != null && mserver.isRegistered(parentName)) {
1089:                        mserver
1090:                                .invoke(
1091:                                        parentName,
1092:                                        "addChild",
1093:                                        new Object[] { this  },
1094:                                        new String[] { "org.apache.catalina.Container" });
1095:                    }
1096:                }
1097:                initialized = true;
1098:            }
1099:
1100:            public ObjectName getParentName()
1101:                    throws MalformedObjectNameException {
1102:                return null;
1103:            }
1104:
1105:            public void destroy() throws Exception {
1106:                if (started) {
1107:                    stop();
1108:                }
1109:                initialized = false;
1110:
1111:                // unregister this component
1112:                if (oname != null) {
1113:                    try {
1114:                        if (controller == oname) {
1115:                            Registry.getRegistry(null, null)
1116:                                    .unregisterComponent(oname);
1117:                            if (log.isDebugEnabled())
1118:                                log.debug("unregistering " + oname);
1119:                        }
1120:                    } catch (Throwable t) {
1121:                        log.error("Error unregistering ", t);
1122:                    }
1123:                }
1124:
1125:                if (parent != null) {
1126:                    parent.removeChild(this );
1127:                }
1128:
1129:                // Stop our child containers, if any
1130:                Container children[] = findChildren();
1131:                for (int i = 0; i < children.length; i++) {
1132:                    removeChild(children[i]);
1133:                }
1134:
1135:            }
1136:
1137:            // ------------------------------------------------------- Pipeline Methods
1138:
1139:            /**
1140:             * Add a new Valve to the end of the pipeline associated with this
1141:             * Container.  Prior to adding the Valve, the Valve's
1142:             * <code>setContainer</code> method must be called, with this Container
1143:             * as an argument.  The method may throw an
1144:             * <code>IllegalArgumentException</code> if this Valve chooses not to
1145:             * be associated with this Container, or <code>IllegalStateException</code>
1146:             * if it is already associated with a different Container.
1147:             *
1148:             * @param valve Valve to be added
1149:             *
1150:             * @exception IllegalArgumentException if this Container refused to
1151:             *  accept the specified Valve
1152:             * @exception IllegalArgumentException if the specifie Valve refuses to be
1153:             *  associated with this Container
1154:             * @exception IllegalStateException if the specified Valve is already
1155:             *  associated with a different Container
1156:             */
1157:            public synchronized void addValve(Valve valve) {
1158:
1159:                pipeline.addValve(valve);
1160:                fireContainerEvent(ADD_VALVE_EVENT, valve);
1161:            }
1162:
1163:            public ObjectName[] getValveObjectNames() {
1164:                return ((StandardPipeline) pipeline).getValveObjectNames();
1165:            }
1166:
1167:            /**
1168:             * <p>Return the Valve instance that has been distinguished as the basic
1169:             * Valve for this Pipeline (if any).
1170:             */
1171:            public Valve getBasic() {
1172:
1173:                return (pipeline.getBasic());
1174:
1175:            }
1176:
1177:            /**
1178:             * Return the first valve in the pipeline.
1179:             */
1180:            public Valve getFirst() {
1181:
1182:                return (pipeline.getFirst());
1183:
1184:            }
1185:
1186:            /**
1187:             * Return the set of Valves in the pipeline associated with this
1188:             * Container, including the basic Valve (if any).  If there are no
1189:             * such Valves, a zero-length array is returned.
1190:             */
1191:            public Valve[] getValves() {
1192:
1193:                return (pipeline.getValves());
1194:
1195:            }
1196:
1197:            /**
1198:             * Remove the specified Valve from the pipeline associated with this
1199:             * Container, if it is found; otherwise, do nothing.
1200:             *
1201:             * @param valve Valve to be removed
1202:             */
1203:            public synchronized void removeValve(Valve valve) {
1204:
1205:                pipeline.removeValve(valve);
1206:                fireContainerEvent(REMOVE_VALVE_EVENT, valve);
1207:            }
1208:
1209:            /**
1210:             * <p>Set the Valve instance that has been distinguished as the basic
1211:             * Valve for this Pipeline (if any).  Prioer to setting the basic Valve,
1212:             * the Valve's <code>setContainer()</code> will be called, if it
1213:             * implements <code>Contained</code>, with the owning Container as an
1214:             * argument.  The method may throw an <code>IllegalArgumentException</code>
1215:             * if this Valve chooses not to be associated with this Container, or
1216:             * <code>IllegalStateException</code> if it is already associated with
1217:             * a different Container.</p>
1218:             *
1219:             * @param valve Valve to be distinguished as the basic Valve
1220:             */
1221:            public void setBasic(Valve valve) {
1222:
1223:                pipeline.setBasic(valve);
1224:
1225:            }
1226:
1227:            /**
1228:             * Execute a periodic task, such as reloading, etc. This method will be
1229:             * invoked inside the classloading context of this container. Unexpected
1230:             * throwables will be caught and logged.
1231:             */
1232:            public void backgroundProcess() {
1233:
1234:                if (!started)
1235:                    return;
1236:
1237:                if (cluster != null) {
1238:                    try {
1239:                        cluster.backgroundProcess();
1240:                    } catch (Exception e) {
1241:                        log.warn(sm.getString(
1242:                                "containerBase.backgroundProcess.cluster",
1243:                                cluster), e);
1244:                    }
1245:                }
1246:                if (loader != null) {
1247:                    try {
1248:                        loader.backgroundProcess();
1249:                    } catch (Exception e) {
1250:                        log.warn(sm.getString(
1251:                                "containerBase.backgroundProcess.loader",
1252:                                loader), e);
1253:                    }
1254:                }
1255:                if (manager != null) {
1256:                    try {
1257:                        manager.backgroundProcess();
1258:                    } catch (Exception e) {
1259:                        log.warn(sm.getString(
1260:                                "containerBase.backgroundProcess.manager",
1261:                                manager), e);
1262:                    }
1263:                }
1264:                if (realm != null) {
1265:                    try {
1266:                        realm.backgroundProcess();
1267:                    } catch (Exception e) {
1268:                        log
1269:                                .warn(
1270:                                        sm
1271:                                                .getString(
1272:                                                        "containerBase.backgroundProcess.realm",
1273:                                                        realm), e);
1274:                    }
1275:                }
1276:                Valve current = pipeline.getFirst();
1277:                while (current != null) {
1278:                    try {
1279:                        current.backgroundProcess();
1280:                    } catch (Exception e) {
1281:                        log.warn(sm.getString(
1282:                                "containerBase.backgroundProcess.valve",
1283:                                current), e);
1284:                    }
1285:                    current = current.getNext();
1286:                }
1287:                lifecycle.fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
1288:            }
1289:
1290:            // ------------------------------------------------------ Protected Methods
1291:
1292:            /**
1293:             * Notify all container event listeners that a particular event has
1294:             * occurred for this Container.  The default implementation performs
1295:             * this notification synchronously using the calling thread.
1296:             *
1297:             * @param type Event type
1298:             * @param data Event data
1299:             */
1300:            public void fireContainerEvent(String type, Object data) {
1301:
1302:                if (listeners.size() < 1)
1303:                    return;
1304:                ContainerEvent event = new ContainerEvent(this , type, data);
1305:                ContainerListener list[] = new ContainerListener[0];
1306:                synchronized (listeners) {
1307:                    list = (ContainerListener[]) listeners.toArray(list);
1308:                }
1309:                for (int i = 0; i < list.length; i++)
1310:                    ((ContainerListener) list[i]).containerEvent(event);
1311:
1312:            }
1313:
1314:            /**
1315:             * Return the abbreviated name of this container for logging messsages
1316:             */
1317:            protected String logName() {
1318:
1319:                if (logName != null) {
1320:                    return logName;
1321:                }
1322:                String loggerName = null;
1323:                Container current = this ;
1324:                while (current != null) {
1325:                    String name = current.getName();
1326:                    if ((name == null) || (name.equals(""))) {
1327:                        name = "/";
1328:                    }
1329:                    loggerName = "[" + name + "]"
1330:                            + ((loggerName != null) ? ("." + loggerName) : "");
1331:                    current = current.getParent();
1332:                }
1333:                logName = ContainerBase.class.getName() + "." + loggerName;
1334:                return logName;
1335:
1336:            }
1337:
1338:            // -------------------- JMX and Registration  --------------------
1339:            protected String type;
1340:            protected String domain;
1341:            protected String suffix;
1342:            protected ObjectName oname;
1343:            protected ObjectName controller;
1344:            protected transient MBeanServer mserver;
1345:
1346:            public ObjectName getJmxName() {
1347:                return oname;
1348:            }
1349:
1350:            public String getObjectName() {
1351:                if (oname != null) {
1352:                    return oname.toString();
1353:                } else
1354:                    return null;
1355:            }
1356:
1357:            public String getDomain() {
1358:                if (domain == null) {
1359:                    Container parent = this ;
1360:                    while (parent != null
1361:                            && !(parent instanceof  StandardEngine)) {
1362:                        parent = parent.getParent();
1363:                    }
1364:                    if (parent instanceof  StandardEngine) {
1365:                        domain = ((StandardEngine) parent).getDomain();
1366:                    }
1367:                }
1368:                return domain;
1369:            }
1370:
1371:            public void setDomain(String domain) {
1372:                this .domain = domain;
1373:            }
1374:
1375:            public String getType() {
1376:                return type;
1377:            }
1378:
1379:            protected String getJSR77Suffix() {
1380:                return suffix;
1381:            }
1382:
1383:            public ObjectName preRegister(MBeanServer server, ObjectName name)
1384:                    throws Exception {
1385:                oname = name;
1386:                mserver = server;
1387:                if (name == null) {
1388:                    return null;
1389:                }
1390:
1391:                domain = name.getDomain();
1392:
1393:                type = name.getKeyProperty("type");
1394:                if (type == null) {
1395:                    type = name.getKeyProperty("j2eeType");
1396:                }
1397:
1398:                String j2eeApp = name.getKeyProperty("J2EEApplication");
1399:                String j2eeServer = name.getKeyProperty("J2EEServer");
1400:                if (j2eeApp == null) {
1401:                    j2eeApp = "none";
1402:                }
1403:                if (j2eeServer == null) {
1404:                    j2eeServer = "none";
1405:                }
1406:                suffix = ",J2EEApplication=" + j2eeApp + ",J2EEServer="
1407:                        + j2eeServer;
1408:                return name;
1409:            }
1410:
1411:            public void postRegister(Boolean registrationDone) {
1412:            }
1413:
1414:            public void preDeregister() throws Exception {
1415:            }
1416:
1417:            public void postDeregister() {
1418:            }
1419:
1420:            public ObjectName[] getChildren() {
1421:                ObjectName result[] = new ObjectName[children.size()];
1422:                Iterator it = children.values().iterator();
1423:                int i = 0;
1424:                while (it.hasNext()) {
1425:                    Object next = it.next();
1426:                    if (next instanceof  ContainerBase) {
1427:                        result[i++] = ((ContainerBase) next).getJmxName();
1428:                    }
1429:                }
1430:                return result;
1431:            }
1432:
1433:            public ObjectName createObjectName(String domain, ObjectName parent)
1434:                    throws Exception {
1435:                if (log.isDebugEnabled())
1436:                    log.debug("Create ObjectName " + domain + " " + parent);
1437:                return null;
1438:            }
1439:
1440:            public String getContainerSuffix() {
1441:                Container container = this ;
1442:                Container context = null;
1443:                Container host = null;
1444:                Container servlet = null;
1445:
1446:                StringBuffer suffix = new StringBuffer();
1447:
1448:                if (container instanceof  StandardHost) {
1449:                    host = container;
1450:                } else if (container instanceof  StandardContext) {
1451:                    host = container.getParent();
1452:                    context = container;
1453:                } else if (container instanceof  StandardWrapper) {
1454:                    context = container.getParent();
1455:                    host = context.getParent();
1456:                    servlet = container;
1457:                }
1458:                if (context != null) {
1459:                    String path = ((StandardContext) context).getPath();
1460:                    suffix.append(",path=").append(
1461:                            (path.equals("")) ? "/" : path);
1462:                }
1463:                if (host != null)
1464:                    suffix.append(",host=").append(host.getName());
1465:                if (servlet != null) {
1466:                    String name = container.getName();
1467:                    suffix.append(",servlet=");
1468:                    suffix.append((name == "") ? "/" : name);
1469:                }
1470:                return suffix.toString();
1471:            }
1472:
1473:            /**
1474:             * Start the background thread that will periodically check for
1475:             * session timeouts.
1476:             */
1477:            protected void threadStart() {
1478:
1479:                if (thread != null)
1480:                    return;
1481:                if (backgroundProcessorDelay <= 0)
1482:                    return;
1483:
1484:                threadDone = false;
1485:                String threadName = "ContainerBackgroundProcessor["
1486:                        + toString() + "]";
1487:                thread = new Thread(new ContainerBackgroundProcessor(),
1488:                        threadName);
1489:                thread.setDaemon(true);
1490:                thread.start();
1491:
1492:            }
1493:
1494:            /**
1495:             * Stop the background thread that is periodically checking for
1496:             * session timeouts.
1497:             */
1498:            protected void threadStop() {
1499:
1500:                if (thread == null)
1501:                    return;
1502:
1503:                threadDone = true;
1504:                thread.interrupt();
1505:                try {
1506:                    thread.join();
1507:                } catch (InterruptedException e) {
1508:                    ;
1509:                }
1510:
1511:                thread = null;
1512:
1513:            }
1514:
1515:            // -------------------------------------- ContainerExecuteDelay Inner Class
1516:
1517:            /**
1518:             * Private thread class to invoke the backgroundProcess method 
1519:             * of this container and its children after a fixed delay.
1520:             */
1521:            protected class ContainerBackgroundProcessor implements  Runnable {
1522:
1523:                public void run() {
1524:                    while (!threadDone) {
1525:                        try {
1526:                            Thread.sleep(backgroundProcessorDelay * 1000L);
1527:                        } catch (InterruptedException e) {
1528:                            ;
1529:                        }
1530:                        if (!threadDone) {
1531:                            Container parent = (Container) getMappingObject();
1532:                            ClassLoader cl = Thread.currentThread()
1533:                                    .getContextClassLoader();
1534:                            if (parent.getLoader() != null) {
1535:                                cl = parent.getLoader().getClassLoader();
1536:                            }
1537:                            processChildren(parent, cl);
1538:                        }
1539:                    }
1540:                }
1541:
1542:                protected void processChildren(Container container,
1543:                        ClassLoader cl) {
1544:                    try {
1545:                        if (container.getLoader() != null) {
1546:                            Thread.currentThread().setContextClassLoader(
1547:                                    container.getLoader().getClassLoader());
1548:                        }
1549:                        container.backgroundProcess();
1550:                    } catch (Throwable t) {
1551:                        log.error("Exception invoking periodic operation: ", t);
1552:                    } finally {
1553:                        Thread.currentThread().setContextClassLoader(cl);
1554:                    }
1555:                    Container[] children = container.findChildren();
1556:                    for (int i = 0; i < children.length; i++) {
1557:                        if (children[i].getBackgroundProcessorDelay() <= 0) {
1558:                            processChildren(children[i], cl);
1559:                        }
1560:                    }
1561:                }
1562:
1563:            }
1564:
1565:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.