Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    * 
    *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  package org.apache.catalina.core;
  
  
  import static org.jboss.web.CatalinaMessages.MESSAGES;
  
  import java.util.List;
  import java.util.Map;
  
  
Abstract implementation of the Container interface, providing common functionality required by nearly every implementation. Classes extending this base class must implement getInfo(), and may implement a replacement for invoke().

All subclasses of this abstract base class will include support for a Pipeline object that defines the processing to be performed for each request received by the invoke() method of this class, utilizing the "Chain of Responsibility" design pattern. A subclass should encapsulate its own processing functionality as a Valve, and configure this Valve into the pipeline by calling setBasic().

This implementation fires property change events, per the JavaBeans design pattern, for changes in singleton properties. In addition, it fires the following ContainerEvent events to listeners who register themselves with addContainerListener():

TypeDataDescription
addChildContainerChild container added to this Container.
addValveValveValve added to this Container.
removeChildContainerChild container removed from this Container.
removeValveValveValve removed from this Container.
startnullContainer was started.
stopnullContainer was stopped.
Subclasses that fire additional events should document them in the class comments of the implementation class.

Author(s):
Craig R. McClanahan
 
 
 public abstract class ContainerBase
     implements ContainerLifecyclePipelineMBeanRegistration {

    
Container array type.
 
     protected static final Container[] CONTAINER_ARRAY = new Container[0];
    

    
Listener array type.
 
     protected static final ContainerListener[] LISTENER_ARRAY = new ContainerListener[0];
    

    
Perform addChild with the permissions of this class. addChild can be called with the XML parser on the stack, this allows the XML parser to have fewer privileges than Tomcat.
 
     protected class PrivilegedAddChild
         implements PrivilegedAction {
 
         private Container child;
 
         PrivilegedAddChild(Container child) {
             this. = child;
         }
 
         public Object run() {
             addChildInternal();
             return null;
         }
 
     }
 
 
     // ----------------------------------------------------- Instance Variables
 

    
The child Containers belonging to this Container, keyed by name.
 
     protected Map<StringContainerchildren = new ConcurrentHashMap<StringContainer>();

    
    
The processor delay for this component.
 
     protected int backgroundProcessorDelay = -1;


    
The lifecycle event support for this component.
 
     protected LifecycleSupport lifecycle = new LifecycleSupport(this);


    
The container event listeners for this Container.
 
     protected List<ContainerListenerlisteners = new CopyOnWriteArrayList<ContainerListener>();


    
The Loader implementation with which this Container is associated.
 
     protected Loader loader = null;


    
The Logger implementation with which this Container is associated.
 
     protected Logger logger = null;


    
Associated logger name.
 
     protected String logName = null;
    

    
The Manager implementation with which this Container is associated.
 
     protected Manager manager = null;


    
The cluster with which this Container is associated.
 
     protected Cluster cluster = null;

    
    
The human-readable name of this Container.
 
     protected String name = null;


    
The parent Container to which this Container is a child.
 
     protected Container parent = null;


    
The parent class loader to be configured when we install a Loader.
 
     protected ClassLoader parentClassLoader = null;


    
The Pipeline object with which this Container is associated.
 
     protected Pipeline pipeline = new StandardPipeline(this);


    
The Realm with which this Container is associated.
 
     protected Realm realm = null;


    
The resources DirContext object with which this Container is associated.
 
     protected DirContext resources = null;


    
Has this component been started?
 
     protected boolean started = false;
 
     protected boolean initialized=false;

    
Will children be started automatically when they are added.
 
     protected boolean startChildren = true;

    
The property change support for this component.
 
     protected PropertyChangeSupport support = new PropertyChangeSupport(this);


    
The background thread.
 
     private Thread thread = null;


    
The background thread completion semaphore.
 
     private boolean threadDone = false;
 
 
     // ------------------------------------------------------------- Properties
 

    
Return if the container is started. This sort of conflicts with lifecycle but the purpose should be evident enough.
 
     public boolean isStarted() {
         return ;
     }


    
Get the delay between the invocation of the backgroundProcess method on this container and its children. Child containers will not be invoked if their delay value is not negative (which would mean they are using their own thread). Setting this to a positive value will cause a thread to be spawn. After waiting the specified amount of time, the thread will invoke the executePeriodic method on this container and all its children.
 
     public int getBackgroundProcessorDelay() {
         return ;
     }


    
Set the delay between the invocation of the execute method on this container and its children.

Parameters:
delay The delay in seconds between the invocation of backgroundProcess methods
 
     public void setBackgroundProcessorDelay(int delay) {
          = delay;
     }


    
Return descriptive information about this Container implementation and the corresponding version number, in the format <description>/<version>.
 
     public String getInfo() {
         return this.getClass().getName();
     }


    
Return the Loader with which this Container is associated. If there is no associated Loader, return the Loader associated with our parent Container (if any); otherwise, return null.
 
     public Loader getLoader() {
 
         if ( != null)
             return ();
         if ( != null)
             return (.getLoader());
         return (null);
 
     }


    
Set the Loader with which this Container is associated.

Parameters:
loader The newly associated loader
 
     public synchronized void setLoader(Loader loader) {
 
         // Change components if necessary
         Loader oldLoader = this.;
         if (oldLoader == loader)
             return;
         this. = loader;
 
         // Stop the old component if necessary
         if ( && (oldLoader != null) &&
             (oldLoader instanceof Lifecycle)) {
             try {
                 ((LifecycleoldLoader).stop();
             } catch (LifecycleException e) {
                 ..errorStoppingLoader(e);
             }
         }
 
         // Start the new component if necessary
         if (loader != null)
             loader.setContainer(this);
         if ( && (loader != null) &&
             (loader instanceof Lifecycle)) {
             try {
                 ((Lifecycleloader).start();
             } catch (LifecycleException e) {
                 ..errorStartingLoader(e);
             }
         }
 
         // Report this property change to interested listeners
         .firePropertyChange("loader"oldLoaderthis.);
 
     }


    
Return the Logger with which this Container is associated. If there is no associated Logger, return the Logger associated with our parent Container (if any); otherwise return null.
 
     public Logger getLogger() {
 
         if ( != null)
             return ();
          = Logger.getLogger(logName());
         return ();
 
     }


    
Return the Manager with which this Container is associated. If there is no associated Manager, return the Manager associated with our parent Container (if any); otherwise return null.
 
     public Manager getManager() {
 
         if ( != null)
             return ();
         if ( != null)
             return (.getManager());
         return (null);
 
     }


    
Set the Manager with which this Container is associated.

Parameters:
manager The newly associated Manager
 
     public synchronized void setManager(Manager manager) {
 
         // Change components if necessary
         Manager oldManager = this.;
         if (oldManager == manager)
             return;
         this. = manager;
 
         // Stop the old component if necessary
         if ( && (oldManager != null) &&
             (oldManager instanceof Lifecycle)) {
             try {
                 ((LifecycleoldManager).stop();
             } catch (LifecycleException e) {
                 ..errorStoppingManager(e);
             }
         }
 
         // Start the new component if necessary
         if (manager != null)
             manager.setContainer(this);
         if ( && (manager != null) &&
             (manager instanceof Lifecycle)) {
             try {
                 ((Lifecyclemanager).start();
             } catch (LifecycleException e) {
                 ..errorStartingManager(e);
             }
         }
 
         // Report this property change to interested listeners
         .firePropertyChange("manager"oldManagerthis.);
 
     }


    
Return an object which may be utilized for mapping to this component.
 
     public Object getMappingObject() {
         return this;
     }


    
Return the Cluster with which this Container is associated. If there is no associated Cluster, return the Cluster associated with our parent Container (if any); otherwise return null.
 
     public Cluster getCluster() {
         if ( != null)
             return ();
 
         if ( != null)
             return (.getCluster());
 
         return (null);
     }


    
Set the Cluster with which this Container is associated.

Parameters:
cluster The newly associated Cluster
 
     public synchronized void setCluster(Cluster cluster) {
         // Change components if necessary
         Cluster oldCluster = this.;
         if (oldCluster == cluster)
             return;
         this. = cluster;
 
         // Stop the old component if necessary
         if ( && (oldCluster != null) &&
             (oldCluster instanceof Lifecycle)) {
             try {
                 ((LifecycleoldCluster).stop();
             } catch (LifecycleException e) {
                 ..errorStoppingCluster(e);
             }
         }
 
         // Start the new component if necessary
         if (cluster != null)
             cluster.setContainer(this);
 
         if ( && (cluster != null) &&
             (cluster instanceof Lifecycle)) {
             try {
                 ((Lifecyclecluster).start();
             } catch (LifecycleException e) {
                 ..errorStartingCluster(e);
             }
         }
 
         // Report this property change to interested listeners
         .firePropertyChange("cluster"oldClusterthis.);
     }


    
Return a name string (suitable for use by humans) that describes this Container. Within the set of child containers belonging to a particular parent, Container names must be unique.
 
     public String getName() {
 
         return ();
 
     }


    
Set a name string (suitable for use by humans) that describes this Container. Within the set of child containers belonging to a particular parent, Container names must be unique.

Parameters:
name New name of this container
Throws:
java.lang.IllegalStateException if this Container has already been added to the children of a parent Container (after which the name may not be changed)
 
     public void setName(String name) {
 
         String oldName = this.;
         this. = name;
         .firePropertyChange("name"oldNamethis.);
     }


    
Return if children of this container will be started automatically when they are added to this container.
 
     public boolean getStartChildren() {
 
         return ();
 
     }


    
Set if children of this container will be started automatically when they are added to this container.

Parameters:
startChildren New value of the startChildren flag
 
     public void setStartChildren(boolean startChildren) {
 
         boolean oldStartChildren = this.;
         this. = startChildren;
         .firePropertyChange("startChildren"oldStartChildrenthis.);
     }


    
Return the Container for which this Container is a child, if there is one. If there is no defined parent, return null.
 
     public Container getParent() {
 
         return ();
 
     }


    
Set the parent Container to which this Container is being added as a child. This Container may refuse to become attached to the specified Container by throwing an exception.

Parameters:
container Container to which this Container is being added as a child
Throws:
java.lang.IllegalArgumentException if this Container refuses to become attached to the specified Container
 
     public void setParent(Container container) {
 
         Container oldParent = this.;
         this. = container;
         .firePropertyChange("parent"oldParentthis.);
 
     }


    
Return the parent class loader (if any) for this web application. This call is meaningful only after a Loader has been configured.
 
     public ClassLoader getParentClassLoader() {
         if ( != null)
             return ();
         if ( != null) {
             return (.getParentClassLoader());
         }
         return (ClassLoader.getSystemClassLoader());
 
     }


    
Set the parent class loader (if any) for this web application. This call is meaningful only before a Loader has been configured, and the specified value (if non-null) should be passed as an argument to the class loader constructor.

Parameters:
parent The new parent class loader
 
     public void setParentClassLoader(ClassLoader parent) {
         ClassLoader oldParentClassLoader = this.;
         this. = parent;
         .firePropertyChange("parentClassLoader"oldParentClassLoader,
                                    this.);
 
     }


    
Return the Pipeline object that manages the Valves associated with this Container.
 
     public Pipeline getPipeline() {
 
         return (this.);
 
     }


    
Return the Realm with which this Container is associated. If there is no associated Realm, return the Realm associated with our parent Container (if any); otherwise return null.
 
     public Realm getRealm() {
 
         if ( != null)
             return ();
         if ( != null)
             return (.getRealm());
         return (null);
 
     }


    
Set the Realm with which this Container is associated.

Parameters:
realm The newly associated Realm
 
     public synchronized void setRealm(Realm realm) {
 
         // Change components if necessary
         Realm oldRealm = this.;
         if (oldRealm == realm)
             return;
         this. = realm;
 
         // Stop the old component if necessary
         if ( && (oldRealm != null) &&
             (oldRealm instanceof Lifecycle)) {
             try {
                 ((LifecycleoldRealm).stop();
             } catch (LifecycleException e) {
                 ..errorStoppingRealm(e);
             }
         }
 
         // Start the new component if necessary
         if (realm != null)
             realm.setContainer(this);
         if ( && (realm != null) &&
             (realm instanceof Lifecycle)) {
             try {
                 ((Lifecyclerealm).start();
             } catch (LifecycleException e) {
                 ..errorStartingRealm(e);
             }
         }
 
         // Report this property change to interested listeners
         .firePropertyChange("realm"oldRealmthis.);
 
     }


    
Return the resources DirContext object with which this Container is associated. If there is no associated resources object, return the resources associated with our parent Container (if any); otherwise return null.
 
     public DirContext getResources() {
         if ( != null)
             return ();
         if ( != null)
             return (.getResources());
         return (null);
 
     }


    
Set the resources DirContext object with which this Container is associated.

Parameters:
resources The newly associated DirContext
 
     public synchronized void setResources(DirContext resources) {
         // Called from StandardContext.setResources()
         //              <- StandardContext.start() 
         //              <- ContainerBase.addChildInternal() 
 
         // Change components if necessary
         DirContext oldResources = this.;
         if (oldResources == resources)
             return;
         Hashtable env = new Hashtable();
         if (getParent() != null)
             env.put(.getParent().getName());
         env.put(.getName());
         this. = new ProxyDirContext(envresources);
         // Report this property change to interested listeners
         .firePropertyChange("resources"oldResourcesthis.);
 
     }
 
 
     // ------------------------------------------------------ Container Methods
 

    
Add a new child Container to those associated with this Container, if supported. Prior to adding this Container to the set of children, the child's setParent() method must be called, with this Container as an argument. This method may thrown an IllegalArgumentException if this Container chooses not to be attached to the specified Container, in which case it is not added

Parameters:
child New child Container to be added
Throws:
java.lang.IllegalArgumentException if this exception is thrown by the setParent() method of the child Container
java.lang.IllegalArgumentException if the new child does not have a name unique from that of existing children of this Container
java.lang.IllegalStateException if this Container does not support child Containers
 
     public void addChild(Container child) {
         if (.) {
             PrivilegedAction dp =
                 new PrivilegedAddChild(child);
             AccessController.doPrivileged(dp);
         } else {
             addChildInternal(child);
         }
     }
 
     private synchronized void addChildInternal(Container child) {
 
         if (child.getName() == null)
             throw .containerChildWithNullName();
         if (.get(child.getName()) != null)
             throw .containerChildNameNotUnique(child.getName());
 
         child.setParent(this);  // May throw IAE
         .put(child.getName(), child);
 
         // Start child
         if ( &&  && (child instanceof Lifecycle)) {
             boolean success = false;
             try {
                 ((Lifecyclechild).start();
                 success = true;
             } catch (LifecycleException e) {
                 throw .containerChildStartFailed(child.getName(), e);
             } finally {
                 if (!success) {
                     .remove(child.getName());
                 }
             }
         }
 
         fireContainerEvent(child);
 
     }


    
Add a container event listener to this component.

Parameters:
listener The listener to add
 
     public void addContainerListener(ContainerListener listener) {
 
         .add(listener);
 
     }


    
Add a property change listener to this component.

Parameters:
listener The listener to add
 
     public void addPropertyChangeListener(PropertyChangeListener listener) {
 
         .addPropertyChangeListener(listener);
 
     }


    
Return the child Container, associated with this Container, with the specified name (if any); otherwise, return null

Parameters:
name Name of the child Container to be retrieved
 
     public Container findChild(String name) {
         if (name == null)
             return (null);
         return .get(name);
     }


    
Return the set of children Containers associated with this Container. If this Container has no children, a zero-length array is returned.
 
     public Container[] findChildren() {
         return .values().toArray();
     }


    
Return the set of container listeners associated with this Container. If this Container has no registered container listeners, a zero-length array is returned.
 
         return .toArray();
     }


    
Process the specified Request, to produce the corresponding Response, by invoking the first Valve in our pipeline (if any), or the basic Valve otherwise.

Parameters:
request Request to be processed
response Response to be produced
Throws:
java.lang.IllegalStateException if neither a pipeline or a basic Valve have been configured for this Container
java.io.IOException if an input/output error occurred while processing
javax.servlet.ServletException if a ServletException was thrown while processing this request
 
     public void invoke(Request requestResponse response)
         throws IOExceptionServletException {
 
         .getFirst().invoke(requestresponse);
 
     }


    
Remove an existing child Container from association with this parent Container.

Parameters:
child Existing child Container to be removed
 
     public synchronized void removeChild(Container child) {
 
         if (.get(child.getName()) == null)
             return;
         if (.get(child.getName()) != child)
             return;
         .remove(child.getName());
         
         if ( && (child instanceof Lifecycle)) {
             try {
                 ifchild instanceof ContainerBase ) {
                     if( ((ContainerBase)child). ) {
                         ((Lifecyclechild).stop();
                     }
                 } else {
                     ((Lifecyclechild).stop();
                 }
             } catch (LifecycleException e) {
                 ..errorStoppingChild(e);
             }
         }
         
         fireContainerEvent(child);
         
         // child.setParent(null);
 
     }


    
Remove a container event listener from this component.

Parameters:
listener The listener to remove
 
     public void removeContainerListener(ContainerListener listener) {
         .remove(listener);
     }


    
Remove a property change listener from this component.

Parameters:
listener The listener to remove
 
     public void removePropertyChangeListener(PropertyChangeListener listener) {
 
         .removePropertyChangeListener(listener);
 
     }
 
 
     // ------------------------------------------------------ Lifecycle Methods
 

    
Add a lifecycle event listener to this component.

Parameters:
listener The listener to add
 
     public void addLifecycleListener(LifecycleListener listener) {
 
         .addLifecycleListener(listener);
 
     }


    
Get the lifecycle listeners associated with this lifecycle. If this Lifecycle has no listeners registered, a zero-length array is returned.
 
 
         return .findLifecycleListeners();
 
     }


    
Remove a lifecycle event listener from this component.

Parameters:
listener The listener to remove
 
     public void removeLifecycleListener(LifecycleListener listener) {
 
         .removeLifecycleListener(listener);
 
     }


    
Prepare for active use of the public methods of this Component.

Throws:
org.apache.catalina.LifecycleException if this component detects a fatal error that prevents it from being started
 
     public synchronized void start() throws LifecycleException {
        // Validate and update our current component state
        if () {
            return;
        }
        
        // Notify our interested LifecycleListeners
         = true;
        // Start our subordinate components, if any
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
         = null;
        getLogger();
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
        if (( != null) && ( instanceof Lifecycle))
            ((Lifecycle).start();
        // Start our child containers, if any
        Container children[] = findChildren();
        for (int i = 0; i < children.lengthi++) {
            if (children[iinstanceof Lifecycle)
                ((Lifecyclechildren[i]).start();
        }
        // Start the Valves in our pipeline (including the basic), if any
        if ( instanceof Lifecycle)
            ((Lifecycle).start();
        // Notify our interested LifecycleListeners
        // Start our thread
        threadStart();
        // Notify our interested LifecycleListeners
    }


    
Gracefully shut down active use of the public methods of this Component.

Throws:
org.apache.catalina.LifecycleException if this component detects a fatal error that needs to be reported
    public synchronized void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!) {
            return;
        }
        // Notify our interested LifecycleListeners
        // Stop our thread
        threadStop();
        // Notify our interested LifecycleListeners
         = false;
        // Stop the Valves in our pipeline (including the basic), if any
        if ( instanceof Lifecycle) {
            ((Lifecycle).stop();
        }
        // Stop our child containers, if any
        Container children[] = findChildren();
        for (int i = 0; i < children.lengthi++) {
            if (children[iinstanceof Lifecycle)
                ((Lifecyclechildren[i]).stop();
        }
        // Remove children - so next start can work
        children = findChildren();
        for (int i = 0; i < children.lengthi++) {
            removeChild(children[i]);
        }
        // Stop our subordinate components, if any
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        if (( != null) && ( instanceof Lifecycle)) {
            ((Lifecycle).stop();
        }
        // Notify our interested LifecycleListeners
    }

    
Init method, part of the MBean lifecycle. If the container was added via JMX, it'll register itself with the parent, using the ObjectName conventions to locate the parent. If the container was added directly and it doesn't have an ObjectName, it'll create a name and register itself with the JMX console. On destroy(), the object will unregister.

    public void init() throws Exception {
            ifthis.getParent() == null ) {
                // "Life" update
                ObjectName parentName=getParentName();
                ifparentName != null && 
                        .isRegistered(parentName)) 
                {
                    .invoke(parentName"addChild"new Object[] { this },
                            new String[] {"org.apache.catalina.Container"});
                }
            }
        }
        =true;
    }
    
        return null;
    }
    
    public void destroy() throws Exception {
        if ) {
            stop();
        }
        =false;
        // unregister this component
            if (  != null ) {
                try {
                    if ==  ) {
                        Registry.getRegistry(nullnull).unregisterComponent();
                    }
                } catchThrowable t ) {
                    ..failedContainerJmxUnregistration(t);
                }
            }
        }
        if ( != null) {
            .removeChild(this);
        }
        // Stop our child containers, if any
        Container children[] = findChildren();
        for (int i = 0; i < children.lengthi++) {
            removeChild(children[i]);
        }
                
    }
    // ------------------------------------------------------- Pipeline Methods


    
Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the Valve, the Valve's setContainer method must be called, with this Container as an argument. The method may throw an IllegalArgumentException if this Valve chooses not to be associated with this Container, or IllegalStateException if it is already associated with a different Container.

Parameters:
valve Valve to be added
Throws:
java.lang.IllegalArgumentException if this Container refused to accept the specified Valve
java.lang.IllegalArgumentException if the specifie Valve refuses to be associated with this Container
java.lang.IllegalStateException if the specified Valve is already associated with a different Container
    public synchronized void addValve(Valve valve) {
        .addValve(valve);
        fireContainerEvent(valve);
    }
    public ObjectName[] getValveObjectNames() {
        return ((StandardPipeline)).getValveObjectNames();
    }
    
    

Return the Valve instance that has been distinguished as the basic Valve for this Pipeline (if any).

    public Valve getBasic() {
        return (.getBasic());
    }


    
Return the first valve in the pipeline.
    public Valve getFirst() {
        return (.getFirst());
    }


    
Return the set of Valves in the pipeline associated with this Container, including the basic Valve (if any). If there are no such Valves, a zero-length array is returned.
    public Valve[] getValves() {
        return (.getValves());
    }


    
Remove the specified Valve from the pipeline associated with this Container, if it is found; otherwise, do nothing.

Parameters:
valve Valve to be removed
    public synchronized void removeValve(Valve valve) {
        .removeValve(valve);
        fireContainerEvent(valve);
    }


    

Set the Valve instance that has been distinguished as the basic Valve for this Pipeline (if any). Prioer to setting the basic Valve, the Valve's setContainer() will be called, if it implements Contained, with the owning Container as an argument. The method may throw an IllegalArgumentException if this Valve chooses not to be associated with this Container, or IllegalStateException if it is already associated with a different Container.

Parameters:
valve Valve to be distinguished as the basic Valve
    public void setBasic(Valve valve) {
        .setBasic(valve);
    }


    
Execute a periodic task, such as reloading, etc. This method will be invoked inside the classloading context of this container. Unexpected throwables will be caught and logged.
    public void backgroundProcess() {
        
        if (!)
            return;
        if ( != null) {
            try {
                .backgroundProcess();
            } catch (Exception e) {
                ..backgroundProcessingError(e);
            }
        }
        if ( != null) {
            try {
                .backgroundProcess();
            } catch (Exception e) {
                ..backgroundProcessingError(e);
            }
        }
        if ( != null) {
            try {
                .backgroundProcess();
            } catch (Exception e) {
                ..backgroundProcessingError(e);
            }
        }
        if ( != null) {
            try {
                .backgroundProcess();
            } catch (Exception e) {
                ..backgroundProcessingError(e);
            }
        }
        Valve current = .getFirst();
        while (current != null) {
            try {
                current.backgroundProcess();
            } catch (Exception e) {
                ..backgroundProcessingError(currente);
            }
            current = current.getNext();
        }
    }


    
Notify all container event listeners that a particular event has occurred for this Container. The default implementation performs this notification synchronously using the calling thread.

Parameters:
type Event type
data Event data
    public void fireContainerEvent(String typeObject data) {
        if (.size() < 1)
            return;
        ContainerEvent event = new ContainerEvent(thistypedata);
        ContainerListener list[] = new ContainerListener[0];
        synchronized () {
            list = (ContainerListener[]) .toArray(list);
        }
        for (int i = 0; i < list.lengthi++)
            ((ContainerListenerlist[i]).containerEvent(event);
    }
    // ------------------------------------------------------ Protected Methods


    
Return the abbreviated name of this container for logging messsages
    protected String logName() {
        if ( != null) {
            return ;
        }
        String loggerName = null;
        Container current = this;
        while (current != null) {
            String name = current.getName();
            if ((name == null) || (name.equals(""))) {
                name = "/";
            }
            loggerName = "[" + name + "]" 
                + ((loggerName != null) ? ("." + loggerName) : "");
            current = current.getParent();
        }
         = ContainerBase.class.getName() + "." + loggerName;
        return ;
        
    }
    
    // -------------------- JMX and Registration  --------------------
    protected String type;
    protected String domain;
    protected String suffix;
    protected ObjectName oname;
    protected ObjectName controller;
    protected MBeanServer mserver;
    public ObjectName getJmxName() {
        return ;
    }
    
    public String getObjectName() {
        if ( != null) {
            return .toString();
        } else return null;
    }
    public String getDomain() {
        if==null ) {
            Container parent=this;
            whileparent != null &&
                    !( parent instanceof StandardEngine) ) {
                parent=parent.getParent();
            }
            ifparent instanceof StandardEngine ) {
                =((StandardEngine)parent).getDomain();
            } 
        }
        return ;
    }
    public void setDomain(String domain) {
        this.=domain;
    }
    
    public String getType() {
        return ;
    }
    protected String getJSR77Suffix() {
        return ;
    }
    public ObjectName preRegister(MBeanServer server,
                                  ObjectName namethrows Exception {
        =name;
        =server;
        if (name == null ){
            return null;
        }
        =name.getDomain();
        =name.getKeyProperty("type");
        if==null ) {
            =name.getKeyProperty("j2eeType");
        }
        String j2eeApp=name.getKeyProperty("J2EEApplication");
        String j2eeServer=name.getKeyProperty("J2EEServer");
        ifj2eeApp==null ) {
            j2eeApp="none";
        }
        ifj2eeServer==null ) {
            j2eeServer="none";
        }
        =",J2EEApplication=" + j2eeApp + ",J2EEServer=" + j2eeServer;
        return name;
    }
    public void postRegister(Boolean registrationDone) {
    }
    public void preDeregister() throws Exception {
    }
    public void postDeregister() {
    }
    public ObjectName[] getChildren() {
        ObjectName result[]=new ObjectName[.size()];
        Iterator it=.values().iterator();
        int i=0;
        whileit.hasNext() ) {
            Object next=it.next();
            ifnext instanceof ContainerBase ) {
                result[i++]=((ContainerBase)next).getJmxName();
            }
        }
        return result;
    }
    public ObjectName createObjectName(String domainObjectName parent)
        throws Exception
    {
        return null;
    }
    public String getContainerSuffix() {
        Container container=this;
        Container context=null;
        Container host=null;
        Container servlet=null;
        
        StringBuilder suffix=new StringBuilder();
        
        ifcontainer instanceof StandardHost ) {
            host=container;
        } else ifcontainer instanceof StandardContext ) {
            host=container.getParent();
            context=container;
        } else ifcontainer instanceof StandardWrapper ) {
            context=container.getParent();
            host=context.getParent();
            servlet=container;
        }
        ifcontext!=null ) {
            String path=((StandardContext)context).getPath();
            suffix.append(",path=").append((path.equals("")) ? "/" : path);
        } 
        ifhost!=null ) suffix.append(",host=").appendhost.getName() );
        ifservlet != null ) {
            String name=container.getName();
            suffix.append(",servlet=");
            suffix.append((name=="") ? "/" : name);
        }
        return suffix.toString();
    }


    
Start the background thread that will periodically check for session timeouts.
    protected void threadStart() {
        if ( != null)
          &nb