Lifecycle refactoring - Manager
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sat, 6 Mar 2010 13:03:11 +0000 (13:03 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sat, 6 Mar 2010 13:03:11 +0000 (13:03 +0000)
Lifecycle.START event fired too early in a number of cases
Added toString() for use in Lifecycle error messages

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@919756 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
java/org/apache/catalina/ha/session/BackupManager.java
java/org/apache/catalina/ha/session/DeltaManager.java
java/org/apache/catalina/ha/session/LocalStrings.properties
java/org/apache/catalina/ha/session/LocalStrings_es.properties
java/org/apache/catalina/ha/session/SimpleTcpReplicationManager.java
java/org/apache/catalina/session/LocalStrings.properties
java/org/apache/catalina/session/LocalStrings_es.properties
java/org/apache/catalina/session/LocalStrings_fr.properties
java/org/apache/catalina/session/LocalStrings_ja.properties
java/org/apache/catalina/session/ManagerBase.java
java/org/apache/catalina/session/PersistentManagerBase.java
java/org/apache/catalina/session/StandardManager.java

index 1f68f35..a69d797 100644 (file)
@@ -30,6 +30,7 @@ import org.apache.catalina.tribes.Channel;
 import org.apache.catalina.tribes.io.ReplicationStream;
 import org.apache.catalina.tribes.tipis.LazyReplicatedMap;
 import org.apache.catalina.tribes.tipis.AbstractReplicatedMap.MapOwner;
+import org.apache.catalina.util.LifecycleBase;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -129,7 +130,7 @@ public class BackupManager extends StandardManager implements ClusterManager, Ma
     }
     
     public ClusterMessage requestCompleted(String sessionId) {
-        if ( !this.started ) return null;
+        if (!getState().isAvailable()) return null;
         LazyReplicatedMap map = (LazyReplicatedMap)sessions;
         map.replicate(sessionId,false);
         return null;
@@ -182,21 +183,22 @@ public class BackupManager extends StandardManager implements ClusterManager, Ma
     public String getName() {
         return this.name;
     }
+
+
     /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component.  This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.<BR>
-     * Starts the cluster communication channel, this will connect with the other nodes
-     * in the cluster, and request the current session state to be transferred to this node.
-     * @exception IllegalStateException if this component has already been
-     *  started
+     * Start this component and implement the requirements
+     * of {@link LifecycleBase#startInternal()}.
+     *
+     * Starts the cluster communication channel, this will connect with the
+     * other nodes in the cluster, and request the current session state to be
+     * transferred to this node.
+     * 
      * @exception LifecycleException if this component detects a fatal error
      *  that prevents this component from being used
      */
     @Override
-    public void start() throws LifecycleException {
-        if ( this.started ) return;
-        
+    protected synchronized void startInternal() throws LifecycleException {
+
         try {
             cluster.registerManager(this);
             CatalinaCluster catclust = cluster;
@@ -207,12 +209,12 @@ public class BackupManager extends StandardManager implements ClusterManager, Ma
                                                           getClassLoaders());
             map.setChannelSendOptions(mapSendOptions);
             this.sessions = map;
-            super.start();
-            this.started = true;
         }  catch ( Exception x ) {
             log.error("Unable to start BackupManager",x);
             throw new LifecycleException("Failed to start BackupManager",x);
         }
+
+        super.startInternal();
     }
     
     public String getMapName() {
@@ -222,33 +224,28 @@ public class BackupManager extends StandardManager implements ClusterManager, Ma
         return name;
     }
 
+
     /**
-     * Gracefully terminate the active use of the public methods of this
-     * component.  This method should be the last one called on a given
-     * instance of this component.<BR>
-     * This will disconnect the cluster communication channel and stop the listener thread.
-     * @exception IllegalStateException if this component has not been started
+     * Stop this component and implement the requirements
+     * of {@link LifecycleBase#stopInternal()}.
+     * 
+     * This will disconnect the cluster communication channel and stop the
+     * listener thread.
+     *
      * @exception LifecycleException if this component detects a fatal error
-     *  that needs to be reported
+     *  that prevents this component from being used
      */
     @Override
-    public void stop() throws LifecycleException
-    {
+    protected synchronized void stopInternal() throws LifecycleException {
+
+        super.stopInternal();
         
         LazyReplicatedMap map = (LazyReplicatedMap)sessions;
         if ( map!=null ) {
             map.breakdown();
         }
-        if ( !this.started ) return;
-        try {
-        } catch ( Exception x ){
-            log.error("Unable to stop BackupManager",x);
-            throw new LifecycleException("Failed to stop BackupManager",x);
-        } finally {
-            super.stop();
-        }
-        cluster.removeManager(this);
 
+        cluster.removeManager(this);
     }
 
     @Override
index b6899cc..513a750 100644 (file)
@@ -33,7 +33,7 @@ import org.apache.catalina.Context;
 import org.apache.catalina.Engine;
 import org.apache.catalina.Host;
 import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
 import org.apache.catalina.Session;
 import org.apache.catalina.Valve;
 import org.apache.catalina.core.StandardContext;
@@ -42,7 +42,7 @@ import org.apache.catalina.ha.ClusterMessage;
 import org.apache.catalina.ha.tcp.ReplicationValve;
 import org.apache.catalina.tribes.Member;
 import org.apache.catalina.tribes.io.ReplicationStream;
-import org.apache.catalina.util.LifecycleSupport;
+import org.apache.catalina.util.LifecycleBase;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.catalina.ha.ClusterManager;
 
@@ -83,11 +83,6 @@ public class DeltaManager extends ClusterManagerBase{
     private static final String info = "DeltaManager/2.1";
 
     /**
-     * Has this component been started yet?
-     */
-    private boolean started = false;
-
-    /**
      * The descriptive name of this Manager implementation (for logging).
      */
     protected static String managerName = "DeltaManager";
@@ -101,11 +96,6 @@ public class DeltaManager extends ClusterManagerBase{
     private ReplicationValve replicationValve = null ;
     
     /**
-     * The lifecycle event support for this component.
-     */
-    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-    /**
      * The maximum number of active Sessions allowed, or -1 for no limit.
      */
     private int maxActiveSessions = -1;
@@ -758,55 +748,17 @@ public class DeltaManager extends ClusterManagerBase{
         return fos.toByteArray();
     }
 
-    // ------------------------------------------------------ Lifecycle Methods
-
-    /**
-     * Add a lifecycle event listener to this component.
-     * 
-     * @param listener
-     *            The listener to add
-     */
-    public void addLifecycleListener(LifecycleListener listener) {
-        lifecycle.addLifecycleListener(listener);
-    }
-
-    /**
-     * Get the lifecycle listeners associated with this lifecycle. If this
-     * Lifecycle has no listeners registered, a zero-length array is returned.
-     */
-    public LifecycleListener[] findLifecycleListeners() {
-        return lifecycle.findLifecycleListeners();
-    }
-
     /**
-     * Remove a lifecycle event listener from this component.
-     * 
-     * @param listener
-     *            The listener to remove
-     */
-    public void removeLifecycleListener(LifecycleListener listener) {
-        lifecycle.removeLifecycleListener(listener);
-    }
-
-    /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component. This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.
-     * 
-     * @exception LifecycleException
-     *                if this component detects a fatal error that prevents this
-     *                component from being used
+     * Start this component and implement the requirements
+     * of {@link LifecycleBase#startInternal()}.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that prevents this component from being used
      */
-    public void start() throws LifecycleException {
+    @Override
+    protected synchronized void startInternal() throws LifecycleException {
         if (!initialized) init();
 
-        // Validate and update our current component state
-        if (started) {
-            return;
-        }
-        started = true;
-        lifecycle.fireLifecycleEvent(START_EVENT, null);
-
         // Force initialization of the random number generator
         generateSessionId();
 
@@ -862,6 +814,8 @@ public class DeltaManager extends ClusterManagerBase{
         } catch (Throwable t) {
             log.error(sm.getString("deltaManager.managerLoad"), t);
         }
+        
+        setState(LifecycleState.STARTING);
     }
 
     /**
@@ -998,26 +952,20 @@ public class DeltaManager extends ClusterManagerBase{
     }
 
     /**
-     * Gracefully terminate the active use of the public methods of this
-     * component. This method should be the last one called on a given instance
-     * of this component.
-     * 
-     * @exception LifecycleException
-     *                if this component detects a fatal error that needs to be
-     *                reported
+     * Stop this component and implement the requirements
+     * of {@link LifecycleBase#stopInternal()}.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that prevents this component from being used
      */
-    public void stop() throws LifecycleException {
+    @Override
+    protected synchronized void stopInternal() throws LifecycleException {
 
         if (log.isDebugEnabled())
             log.debug(sm.getString("deltaManager.stopped", getName()));
 
-
-        // Validate and update our current component state
-        if (!started)
-            throw new LifecycleException(sm.getString("deltaManager.notStarted"));
-        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-        started = false;
-
+        setState(LifecycleState.STOPPING);
+        
         // Expire all active sessions
         if (log.isInfoEnabled()) log.info(sm.getString("deltaManager.expireSessions", getName()));
         Session sessions[] = findSessions();
index 3b52609..ca587ef 100644 (file)
@@ -34,7 +34,6 @@ deltaManager.noCluster=Starting... no cluster associated with this context: [{0}
 deltaManager.noMasterMember=Starting... with no other member for context [{0}] at domain [{1}]
 deltaManager.noMembers=Manager [{0}]: skipping state transfer. No members active in cluster group.
 deltaManager.noSessionState=Manager [{0}]: No session state send at {1} received, timing out after {2} ms.
-deltaManager.notStarted=Manager has not yet been started
 deltaManager.sendMessage.newSession=Manager [{0}] send new session ({1})
 deltaManager.expireSessions=Manager [{0}] expiring sessions upon shutdown
 deltaManager.receiveMessage.accessed=Manager [{0}]: received session [{1}] accessed.
index 42fcbfb..69d4690 100644 (file)
@@ -34,7 +34,6 @@ deltaManager.noCluster = Arrancando... no hay cl\u00FAster asociado con este con
 deltaManager.noMasterMember = Arrancando... sin otro miembro para el contexto [{0}] en dominio [{1}]
 deltaManager.noMembers = Gestor [{0}]\: saltando estado de transferencia. No hay miembros activos en grupo de cl\u00FAster.
 deltaManager.noSessionState = Gestor [{0}]\: No se ha recibido estado de sesi\u00F3n a las {1}, agotando tiempo tras {2} ms.
-deltaManager.notStarted = El gestor a\u00FAn no ha sido arrancado
 deltaManager.sendMessage.newSession = El gestor [{0}] env\u00EDa nueva sesi\u00F3n ({1})
 deltaManager.expireSessions = Gestor [{0}] expirando sesiones al apagar
 deltaManager.receiveMessage.accessed = Gestor [{0}]\: accedida sesi\u00F3n [{1}] recibida.
index 477e1e3..989f3ea 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.catalina.ha.session;
 import java.io.IOException;
 
 import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
 import org.apache.catalina.Session;
 import org.apache.catalina.ha.CatalinaCluster;
 import org.apache.catalina.ha.ClusterManager;
@@ -27,6 +28,8 @@ import org.apache.catalina.tribes.Member;
 import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.catalina.session.StandardManager;
 import org.apache.catalina.tribes.io.ReplicationStream;
+import org.apache.catalina.util.LifecycleBase;
+
 import java.io.ByteArrayInputStream;
 import org.apache.catalina.Loader;
 
@@ -67,16 +70,11 @@ public class SimpleTcpReplicationManager extends StandardManager implements Clus
     //the group name
     protected String mGroupName = "TomcatReplication";
 
-    //somehow start() gets called more than once
-    protected boolean mChannelStarted = false;
-
     //log to screen
     protected boolean mPrintToScreen = true;
 
     protected boolean defaultMode = false;
 
-    protected boolean mManagerRunning = false;
-
     /** Use synchronous rather than asynchronous replication. Every session modification (creation, change, removal etc)
      * will be sent to all members. The call will then wait for max milliseconds, or forever (if timeout is 0) for
      * all responses.
@@ -138,11 +136,6 @@ public class SimpleTcpReplicationManager extends StandardManager implements Clus
         this.defaultMode = defaultMode;
     }
     
-    public boolean isManagerRunning()
-    {
-        return mManagerRunning;
-    }
-
     public void setUseDirtyFlag(boolean usedirtyflag)
     {
         this.useDirtyFlag = usedirtyflag;
@@ -465,28 +458,28 @@ public class SimpleTcpReplicationManager extends StandardManager implements Clus
     public String getName() {
         return this.name;
     }
+
+
     /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component.  This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.<BR>
-     * Starts the cluster communication channel, this will connect with the other nodes
-     * in the cluster, and request the current session state to be transferred to this node.
-     * @exception IllegalStateException if this component has already been
-     *  started
+     * Start this component and implement the requirements
+     * of {@link LifecycleBase#startInternal()}.
+     *
+     * Starts the cluster communication channel, this will connect with the
+     * other nodes in the cluster, and request the current session state to be
+     * transferred to this node.
+     * 
      * @exception LifecycleException if this component detects a fatal error
      *  that prevents this component from being used
      */
     @Override
-    public void start() throws LifecycleException {
-        mManagerRunning = true;
-        super.start();
+    protected synchronized void startInternal() throws LifecycleException {
+
         try {
-            //the channel is already running
-            if ( mChannelStarted ) return;
             if(log.isInfoEnabled())
                 log.info("Starting clustering manager...:"+getName());
             if ( cluster == null ) {
                 log.error("Starting... no cluster associated with this context:"+getName());
+                setState(LifecycleState.FAILED);
                 return;
             }
             cluster.registerManager(this);
@@ -524,27 +517,28 @@ public class SimpleTcpReplicationManager extends StandardManager implements Clus
                 if(log.isInfoEnabled())
                     log.info("Manager["+getName()+"], skipping state transfer. No members active in cluster group.");
             }//end if
-            mChannelStarted = true;
+            super.startInternal();
         }  catch ( Exception x ) {
             log.error("Unable to start SimpleTcpReplicationManager",x);
+            setState(LifecycleState.FAILED);
         }
     }
 
+
     /**
-     * Gracefully terminate the active use of the public methods of this
-     * component.  This method should be the last one called on a given
-     * instance of this component.<BR>
-     * This will disconnect the cluster communication channel and stop the listener thread.
-     * @exception IllegalStateException if this component has not been started
+     * Stop this component and implement the requirements
+     * of {@link LifecycleBase#stopInternal()}.
+     *
+     * This will disconnect the cluster communication channel and stop the
+     * listener thread.
+     * 
      * @exception LifecycleException if this component detects a fatal error
-     *  that needs to be reported
+     *  that prevents this component from being used
      */
     @Override
-    public void stop() throws LifecycleException
-    {
-        mManagerRunning = false;
-        mChannelStarted = false;
-        super.stop();
+    protected synchronized void stopInternal() throws LifecycleException {
+
+        super.stopInternal();
         try
         {
             this.sessions.clear();
index 0f7b85b..c798044 100644 (file)
@@ -33,13 +33,11 @@ managerBase.gotten=Completed getting message digest component
 managerBase.random=Exception initializing random number generator of class {0}
 managerBase.seeding=Seeding random number generator class {0}
 serverSession.value.iae=null value
-standardManager.alreadyStarted=Manager has already been started
 standardManager.createSession.ise=createSession: Too many active sessions
 standardManager.expireException=processsExpire:  Exception during session expiration
 standardManager.loading=Loading persisted sessions from {0}
 standardManager.loading.cnfe=ClassNotFoundException while loading persisted sessions: {0}
 standardManager.loading.ioe=IOException while loading persisted sessions: {0}
-standardManager.notStarted=Manager has not yet been started
 standardManager.sessionTimeout=Invalid session timeout setting {0}
 standardManager.unloading=Saving persisted sessions to {0}
 standardManager.unloading.ioe=IOException while saving persisted sessions: {0}
index b94cfb3..3712d59 100644 (file)
@@ -32,13 +32,11 @@ managerBase.gotten = Completada la obtenci\u00F3n de mensaje de componente de re
 managerBase.random = Excepci\u00F3n inicializando generador de n\u00FAmeros aleatorios de clase {0}
 managerBase.seeding = Sembrando clase de generador de n\u00FAmeros aleatorios {0}
 serverSession.value.iae = valor nulo
-standardManager.alreadyStarted = Ya ha sido arrancado el Gestor
 standardManager.createSession.ise = createSession\: Demasiadas sesiones activas
 standardManager.expireException = processsExpire\: Excepci\u00F3n durante la expiraci\u00F3n de sesi\u00F3n
 standardManager.loading = Cargando sesiones persistidas desde {0}
 standardManager.loading.cnfe = ClassNotFoundException al cargar sesiones persistidas\: {0}
 standardManager.loading.ioe = IOException al cargar sesiones persistidas\: {0}
-standardManager.notStarted = A\u00FAn no se ha arrancado el Gestor
 standardManager.sessionTimeout = Valor inv\u00E1lido de Tiempo Agotado de sesi\u00F3n {0}
 standardManager.unloading = Salvando sesiones persistidas a {0}
 standardManager.unloading.ioe = IOException al salvar sesiones persistidas\: {0}
index 0db95aa..c4cc75e 100644 (file)
@@ -32,13 +32,11 @@ managerBase.gotten=Prise du composant d''algorithme empreinte de message (messag
 managerBase.random=Exception durant l''initialisation de la classe du g\u00e9n\u00e9rateur de nombre al\u00e9atoire {0}
 managerBase.seeding=Alimentation de la classe du g\u00e9n\u00e9rateur de nombre al\u00e9atoire {0}
 serverSession.value.iae=valeur nulle
-standardManager.alreadyStarted=Le "Manager" a \u00e9t\u00e9 d\u00e9marr\u00e9
 standardManager.createSession.ise="createSession": Trop de sessions actives
 standardManager.expireException="processsExpire":  Exception lors de l''expiration de la session
 standardManager.loading=Chargement des sessions qui ont persist\u00e9 depuis {0}
 standardManager.loading.cnfe="ClassNotFoundException" lors du chargement de sessions persistantes: {0}
 standardManager.loading.ioe="IOException" lors du chargement de sessions persistantes: {0}
-standardManager.notStarted=Le "Manager" n''a pas encore \u00e9t\u00e9 d\u00e9marr\u00e9
 standardManager.sessionTimeout=R\u00e9glage du d\u00e9lai d''inactivit\u00e9 (timeout) de session invalide {0}
 standardManager.unloading=Sauvegarde des sessions ayant persist\u00e9 vers {0}
 standardManager.unloading.ioe="IOException" lors de la sauvegarde de sessions persistantes: {0}
index 368819b..2c63b0f 100644 (file)
@@ -33,13 +33,11 @@ managerBase.gotten=\u30e1\u30c3\u30bb\u30fc\u30b8\u30c0\u30a4\u30b8\u30a7\u30b9\
 managerBase.random=\u30af\u30e9\u30b9 {0} \u306e\u4e71\u6570\u767a\u751f\u5668\u306e\u521d\u671f\u5316\u306e\u4f8b\u5916\u3067\u3059
 managerBase.seeding=\u4e71\u6570\u767a\u751f\u5668\u30af\u30e9\u30b9 {0} \u306e\u30b7\u30fc\u30c9\u3092\u751f\u6210\u3057\u3066\u3044\u307e\u3059
 serverSession.value.iae=null\u5024\u3067\u3059
-standardManager.alreadyStarted=\u30de\u30cd\u30fc\u30b8\u30e3\u306f\u65e2\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
 standardManager.createSession.ise=createSession: \u30a2\u30af\u30c6\u30a3\u30d6\u30bb\u30c3\u30b7\u30e7\u30f3\u304c\u591a\u3059\u304e\u307e\u3059
 standardManager.expireException=processsExpire: \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u7d42\u4e86\u51e6\u7406\u4e2d\u306e\u4f8b\u5916\u3067\u3059
 standardManager.loading={0} \u304b\u3089\u6301\u7d9a\u3055\u308c\u305f\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u3059
 standardManager.loading.cnfe=\u6301\u7d9a\u3055\u308c\u305f\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u30ed\u30fc\u30c9\u4e2d\u306bClassNotFoundException\u304c\u767a\u751f\u3057\u307e\u3057\u305f: {0}
 standardManager.loading.ioe=\u6301\u7d9a\u3055\u308c\u305f\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u30ed\u30fc\u30c9\u4e2d\u306eIOException\u3067\u3059: {0}
-standardManager.notStarted=\u30de\u30cd\u30fc\u30b8\u30e3\u306f\u307e\u3060\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u305b\u3093
 standardManager.sessionTimeout=\u7121\u52b9\u306a\u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u8a2d\u5b9a\u3067\u3059 {0}
 standardManager.unloading=\u6301\u7d9a\u3055\u308c\u305f\u30bb\u30c3\u30b7\u30e7\u30f3\u3092 {0} \u306b\u4fdd\u5b58\u3057\u307e\u3059
 standardManager.unloading.ioe=\u6301\u7d9a\u3055\u308c\u305f\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u4fdd\u5b58\u4e2d\u306eIOException\u3067\u3059: {0}
index d0a35b3..c70ea4c 100644 (file)
@@ -49,6 +49,7 @@ import org.apache.catalina.Manager;
 import org.apache.catalina.Session;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.util.LifecycleBase;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -64,7 +65,9 @@ import org.apache.tomcat.util.modeler.Registry;
  * @version $Revision$ $Date$
  */
 
-public abstract class ManagerBase implements Manager, MBeanRegistration {
+public abstract class ManagerBase extends LifecycleBase
+        implements Manager, MBeanRegistration {
+
     private final Log log = LogFactory.getLog(ManagerBase.class); // must not be static
 
     // ----------------------------------------------------- Instance Variables
@@ -1261,6 +1264,24 @@ public abstract class ManagerBase implements Manager, MBeanRegistration {
         return s.getCreationTime();
     }
 
+    
+    /**
+     * Return a String rendering of this object.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(this.getClass().getName());
+        sb.append('[');
+        if (container == null) {
+            sb.append("Container is null");
+        } else {
+            sb.append(container.getName());
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+    
+    
     // -------------------- JMX and Registration  --------------------
     protected String domain;
     protected ObjectName oname;
index 660affb..41066a1 100644 (file)
@@ -31,10 +31,10 @@ import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.Lifecycle;
 import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
 import org.apache.catalina.Session;
 import org.apache.catalina.Store;
-import org.apache.catalina.util.LifecycleSupport;
+import org.apache.catalina.util.LifecycleBase;
 
 import org.apache.catalina.security.SecurityUtil;
 import org.apache.juli.logging.Log;
@@ -53,9 +53,8 @@ import org.apache.juli.logging.LogFactory;
  * @version $Revision$ $Date$
  */
 
-public abstract class PersistentManagerBase
-    extends ManagerBase
-    implements Lifecycle, PropertyChangeListener {
+public abstract class PersistentManagerBase extends ManagerBase
+    implements PropertyChangeListener {
 
     private static final Log log = LogFactory.getLog(PersistentManagerBase.class);
 
@@ -140,12 +139,6 @@ public abstract class PersistentManagerBase
 
 
     /**
-     * The lifecycle event support for this component.
-     */
-    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-
-    /**
      * The maximum number of active Sessions allowed, or -1 for no limit.
      */
     protected int maxActiveSessions = -1;
@@ -158,12 +151,6 @@ public abstract class PersistentManagerBase
 
 
     /**
-     * Has this component been started yet?
-     */
-    protected boolean started = false;
-
-
-    /**
      * Store object which will manage the Session store.
      */
     protected Store store = null;
@@ -438,26 +425,6 @@ public abstract class PersistentManagerBase
 
 
     /**
-     * Get the started status.
-     */
-    protected boolean isStarted() {
-
-        return started;
-
-    }
-
-
-    /**
-     * Set the started flag
-     */
-    protected void setStarted(boolean started) {
-
-        this.started = started;
-
-    }
-
-
-    /**
      * Set the Store object which will manage persistent Session
      * storage for this Manager.
      *
@@ -932,65 +899,19 @@ public abstract class PersistentManagerBase
     }
 
 
-    // ------------------------------------------------------ Lifecycle Methods
-
-
-    /**
-     * Add a lifecycle event listener to this component.
-     *
-     * @param listener The listener to add
-     */
-    public void addLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.addLifecycleListener(listener);
-
-    }
-
-
-    /**
-     * Get the lifecycle listeners associated with this lifecycle. If this 
-     * Lifecycle has no listeners registered, a zero-length array is returned.
-     */
-    public LifecycleListener[] findLifecycleListeners() {
-
-        return lifecycle.findLifecycleListeners();
-
-    }
-
-
-    /**
-     * Remove a lifecycle event listener from this component.
-     *
-     * @param listener The listener to remove
-     */
-    public void removeLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.removeLifecycleListener(listener);
-
-    }
-
-
     /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component.  This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.
+     * Start this component and implement the requirements
+     * of {@link LifecycleBase#startInternal()}.
      *
      * @exception LifecycleException if this component detects a fatal error
      *  that prevents this component from being used
      */
-    public void start() throws LifecycleException {
+    @Override
+    protected synchronized void startInternal() throws LifecycleException {
 
-        // Validate and update our current component state
-        if (started) {
-            log.info(sm.getString("standardManager.alreadyStarted"));
-            return;
-        }
         if( ! initialized )
             init();
         
-        lifecycle.fireLifecycleEvent(START_EVENT, null);
-        started = true;
-
         // Force initialization of the random number generator
         if (log.isDebugEnabled())
             log.debug("Force random number initialization starting");
@@ -1003,31 +924,25 @@ public abstract class PersistentManagerBase
         else if (store instanceof Lifecycle)
             ((Lifecycle)store).start();
 
+        setState(LifecycleState.STARTING);
     }
 
 
     /**
-     * Gracefully terminate the active use of the public methods of this
-     * component.  This method should be the last one called on a given
-     * instance of this component.
+     * Stop this component and implement the requirements
+     * of {@link LifecycleBase#stopInternal()}.
      *
      * @exception LifecycleException if this component detects a fatal error
-     *  that needs to be reported
+     *  that prevents this component from being used
      */
-   public void stop() throws LifecycleException {
+    @Override
+    protected synchronized void stopInternal() throws LifecycleException {
 
         if (log.isDebugEnabled())
             log.debug("Stopping");
 
-        // Validate and update our current component state
-        if (!isStarted()) {
-            log.info(sm.getString("standardManager.notStarted"));
-            return;
-        }
+        setState(LifecycleState.STOPPING);
         
-        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-        setStarted(false);
-
         if (getStore() != null && saveOnRestart) {
             unload();
         } else {
@@ -1089,7 +1004,7 @@ public abstract class PersistentManagerBase
      */
     protected void processMaxIdleSwaps() {
 
-        if (!isStarted() || maxIdleSwap < 0)
+        if (!getState().isAvailable() || maxIdleSwap < 0)
             return;
 
         Session sessions[] = findSessions();
@@ -1132,7 +1047,7 @@ public abstract class PersistentManagerBase
      */
     protected void processMaxActiveSwaps() {
 
-        if (!isStarted() || getMaxActiveSessions() < 0)
+        if (!getState().isAvailable() || getMaxActiveSessions() < 0)
             return;
 
         Session sessions[] = findSessions();
@@ -1182,7 +1097,7 @@ public abstract class PersistentManagerBase
      */
     protected void processMaxIdleBackups() {
 
-        if (!isStarted() || maxIdleBackup < 0)
+        if (!getState().isAvailable() || maxIdleBackup < 0)
             return;
 
         Session sessions[] = findSessions();
index bbfdfc0..5d5e572 100644 (file)
@@ -37,13 +37,12 @@ import java.util.Iterator;
 import javax.servlet.ServletContext;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
-import org.apache.catalina.Lifecycle;
 import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
 import org.apache.catalina.Loader;
 import org.apache.catalina.Session;
 import org.apache.catalina.util.CustomObjectInputStream;
-import org.apache.catalina.util.LifecycleSupport;
+import org.apache.catalina.util.LifecycleBase;
 
 import org.apache.catalina.security.SecurityUtil;
 import org.apache.juli.logging.Log;
@@ -63,9 +62,8 @@ import org.apache.juli.logging.LogFactory;
  * @version $Revision$ $Date$
  */
 
-public class StandardManager
-    extends ManagerBase
-    implements Lifecycle, PropertyChangeListener {
+public class StandardManager extends ManagerBase
+        implements PropertyChangeListener {
 
     private final Log log = LogFactory.getLog(StandardManager.class); // must not be static
 
@@ -108,12 +106,6 @@ public class StandardManager
 
 
     /**
-     * The lifecycle event support for this component.
-     */
-    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-
-    /**
      * The maximum number of active Sessions allowed, or -1 for no limit.
      */
     protected int maxActiveSessions = -1;
@@ -137,12 +129,6 @@ public class StandardManager
 
 
     /**
-     * Has this component been started yet?
-     */
-    protected boolean started = false;
-
-
-    /**
      * Number of session creations that failed due to maxActiveSessions.
      */
     protected int rejectedSessions = 0;
@@ -567,63 +553,19 @@ public class StandardManager
     }
 
 
-    // ------------------------------------------------------ Lifecycle Methods
-
-
     /**
-     * Add a lifecycle event listener to this component.
-     *
-     * @param listener The listener to add
-     */
-    public void addLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.addLifecycleListener(listener);
-
-    }
-
-
-    /**
-     * Get the lifecycle listeners associated with this lifecycle. If this
-     * Lifecycle has no listeners registered, a zero-length array is returned.
-     */
-    public LifecycleListener[] findLifecycleListeners() {
-
-        return lifecycle.findLifecycleListeners();
-
-    }
-
-
-    /**
-     * Remove a lifecycle event listener from this component.
-     *
-     * @param listener The listener to remove
-     */
-    public void removeLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.removeLifecycleListener(listener);
-
-    }
-
-    /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component.  This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.
+     * Start this component and implement the requirements
+     * of {@link LifecycleBase#startInternal()}.
      *
      * @exception LifecycleException if this component detects a fatal error
      *  that prevents this component from being used
      */
-    public void start() throws LifecycleException {
+    @Override
+    protected synchronized void startInternal() throws LifecycleException {
 
         if( ! initialized )
             init();
 
-        // Validate and update our current component state
-        if (started) {
-            return;
-        }
-        lifecycle.fireLifecycleEvent(START_EVENT, null);
-        started = true;
-
         // Force initialization of the random number generator
         if (log.isDebugEnabled())
             log.debug("Force random number initialization starting");
@@ -638,29 +580,25 @@ public class StandardManager
             log.error(sm.getString("standardManager.managerLoad"), t);
         }
 
+        setState(LifecycleState.STARTING);
     }
 
 
     /**
-     * Gracefully terminate the active use of the public methods of this
-     * component.  This method should be the last one called on a given
-     * instance of this component.
+     * Stop this component and implement the requirements
+     * of {@link LifecycleBase#stopInternal()}.
      *
      * @exception LifecycleException if this component detects a fatal error
-     *  that needs to be reported
+     *  that prevents this component from being used
      */
-    public void stop() throws LifecycleException {
+    @Override
+    protected synchronized void stopInternal() throws LifecycleException {
 
         if (log.isDebugEnabled())
             log.debug("Stopping");
 
-        // Validate and update our current component state
-        if (!started)
-            throw new LifecycleException
-                (sm.getString("standardManager.notStarted"));
-        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-        started = false;
-
+        setState(LifecycleState.STOPPING);
+        
         // Write out sessions
         try {
             unload();