From 6a6f17bfb7f50046b444e4eebedbf694af24a9e4 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 4 Mar 2010 18:06:21 +0000 Subject: [PATCH] Lifecycle refactoring. Part 1 of many. Better define the start and stop methods as well as the overall component lifecycle and the relationship between start/stop, component state and events. Add a getState() method but it is commented out in this checkin to prevent compilation errors. It will be uncommented once the method has been added to the components that implement Lifecycle. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@919100 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/Lifecycle.java | 92 +++++++++++++++++++++++++--- java/org/apache/catalina/LifecycleState.java | 56 +++++++++++++++++ 2 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 java/org/apache/catalina/LifecycleState.java diff --git a/java/org/apache/catalina/Lifecycle.java b/java/org/apache/catalina/Lifecycle.java index a549f3ed2..fc108c2ac 100644 --- a/java/org/apache/catalina/Lifecycle.java +++ b/java/org/apache/catalina/Lifecycle.java @@ -21,14 +21,52 @@ package org.apache.catalina; /** * Common interface for component life cycle methods. Catalina components - * may, but are not required to, implement this interface (as well as the - * appropriate interface(s) for the functionality they support) in order to - * provide a consistent mechanism to start and stop the component. + * may implement this interface (as well as the appropriate interface(s) for + * the functionality they support) in order to provide a consistent mechanism + * to start and stop the component. + *
+ * The valid state transitions for components that support Lifecycle are: + *
+ *                  --------------------<--------------------------
+ *                  |                                             |
+ *     start()      |        auto          auto         stop()    |       
+ * NEW --->--- STARTING_PREP -->- STARTING -->- STARTED -->---    |
+ *                                                 |         |    |
+ *                                     auto        |         |    |
+ *      ---------<----- MUST_STOP --<---------------         |    |
+ *      |                                                    |    |
+ *      ---------------------------<--------------------------    ^
+ *      |                                                         |
+ *      |        auto          auto                start()        |
+ * STOPPING_PREP -->- STOPPING -->- STOPPED -------------->--------
+ *      ^
+ *      |stop()
+ *      |
+ *   FAILED
+ * 
+ * Any state can transition to FAILED.
+ * 
+ * Calling start() while a component is in states STARTING_PREP, STARTING or
+ * STARTED has no effect.
+ * 
+ * Calling stop() while a component is in states STOPPING_PREP, STOPPING or
+ * STOPPED has no effect.
+ * 
+ * MUST_STOP is used to indicate that the {@link #stop()} should be called on
+ * the component as soon as {@link start()} exits.
+ * 
+ * Attempting any other transition will throw {@link LifecycleException}.
+ * 
+ * 
+ * The {@link LifecycleEvent}s fired during state changes are defined in the + * methods that trigger the changed. No {@link LifecycleEvent}s are fired if the + * attempted transition is not valid. + * + * TODO: Not all components may transition from STOPPED to STARTING_PREP * * @author Craig R. McClanahan * @version $Revision$ $Date$ */ - public interface Lifecycle { @@ -118,8 +156,21 @@ public interface Lifecycle { /** * Prepare for the beginning of active use of the public methods of this * component. This method should be called before any of the public - * methods of this component are utilized. It should also send a - * LifecycleEvent of type START_EVENT to any registered listeners. + * methods of this component are utilized. The following + * {@link LifecycleEvent}s will be fired in the following order: + *
    + *
  1. BEFORE_START_EVENT: At the beginning of the method. It is as this + * point the state transitions to + * {@link LifecycleState#STARTING_PREP}.
  2. + *
  3. START_EVENT: During the method once it is safe to call start() for + * any child components. It is at this point that the + * state transitions to {@link LifecycleState#STARTING} + * and that the public methods may be used.
  4. + *
  5. AFTER_START_EVENT: At the end of the method, immediately before it + * returns. It is at this point that the state + * transitions to {@link LifecycleState#STARTED}. + *
  6. + *
* * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used @@ -129,14 +180,35 @@ public interface Lifecycle { /** * 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. It should also send a LifecycleEvent - * of type STOP_EVENT to any registered listeners. - * + * component. Once the STOP_EVENT is fired, the public methods should not + * be used. The following {@link LifecycleEvent}s will be fired in the + * following order: + *
    + *
  1. BEFORE_STOP_EVENT: At the beginning of the method. It is at this + * point that the state transitions to + * {@link LifecycleState#STOPPING_PREP}.
  2. + *
  3. STOP_EVENT: During the method once it is safe to call stop() for + * any child components. It is at this point that the + * state transitions to {@link LifecycleState#STOPPING} + * and that the public methods may no longer be used.
  4. + *
  5. AFTER_STOP_EVENT: At the end of the method, immediately before it + * returns. It is at this point that the state + * transitions to {@link LifecycleState#STOPPED}. + *
  6. + *
+ * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException; + /** + * Obtain the current state of the source component. + * + * @return The current state of the source component. + */ + // TODO Remove this comment once all components that implement Lifecycle + // have had this method added + //public LifecycleState getState(); } diff --git a/java/org/apache/catalina/LifecycleState.java b/java/org/apache/catalina/LifecycleState.java new file mode 100644 index 000000000..a569dc97f --- /dev/null +++ b/java/org/apache/catalina/LifecycleState.java @@ -0,0 +1,56 @@ +/* + * 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; + +/** + * The list of valid states for components that implement {@link Lifecycle}. + * See {@link Lifecycle} for the state transition diagram. + */ +public enum LifecycleState { + NEW(false, null), + STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT), + STARTING(true, Lifecycle.START_EVENT), + STARTED(true, Lifecycle.AFTER_START_EVENT), + STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT), + STOPPING(false, Lifecycle.STOP_EVENT), + STOPPED(false, Lifecycle.AFTER_STOP_EVENT), + FAILED(false, null), + MUST_STOP(true, null); + + private final boolean available; + private final String lifecycleEvent; + + private LifecycleState(boolean available, String lifecycleEvent) { + this.available = available; + this.lifecycleEvent = lifecycleEvent; + } + + /** + * Is a component in this state available for use? + */ + public boolean isAvailable() { + return available; + } + + /** + * + */ + public String getLifecycleEvent() { + return lifecycleEvent; + } +} -- 2.11.0