OK, I have an initial patch for this ready. I can commit it myself, but I wanted to post it as a warning as it has a few unresolved issues.

I have implemented the JSR77 state model in Component and AbstractComponent

For start and stop this was simple.   But I have also removed the
create and destroy methods for now.   I moved any create operations
I found to the start() (or doStart()) methods.

I have left destroy methods in the code, but noted that they are
currently not supported by the lifecycle.   I think they do contain
good cleanup code - but we could just rely on java finalize mechanism?
Or we could move the code into doStop to be symmetric with doStart.

I have implemented startRecursive in ContainerImpl - however, I really
think that we need an AbstractContainer class for this.   But this
would need a method for iterating over children in the Container interface.
As this is not there - I have not done this... more reading of JSR77 spec
required to support their container naming and methods I think?

In JSR77 there is no stopRecursive method - so ContainerImpl.stop is
actually recursive (which I think is the correct thing to do?) Again
this should be in AbstactContainer.

I'll give this a few hours for "DON'T DO IT" reponses and if I don't
get them I'll do the commit and we can work on the remaining issues.


-- Greg Wilkins<[EMAIL PROTECTED]> Phone/fax: +44 7092063462 Mort Bay Consulting Australia and UK. http://www.mortbay.com
Index: modules/core/src/java/org/apache/geronimo/common/AbstractComponent.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractComponent.java,v
retrieving revision 1.2
diff -r1.2 AbstractComponent.java
58d57
< 
68,69c67,70
< public class AbstractComponent implements Component {
<     private State state = State.NOT_CREATED;
---
> public class AbstractComponent implements Component
> {
>     private State state= State.STOPPED;
>     private long startTime;
71c72
<     protected Log log = LogFactory.getLog(getClass());
---
>     protected Log log= LogFactory.getLog(getClass());
73c74,75
<     public State getState() {
---
>     public State getState()
>     {
77,91c79,178
<     public final Container getContainer() {
<         return container;
<     }
< 
<     public final void setContainer(Container container) {
<         if (state != State.NOT_CREATED && state != State.DESTROYED) {
<             throw new IllegalStateException("Set container can only be called 
while in the not-created or destroyed states: state=" + state);
<         }
<         if (state == State.NOT_CREATED && container == null) {
<             throw new IllegalArgumentException("Interceptor has not been 
created; container must be NOT null.");
<         }
<         if (state == State.DESTROYED && container != null) {
<             throw new IllegalArgumentException("Interceptor has been 
destroyed; container must be null.");
<         }
<         this.container = container;
---
>     /**
>      * Set the Component state.
>      * @param newState
>      * @throws IllegalStateException Thrown if the transition is not 
> supported by the JSR77 lifecycle.
>      */
>     protected void setState(State newState) throws IllegalStateException
>     {
>         switch (state.getIndex())
>         {
>             case State.STOPPED_INDEX :
>                 {
>                     switch (state.getIndex())
>                     {
>                         case State.STARTING_INDEX :
>                             break;
>                         case State.STOPPED_INDEX :
>                         case State.RUNNING_INDEX :
>                         case State.STOPPING_INDEX :
>                         case State.FAILED_INDEX :
>                             throw new IllegalStateException(
>                                 "Can not transition to " + newState + " state 
> from " + state);
>                     }
>                     break;
>                 }
> 
>             case State.STARTING_INDEX :
>                 {
>                     switch (state.getIndex())
>                     {
>                         case State.RUNNING_INDEX :
>                         case State.FAILED_INDEX :
>                         case State.STOPPING_INDEX :
>                             break;
>                         case State.STOPPED_INDEX :
>                         case State.STARTING_INDEX :
>                             throw new IllegalStateException(
>                                 "Can not transition to " + newState + " state 
> from " + state);
>                     }
>                     break;
>                 }
> 
>             case State.RUNNING_INDEX :
>                 {
>                     switch (state.getIndex())
>                     {
>                         case State.STOPPING_INDEX :
>                         case State.FAILED_INDEX :
>                             break;
>                         case State.STOPPED_INDEX :
>                         case State.STARTING_INDEX :
>                         case State.RUNNING_INDEX :
>                             throw new IllegalStateException(
>                                 "Can not transition to " + newState + " state 
> from " + state);
> 
>                     }
>                     break;
>                 }
> 
>             case State.STOPPING_INDEX :
>                 {
>                     switch (state.getIndex())
>                     {
>                         case State.STOPPED_INDEX :
>                         case State.FAILED_INDEX :
>                             break;
>                         case State.STARTING_INDEX :
>                         case State.RUNNING_INDEX :
>                         case State.STOPPING_INDEX :
>                             throw new IllegalStateException(
>                                 "Can not transition to " + newState + " state 
> from " + state);
>                     }
>                     break;
>                 }
> 
>             case State.FAILED_INDEX :
>                 {
>                     switch (state.getIndex())
>                     {
>                         case State.STARTING_INDEX :
>                         case State.STOPPING_INDEX :
>                             break;
>                         case State.STOPPED_INDEX :
>                         case State.RUNNING_INDEX :
>                         case State.FAILED_INDEX :
>                             throw new IllegalStateException(
>                                 "Can not transition to " + newState + " state 
> from " + state);
>                     }
>                     break;
>                 }
>         }
>         log.debug("State changed from " + state + " to " + newState);
>         if (newState==State.RUNNING)
>             startTime= System.currentTimeMillis();
>         state= newState;
> 
>     }
> 
>     public long getStartTime()
>     {
>         return startTime;
94,98c181,183
<     public void create() throws Exception {
<         if (state != State.NOT_CREATED) {
<             throw new IllegalStateException("Can not transition to created 
state from " + state);
<         }
<         state = State.STOPPED;
---
>     public final Container getContainer()
>     {
>         return container;
101,105c186,249
<     public void start() throws Exception {
<         if (state != State.STOPPED) {
<             throw new IllegalStateException("Can not transition to started 
state from " + state);
<         }
<         state = State.STARTED;
---
>     public final void setContainer(Container container)
>     {
>         if (state != State.STOPPED)
>         {
>             throw new IllegalStateException(
>                 "Set container can only be called while in the stopped state: 
> state=" + state);
>         }
>         this.container= container;
>     }
> 
>     public void start() throws Exception
>     {
>         try
>         {
>             setState(State.STARTING);
>             doStart();
>             setState(State.RUNNING);
>         }
>         finally
>         {
>             if (state != State.RUNNING)
>                 setState(State.FAILED);
>         }
>     }
> 
>     public void startRecursive() throws Exception
>     {
>         start();
>     }
> 
>     /**
>      * Do the start tasks for the component.  Called in the STARTING state by 
>      * the start() and startRecursive() methods to perform the tasks required 
> to 
>      * start the component. The default implementation does nothing.
>      * @throws Exception
>      */
>     public void doStart() throws Exception
>     {
>     }
> 
>     public void stop()
>     {
>         // Do the actual stop tasks
>         try
>         {
>             setState(State.STOPPING);
>             doStop();
>             setState(State.STOPPED);
>         }
>         catch (Exception e)
>         {
>             log.warn("Stop failed", e);
>             setState(State.FAILED);
>         }
>     }
> 
>     /**
>      * Do the stop tasks for the component.  Called in the STOPPING state by 
> the stop()
>      * method to perform the tasks required to stop the component.
>      * This implementation does nothing.
>      * @throws Exception
>      */
>     public void doStop() throws Exception
>     {
108,122d251
<     public void stop() {
<         if (state == State.NOT_CREATED || state == State.DESTROYED) {
<             throw new IllegalStateException("Can not transition to started 
state from " + state);
<         } else if (state == State.STOPPED) {
<             log.warn("Stop called on an already stopped component; no 
exception will be thrown but this is a programming error.");
<         }
<         state = State.STOPPED;
<     }
< 
<     public void destroy() {
<         if (state != State.STOPPED) {
<             log.warn("Destroy called on an component in the " + state + " 
state; no exception will be thrown but this is a programming error.");
<         }
<         state = State.DESTROYED;
<     }
Index: modules/core/src/java/org/apache/geronimo/common/AbstractInterceptor.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractInterceptor.java,v
retrieving revision 1.2
diff -r1.2 AbstractInterceptor.java
73,80c73,74
<         if (state != State.NOT_CREATED && state != State.DESTROYED) {
<             throw new IllegalStateException("setNext can only be called while 
in the not-created or destroyed states: state=" + state);
<         }
<         if (state == State.NOT_CREATED && nextInterceptor == null) {
<             throw new IllegalArgumentException("Interceptor has not been 
created; nextInterceptor must be NOT null.");
<         }
<         if (state == State.DESTROYED && nextInterceptor != null) {
<             throw new IllegalArgumentException("Interceptor has been 
destroyed; nextInterceptor must be null.");
---
>         if (state != State.STOPPED) {
>             throw new IllegalStateException("setNext can only be called while 
> in the stopped state: state=" + state);
Index: modules/core/src/java/org/apache/geronimo/common/Component.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/Component.java,v
retrieving revision 1.2
diff -r1.2 Component.java
60c60
<  *
---
>  * Implements the JSR 77 state model
71a72,77
>       /**
>        * Gets the start time of this component
>        * @return time in milliseonds since epoch that this component was 
> started.
>        */
>       long getStartTime();
>       
90,103c96
<      * Transitions the component to the stopped state.  This method has 
access to the
<      * container. Once an component has been created setContainer() will 
throw IllegalStateException.
<      *
<      * Normally a component uses this to acquire references to other 
componets of the container. The
<      * components will all have been registered at this stage, but not 
necessarily
<      * created so methods should not be invoked on the reference until the 
start method.
<      *
<      * @throws java.lang.Exception if a problem occurs during the transition
<      * @throws java.lang.IllegalStateException if this interceptor is not in 
the not-created state
<      */
<     void create() throws Exception, IllegalStateException;
< 
<     /**
<      * Transitions the component to the started state.  This method has 
access to the
---
>      * Transitions the component to the starting state.  This method has 
> access to the
111c104
<      * @throws java.lang.IllegalStateException if this interceptor is not in 
the stopped state
---
>      * @throws java.lang.IllegalStateException if this interceptor is not in 
> the stopped or failed state
114a108,122
>       /**
>        * Transitions the component to the starting state.  This method has 
> access to the
>        * container.
>        * 
>        * If this Component is a Container, then startRecursive is called on 
> all child Components
>        * that are in the STOPPED or FAILED state.
>        * Normally a component uses this to cache data from other components. 
> The other components will
>        * have been created at this stage, but not necessairly started and may 
> not be ready to have methods
>        * invoked on them.
>        *
>        * @throws java.lang.Exception if a problem occurs during the transition
>        * @throws java.lang.IllegalStateException if this interceptor is not 
> in the STOPPED or FAILED state
>        */
>       void startRecursive() throws Exception, IllegalStateException;
> 
116c124
<      * Transitions the component to the stopped state.  This method has 
access to the
---
>      * Transitions the component to the stopping state.  This method has 
> access to the
118a127,129
>        * If this is Component is a Container, then all its child components 
> must be in the 
>        * STOPPED or FAILED State.
>        * 
123c134,136
<     void stop();
---
>     void stop() throws IllegalStateException;
>     
> 
125,135d137
<     /**
<      * Transitions the component to the destroyed state.  This method has 
access to the
<      * container.  Once a component has been destroyed, it can not be 
recreated with the i
<      * create method.  If the create method is called on an destroyed 
component an
<      * IllegalStateException will be thrown.
<      *
<      * Normally a component uses this to drop references to components cached 
in the create method.
<      * The other components will not necessairly have been destroyed at this 
stage, but may have been
<      * stopped somethods should not be called on other components.
<      */
<     void destroy();
Index: modules/core/src/java/org/apache/geronimo/common/State.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/State.java,v
retrieving revision 1.2
diff -r1.2 State.java
65,69c65,77
<     public static final State NOT_CREATED = new State("not-created");
<     public static final State STOPPED = new State("stopped");
<     public static final State STARTED = new State("started");
<     public static final State DESTROYED = new State("destroyed");
< 
---
>       
>       public static final int STARTING_INDEX=0;
>       public static final int RUNNING_INDEX=1;
>       public static final int STOPPING_INDEX=2;
>       public static final int STOPPED_INDEX=3;
>       public static final int FAILED_INDEX=4;
>       
>     public static final State STARTING = new State("starting",STARTING_INDEX);
>     public static final State RUNNING = new State("running",RUNNING_INDEX);
>       public static final State STOPPING = new 
> State("stopping",STOPPING_INDEX);
>       public static final State STOPPED = new State("stopped",STOPPED_INDEX);
>       public static final State FAILED = new State("failed",FAILED_INDEX);
>       
71,72c79,81
< 
<     private State(String name) {
---
>       private final int index;
>       
>     private State(String name, int index) {
73a83
>         this.index = index;
75a86,89
>       public int getIndex() { 
>               return index;
>       }
>       
Index: modules/core/src/java/org/apache/geronimo/ejb/EJBProxyFactoryManager.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/ejb/EJBProxyFactoryManager.java,v
retrieving revision 1.3
diff -r1.3 EJBProxyFactoryManager.java
76,87d75
<     public void create() throws Exception {
<         log.debug("Creating EJBProxyFactoryManager: ejbName=" + 
EJBPlugins.getEJBMetadata(getContainer()).getName());
<         super.create();
<         for (Iterator iterator = proxies.keySet().iterator(); 
iterator.hasNext();) {
<             String proxyName = (String) iterator.next();
<             EJBProxyFactory ejbProxyFactory = getEJBProxyFactory(proxyName);
<             // @todo uncomment this when the ejb proxy factories are rewriten 
to be full components
<             //ejbProxyFactory.setContainer(getContainer());
<             log.debug("Creating EJBProxyFactory: proxyName=" + proxyName + " 
ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
<             ejbProxyFactory.create();
<         }
<     }
89c77
<     public void start() throws Exception {
---
>     public void doStart() throws Exception {
91c79,80
<         super.start();
---
> 
>         // @todo This should be handled by startRecursive()
100c89
<     public void stop() {
---
>     public void doStop() {
102c91,92
<         super.stop();
---
>  
>         // @todo This will not work when this is a container, as children 
> must be stopped before stop() is called.
110a101,104
> 
>     /**
>      * @todo Currently not part of the Component lifecycle (due to jsr77)
>      */
112,121d105
<         log.debug("Destroying EJBProxyFactoryManager: ejbName=" + 
EJBPlugins.getEJBMetadata(getContainer()).getName());
<         super.destroy();
<         for (Iterator iterator = proxies.keySet().iterator(); 
iterator.hasNext();) {
<             String proxyName = (String) iterator.next();
<             EJBProxyFactory ejbProxyFactory = getEJBProxyFactory(proxyName);
<             log.debug("Destroying EJBProxyFactory: proxyName=" + proxyName + 
" ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
<             ejbProxyFactory.destroy();
<             // @todo uncomment this when the ejb proxy factories are rewriten 
to be full components
<             //ejbProxyFactory.setContainer(null);
<         }
Index: 
modules/core/src/java/org/apache/geronimo/ejb/cache/EnterpriseContextInstancePool.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/ejb/cache/EnterpriseContextInstancePool.java,v
retrieving revision 1.3
diff -r1.3 EnterpriseContextInstancePool.java
82,89c82,87
<     public void create() throws Exception {
<         super.create();
<         pool = new 
SimpleInstancePool(EJBPlugins.getInstanceFactory(getContainer()), maxSize, 
hardLimit);
<         discardQueue = new DiscardQueue();
<     }
< 
<     public void start() throws Exception {
<         super.start();
---
>     public void doStart() throws Exception {
>         if (pool==null)
>             pool = new 
> SimpleInstancePool(EJBPlugins.getInstanceFactory(getContainer()), maxSize, 
> hardLimit);
>         if (discardQueue==null)
>             discardQueue = new DiscardQueue();
>         
92a91
>     // @todo Destroy not part of jsr77 lifecycle
107,108d105
< 
<         super.destroy();
Index: 
modules/core/src/java/org/apache/geronimo/ejb/container/ContainerImpl.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/ejb/container/ContainerImpl.java,v
retrieving revision 1.3
diff -r1.3 ContainerImpl.java
76c76,79
<  *
---
>  * @todo Currently this class implements the startRecursive method of 
>  * the JSR77 lifecycle. This should be moved to an AbstractContainer class
>  * @todo The stop method is implemented as stopRecursive, which is not 
>  * supported by jsr77
101,109c104,118
<     public void create() throws Exception {
<         super.create();
<         // Create all the interceptors in forward insertion order
<         for (Iterator iterator = pluginObjects.values().iterator(); 
iterator.hasNext();) {
<             Object object = iterator.next();
<             if (object instanceof Component) {
<                 Component component = (Component) object;
<                 component.setContainer(this);
<                 component.create();
---
> 
>     public void startRecursive() throws Exception
>     {
>         try
>         {
>             // start this component
>             setState(State.STARTING);
>            
>             // Start all the components in forward insertion order
>             for (Iterator iterator = pluginObjects.values().iterator(); 
> iterator.hasNext();) {
>                 Object object = iterator.next();
>                 if (object instanceof Component) {
>                     Component component = (Component) object;
>                     component.startRecursive();
>                 }
111d119
<         }
113,117c121,129
<         // Create all the plugins in forward insertion order
<         for (Iterator iterator = interceptors.iterator(); 
iterator.hasNext();) {
<             Interceptor interceptor = (Interceptor) iterator.next();
<             interceptor.setContainer(this);
<             interceptor.create();
---
>             // Start this component
>             doStart();
>             
>             setState(State.RUNNING);
>         }
>         finally
>         {
>             if (getState() != State.RUNNING)
>                 setState(State.FAILED);
120,131c132,133
< 
<     public void start() throws Exception {
<         super.start();
<         // Start all the interceptors in forward insertion order
<         for (Iterator iterator = pluginObjects.values().iterator(); 
iterator.hasNext();) {
<             Object object = iterator.next();
<             if (object instanceof Component) {
<                 Component component = (Component) object;
<                 component.start();
<             }
<         }
< 
---
>     
>     public void doStart() throws Exception {
140,144d141
<         // Stop all the interceptors in reverse insertion order
<         for (ListIterator iterator = 
interceptors.listIterator(interceptors.size()); iterator.hasPrevious();) {
<             Interceptor interceptor = (Interceptor) iterator.previous();
<             interceptor.stop();
<         }
145a143,144
>         // @todo this is actually a stopRecursive, which is not supported
>         // by JSR77
158a158
>         // Stop this component
160a161
>     
162,163c163,164
<     public void destroy() {
<         // Destroy all the interceptors in reverse insertion order
---
>     public void doStop() {
>         // Stop all the interceptors in reverse insertion order
166,181c167
<             interceptor.destroy();
<             interceptor.setContainer(null);
<         }
< 
<         // Destroy all the plugins in reverse insertion order
<         LinkedList list = new LinkedList();
<         for (Iterator iterator = pluginObjects.values().iterator(); 
iterator.hasNext();) {
<             Object object = iterator.next();
<             if (object instanceof Component) {
<                 list.addFirst(object);
<             }
<         }
<         for (Iterator iterator = list.iterator(); iterator.hasNext();) {
<             Component component = (Component) iterator.next();
<             component.destroy();
<             component.setContainer(null);
---
>             interceptor.stop();
182a169
>     }
183a171,173
>     // @todo destroy not supported in JSR77 lifecycle, needs to be
>     // integrated or removed.
>     public void destroy() {
186d175
<         super.destroy();
195,199c184,185
<         if (state != State.NOT_CREATED && state != State.DESTROYED) {
<             throw new IllegalStateException("putPluginObject can only be 
called while in the not-created or destroyed states: state=" + state);
<         }
<         if (state == State.NOT_CREATED && objectName == null) {
<             throw new IllegalArgumentException("Container has not been 
created; objectName must be NOT null.");
---
>         if (state != State.STOPPED) {
>             throw new IllegalStateException("putPluginObject can only be 
> called while in the stopped state: state=" + state);
201,204d186
<         if (state == State.DESTROYED && objectName != null) {
<             throw new IllegalArgumentException("Container has been destroyed; 
objectName must be null.");
<         }
< 
214c196
<         if (state != State.NOT_CREATED && state != State.DESTROYED) {
---
>         if (state != State.STOPPED) {
217,223d198
<         if (state == State.NOT_CREATED && plugin == null) {
<             throw new IllegalArgumentException("Container has not been 
created; plugin must be NOT null.");
<         }
<         if (state == State.DESTROYED && plugin != null) {
<             throw new IllegalArgumentException("Container has been destroyed; 
plugin must be null.");
<         }
< 
Index: 
modules/core/src/java/org/apache/geronimo/ejb/context/TransactionInterceptor.java
===================================================================
RCS file: 
/home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/ejb/context/TransactionInterceptor.java,v
retrieving revision 1.3
diff -r1.3 TransactionInterceptor.java
80a81,84
>     public long getStartTime(){
>         return transactionInterceptor.getStartTime();
>     }
> 
97c101
<     public void create() throws Exception {
---
>     public void start() throws Exception {
106,109d109
<         transactionInterceptor.create();
<     }
< 
<     public void start() throws Exception {
111a112,115
>     
>     public void startRecursive() throws Exception {
>         transactionInterceptor.startRecursive();
>     }
116a121
>     // @todo not supported by JSR77 lifecycle 
118d122
<         transactionInterceptor.destroy();

Reply via email to