Author: jmarino
Date: Thu Apr 13 17:18:23 2006
New Revision: 393986

URL: http://svn.apache.org/viewcvs?rev=393986&view=rev
Log:
refactor of scope contexts

Modified:
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -64,7 +64,7 @@
 
     /**
      * Removes a context bound to the given name and scope key
-     * 
+     *
      * @throws ScopeRuntimeException
      */
     public void removeContextByKey(String name, Object key) throws 
ScopeRuntimeException;

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -22,7 +22,6 @@
 import org.apache.tuscany.core.context.QualifiedName;
 import org.apache.tuscany.core.context.ScopeContext;
 import org.apache.tuscany.core.context.TargetException;
-import org.apache.tuscany.core.context.AtomicContext;
 import org.apache.tuscany.core.context.impl.AbstractContext;
 
 import java.util.List;
@@ -31,16 +30,13 @@
 
 /**
  * Implements functionality common to scope contexts.
- * <p>
- * <b>NB: </b>Minimal synchronization is performed, particularly for 
initializing and destroying scopes, and it is
- * assumed the scope container will block requests until these operations have 
completed.
- * 
+ *
  * @version $Rev$ $Date$
  */
 public abstract class AbstractScopeContext extends AbstractContext implements 
ScopeContext {
 
     // The collection of runtime configurations for the scope
-    protected Map<String, ContextFactory<Context>> contextFactorys = new 
ConcurrentHashMap<String, ContextFactory<Context>>();
+    protected Map<String, ContextFactory<Context>> contextFactories = new 
ConcurrentHashMap<String, ContextFactory<Context>>();
 
     // The event context the scope container is associated with
     protected EventContext eventContext;
@@ -52,7 +48,7 @@
 
     public void registerFactories(List<ContextFactory<Context>> 
configurations) {
         for (ContextFactory<Context> configuration : configurations) {
-            contextFactorys.put(configuration.getName(), configuration);
+            contextFactories.put(configuration.getName(), configuration);
         }
     }
 
@@ -66,52 +62,13 @@
         return context.getInstance(qName);
     }
 
-    protected EventContext getEventContext() {
-        return eventContext;
-    }
-
-    /**
-     * Notfies instances that are associated with a context and configured to 
receive callbacks that the context is
-     * being destroyed in reverse order
-     * 
-     * @param key the context key
-     */
-    protected void notifyInstanceShutdown(Object key) {
-        Context[] contexts = getShutdownContexts(key);
-        if ((contexts == null) || (contexts.length < 1)) {
-            return;
-        }
-        // shutdown destroyable instances in reverse instantiation order
-        for (int i = contexts.length - 1; i >= 0; i--) {
-            Context context = contexts[i];
-
-            if (context.getLifecycleState() == RUNNING) {
-                synchronized (context) {
-                    removeContextByKey(context.getName(), key);
-                    try {
-                        if (context instanceof AtomicContext){
-                            ((AtomicContext)context).destroy();
-                        }
-                        context.stop();
-                    } catch (TargetException e) {
-                        // TODO send a monitoring event
-                        // log.error("Error releasing instance [" + 
context.getName() + "]",e);
-                    }
-                }
-            }
-        }
-    }
-
     protected void checkInit() {
         if (lifecycleState != RUNNING) {
             throw new IllegalStateException("Scope not running [" + 
lifecycleState + "]");
         }
     }
 
-    /**
-     * Returns an array of contexts that need to be notified of scope 
shutdown. The array must be in the order in which
-     * component contexts were created
-     */
-    protected abstract Context[] getShutdownContexts(Object key);
-
+    protected EventContext getEventContext() {
+        return eventContext;
+    }
 }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -143,7 +143,6 @@
         }
         // propagate events to child contexts
         for (CompositeContext context : contexts.values()) {
-            System.out.println("context"+context);
             context.publish(event);
         }
     }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -21,28 +21,29 @@
 import org.apache.tuscany.core.context.Context;
 import org.apache.tuscany.core.context.CoreRuntimeException;
 import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.TargetException;
 import org.apache.tuscany.core.context.event.ContextCreatedEvent;
+import org.apache.tuscany.core.context.event.Event;
 import org.apache.tuscany.core.context.event.ModuleStartEvent;
 import org.apache.tuscany.core.context.event.ModuleStopEvent;
-import org.apache.tuscany.core.context.event.Event;
 
 import java.util.Map;
-import java.util.Queue;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 /**
  * Manages component contexts whose implementations are module scoped
  *
  * @version $Rev$ $Date$
  */
-public class ModuleScopeContext extends AbstractScopeContext implements 
RuntimeEventListener {
+public class ModuleScopeContext extends AbstractScopeContext {
 
     // Component contexts in this scope keyed by name
     private Map<String, Context> componentContexts;
 
-    private Queue<AtomicContext> destroyableContexts;
+    private List<Context> destroyableContexts;
 
     public ModuleScopeContext(EventContext eventContext) {
         super(eventContext);
@@ -54,7 +55,7 @@
             lifecycleState = RUNNING;
             initComponentContexts();
         } else if (event instanceof ModuleStopEvent) {
-            notifyInstanceShutdown(null);
+            notifyInstanceShutdown();
         } else if (event instanceof ContextCreatedEvent) {
             checkInit();
             if (event.getSource() instanceof AtomicContext) {
@@ -73,8 +74,7 @@
         }
     }
 
-    public synchronized void stop
-            () {
+    public synchronized void stop() {
         if (lifecycleState != RUNNING) {
             throw new IllegalStateException("Scope in wrong state [" + 
lifecycleState + "]");
         }
@@ -83,74 +83,83 @@
         lifecycleState = STOPPED;
     }
 
-    public boolean isCacheable
-            () {
+    public boolean isCacheable() {
         return true;
     }
 
     public void registerFactory
             (ContextFactory<Context> configuration) {
-        contextFactorys.put(configuration.getName(), configuration);
+        contextFactories.put(configuration.getName(), configuration);
         if (lifecycleState == RUNNING) {
             componentContexts.put(configuration.getName(), 
configuration.createContext());
         }
     }
 
-    public Context getContext
-            (String
-                    ctxName) {
+    public Context getContext(String ctxName) {
         checkInit();
+        initComponentContexts();
         return componentContexts.get(ctxName);
     }
 
-    public Context getContextByKey
-            (String
-                    ctxName, Object
-                    key) {
+    public Context getContextByKey(String ctxName, Object key) {
         checkInit();
+        initComponentContexts();
         return componentContexts.get(ctxName);
     }
 
-    public void removeContext
-            (String
-                    ctxName) {
+    public void removeContext(String ctxName) {
         checkInit();
+        if (componentContexts == null){
+            return;
+        }
         Context context = componentContexts.remove(ctxName);
         if (context != null) {
             destroyableContexts.remove(context);
         }
     }
 
-    public void removeContextByKey
-            (String
-                    ctxName, Object
-                    key) {
-        checkInit();
+    public void removeContextByKey(String ctxName, Object key){
         removeContext(ctxName);
     }
 
+
     /**
-     * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing 
components that need to be notified of scope shutdown.
+     * Notfies instances that are associated with a context and configured to 
receive callbacks that the context is
+     * being destroyed in reverse order
      */
-    protected Context[] getShutdownContexts
-            (Object
-                    key) {
-        if (destroyableContexts != null) {
-            // create 0-length array since Queue.size() has O(n) traversal
-            return destroyableContexts.toArray(new Context[0]);
-        } else {
-            return null;
+    private synchronized void notifyInstanceShutdown() {
+        if (destroyableContexts == null || destroyableContexts.size() == 0) {
+            return;
+        }
+        // shutdown destroyable instances in reverse instantiation order
+        ListIterator<Context> iter = 
destroyableContexts.listIterator(destroyableContexts.size());
+        while(iter.hasPrevious()){
+            Context context = iter.previous();
+            if (context.getLifecycleState() == RUNNING) {
+                synchronized (context) {
+                    //removeContextByKey(context.getName(), key);
+                    try {
+                        if (context instanceof AtomicContext){
+                            ((AtomicContext)context).destroy();
+                        }
+                        context.stop();
+                    } catch (TargetException e) {
+                        // TODO send a monitoring event
+                        // log.error("Error releasing instance [" + 
context.getName() + "]",e);
+                    }
+                }
+            }
         }
-    }
+        componentContexts = null;
+        destroyableContexts = null;
+     }
 
-    private synchronized void initComponentContexts
-            () throws CoreRuntimeException {
+    private synchronized void initComponentContexts() throws 
CoreRuntimeException {
         if (componentContexts == null) {
             componentContexts = new ConcurrentHashMap<String, Context>();
-            destroyableContexts = new ConcurrentLinkedQueue<AtomicContext>();
-            for (ContextFactory<Context> config : contextFactorys.values()) {
+            destroyableContexts = new ArrayList<Context>();
+            for (ContextFactory<Context> config : contextFactories.values()) {
                 Context context = config.createContext();
-                context.addListener(this);
                 context.start();
                 componentContexts.put(context.getName(), context);
             }
@@ -163,10 +172,11 @@
                         // perform silent creation and manual shutdown 
registration
                         atomic.init();
                         //if (atomic.isDestroyable()) {
-                         destroyableContexts.add(atomic);
                         //}
                     }
                 }
+                context.addListener(this);
+                destroyableContexts.add(context);
             }
         }
     }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -18,33 +18,33 @@
 
 import org.apache.tuscany.core.builder.ContextFactory;
 import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
 import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
 import org.apache.tuscany.core.context.AtomicContext;
-import org.apache.tuscany.core.context.CoreRuntimeException;
-import org.apache.tuscany.core.context.event.RequestEndEvent;
+import org.apache.tuscany.core.context.TargetException;
 import org.apache.tuscany.core.context.event.ContextCreatedEvent;
 import org.apache.tuscany.core.context.event.Event;
-import org.apache.tuscany.core.context.event.HttpSessionEvent;
+import org.apache.tuscany.core.context.event.RequestEndEvent;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
-import java.util.Queue;
+import java.util.ListIterator;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 /**
  * An implementation of a request-scoped component container.
  * 
  * @version $Rev$ $Date$
  */
-public class RequestScopeContext extends AbstractScopeContext implements 
RuntimeEventListener {
+public class RequestScopeContext extends AbstractScopeContext {
 
     // A collection of service component contexts keyed by thread. Note this 
could have been implemented with a ThreadLocal but
     // using a Map allows finer-grained concurrency.
-    private Map<Object, Map<String, Context>> contextMap;
+    private Map<Object, Map<String, Context>> contexts;
 
     // stores ordered lists of contexts to shutdown for each thread.
-    private Map<Object, Queue<AtomicContext>> destroyComponents;
+    private Map<Object, List<Context>> destroyQueues;
 
     public RequestScopeContext(EventContext eventContext) {
         super(eventContext);
@@ -54,40 +54,34 @@
     public void onEvent(Event event){
         /* clean up current context for pooled threads */
         if (event instanceof RequestEndEvent){
-                checkInit();
-                getEventContext().clearIdentifiers();
-                notifyInstanceShutdown(Thread.currentThread());
-                destroyContext();
+            checkInit();
+            getEventContext().clearIdentifiers();
+            shutdownContexts();
+            cleanupRequestContexts();
         }else if (event instanceof ContextCreatedEvent){
-                checkInit();
-                assert(event.getSource() instanceof Context): "Context must be 
passed on created event";
-                Context context = (Context)event.getSource();
-                if (context instanceof AtomicContext) {
-                    AtomicContext atomic = (AtomicContext)context;
-                    // Queue the context to have its implementation instance 
released if destroyable
-                    //if (atomic.isDestroyable()) {
-                        Queue<AtomicContext> collection = 
destroyComponents.get(Thread.currentThread());
-                        collection.add(atomic);
-                    //}
-                }
+            checkInit();
+            assert(event.getSource() instanceof Context): "Context must be 
passed on created event";
+            Context context = (Context)event.getSource();
+            List<Context> collection = 
destroyQueues.get(Thread.currentThread());
+            collection.add(context);
         }
     }
+
     public synchronized void start() {
         if (lifecycleState != UNINITIALIZED) {
             throw new IllegalStateException("Scope must be in UNINITIALIZED 
state [" + lifecycleState + "]");
         }
-        contextMap = new ConcurrentHashMap<Object, Map<String, Context>>();
-        destroyComponents = new ConcurrentHashMap<Object, 
Queue<AtomicContext>>();
+        contexts = new ConcurrentHashMap<Object, Map<String, Context>>();
+        destroyQueues = new ConcurrentHashMap<Object, List<Context>>();
         lifecycleState = RUNNING;
-
     }
 
     public synchronized void stop() {
         if (lifecycleState != RUNNING) {
             throw new IllegalStateException("Scope in wrong state [" + 
lifecycleState + "]");
         }
-        contextMap = null;
-        destroyComponents = null;
+        contexts = null;
+        destroyQueues = null;
         lifecycleState = STOPPED;
     }
 
@@ -96,19 +90,19 @@
     }
 
     public void registerFactory(ContextFactory<Context> configuration) {
-        contextFactorys.put(configuration.getName(), configuration);
+        contextFactories.put(configuration.getName(), configuration);
     }
 
     public Context getContext(String ctxName) {
         checkInit();
-        Map<String, Context> contexts = getComponentContexts();
+        Map<String, Context> contexts = getContexts();
         Context ctx = contexts.get(ctxName);
         if (ctx == null){
             // check to see if the configuration was added after the request 
was started
-            ContextFactory<Context> configuration = 
contextFactorys.get(ctxName);
+            ContextFactory<Context> configuration = 
contextFactories.get(ctxName);
             if (configuration != null) {
                 ctx = configuration.createContext();
-                ctx.addListener(this);
+                //ctx.addListener(this);
                 ctx.start();
                 contexts.put(ctx.getName(), ctx);
             }
@@ -121,7 +115,7 @@
         if (key == null) {
             return null;
         }
-        Map<String, Context> components = contextMap.get(key);
+        Map<String, Context> components = contexts.get(key);
         if (components == null) {
             return null;
         }
@@ -129,7 +123,6 @@
     }
 
     public void removeContext(String ctxName) {
-        checkInit();
         removeContextByKey(ctxName, Thread.currentThread());
     }
 
@@ -138,37 +131,24 @@
         if (key == null || ctxName == null) {
             return;
         }
-        Map components = contextMap.get(key);
+        Map components = contexts.get(key);
         if (components == null) {
             return;
         }
         components.remove(ctxName);
-        Map<String, Context> contexts = contextMap.get(key);
+        //Map<String, Context> contexts = contexts.get(key);
         // no synchronization for the following two operations since the 
request
         // context will not be shutdown before the second call is processed
-        Context context = contexts.get(ctxName);
-        destroyComponents.get(key).remove(context);
+        //Context context = contexts.get(ctxName);
+        //destroyQueues.get(key).remove(context);
     }
 
 
-    /**
-     * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing 
components that need to be notified of scope shutdown.
-     */
-    protected Context[] getShutdownContexts(Object key) {
-        checkInit();
-        Queue<AtomicContext> queue = 
destroyComponents.get(Thread.currentThread());
-        if (queue != null) {
-            // create 0-length array since Queue.size() has O(n) traversal
-            return queue.toArray(new Context[0]);
-        } else {
-            return null;
-        }
-    }
 
-    private void destroyContext() {
+    private void cleanupRequestContexts() {
         // TODO uninitialize all request-scoped components
-        contextMap.remove(Thread.currentThread());
-        destroyComponents.remove(Thread.currentThread());
+        contexts.remove(Thread.currentThread());
+        destroyQueues.remove(Thread.currentThread());
     }
 
     /**
@@ -180,21 +160,47 @@
      * TODO Eager initialization is not performed for request-scoped components
      */
 
-    private Map<String, Context> getComponentContexts() throws 
CoreRuntimeException {
-        Map<String, Context>  contexts = 
contextMap.get(Thread.currentThread());
+    private Map<String, Context> getContexts() throws CoreRuntimeException {
+        Map<String, Context>  contexts = 
this.contexts.get(Thread.currentThread());
         if (contexts == null) {
             contexts = new ConcurrentHashMap<String, Context>();
-            Queue<AtomicContext> shutdownQueue = new 
ConcurrentLinkedQueue<AtomicContext>();
-            for (ContextFactory<Context> config : contextFactorys.values()) {
+            List<Context> shutdownQueue = new ArrayList<Context>();
+            for (ContextFactory<Context> config : contextFactories.values()) {
                 Context context = config.createContext();
-                context.addListener(this);
                 context.start();
                 contexts.put(context.getName(), context);
+                context.addListener(this);
             }
-            contextMap.put(Thread.currentThread(), contexts);
-            destroyComponents.put(Thread.currentThread(), shutdownQueue);
+            this.contexts.put(Thread.currentThread(), contexts);
+            destroyQueues.put(Thread.currentThread(), shutdownQueue);
         }
         return contexts;
     }
+
+    private synchronized void shutdownContexts() {
+          List<Context> contexts = destroyQueues.get(Thread.currentThread());
+          if (contexts == null || contexts.size() == 0) {
+             return;
+          }
+          // shutdown destroyable instances in reverse instantiation order
+          ListIterator<Context> iter = contexts.listIterator(contexts.size());
+          while(iter.hasPrevious()){
+              Context context = iter.previous();
+              if (context.getLifecycleState() == RUNNING) {
+                  synchronized (context) {
+                      //removeContextByKey(context.getName(), key);
+                      try {
+                          if (context instanceof AtomicContext){
+                              ((AtomicContext)context).destroy();
+                          }
+                          context.stop();
+                      } catch (TargetException e) {
+                          // TODO send a monitoring event
+                          // log.error("Error releasing instance [" + 
context.getName() + "]",e);
+                      }
+                  }
+              }
+          }
+      }
 
 }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -21,17 +21,18 @@
 import org.apache.tuscany.core.context.Context;
 import org.apache.tuscany.core.context.CoreRuntimeException;
 import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
 import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.TargetException;
 import org.apache.tuscany.core.context.event.ContextCreatedEvent;
 import org.apache.tuscany.core.context.event.Event;
 import org.apache.tuscany.core.context.event.HttpSessionEvent;
 import org.apache.tuscany.core.context.event.SessionEndEvent;
 
 import java.util.Map;
-import java.util.Queue;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 /**
  * An implementation of an session-scoped component container
@@ -40,13 +41,13 @@
  * 
  * @version $Rev$ $Date$
  */
-public class SessionScopeContext extends AbstractScopeContext implements 
RuntimeEventListener {
+public class SessionScopeContext extends AbstractScopeContext {
 
     // The collection of service component contexts keyed by session
     private Map<Object, Map<String, Context>> contexts;
 
     // Stores ordered lists of contexts to shutdown keyed by session
-    private Map<Object, Queue<AtomicContext>> destroyableContexts;
+    private Map<Object, List<Context>> destroyQueues;
 
     public SessionScopeContext(EventContext eventContext) {
         super(eventContext);
@@ -58,7 +59,7 @@
             throw new IllegalStateException("Scope container must be in 
UNINITIALIZED state");
         }
         contexts = new ConcurrentHashMap<Object, Map<String, Context>>();
-        destroyableContexts = new ConcurrentHashMap<Object, 
Queue<AtomicContext>>();
+        destroyQueues = new ConcurrentHashMap<Object, List<Context>>();
         lifecycleState = RUNNING;
     }
 
@@ -68,7 +69,7 @@
         }
         contexts = null;
         contexts = null;
-        destroyableContexts = null;
+        destroyQueues = null;
         lifecycleState = STOPPED;
     }
 
@@ -76,24 +77,27 @@
         if (event instanceof SessionEndEvent){
             checkInit();
             Object key = ((SessionEndEvent)event).getId();
-            notifyInstanceShutdown(key);
+            shutdownContexts(key);
             destroyComponentContext(key);
         }else if(event instanceof ContextCreatedEvent){
             checkInit();
-            if (event.getSource() instanceof AtomicContext) {
-                 AtomicContext simpleCtx = (AtomicContext)event.getSource();
-                 // if destroyable, queue the context to have its component 
implementation instance released
-                 if (simpleCtx.isDestroyable()) {
-                     Object sessionKey = 
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
-                     Queue<AtomicContext> comps = 
destroyableContexts.get(sessionKey);
-                     if (comps == null) {
-                         ScopeRuntimeException e = new 
ScopeRuntimeException("Shutdown queue not found for key");
-                         e.setIdentifier(sessionKey.toString());
-                         throw e;
-                     }
-                     comps.add(simpleCtx);
-                 }
-            }
+            Object sessionKey = 
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
+            List<Context> contexts = destroyQueues.get(sessionKey);
+            Context context = (Context)event.getSource();
+            assert(contexts != null): "Shutdown queue not found for key";
+
+//            if (context instanceof AtomicContext) {
+//                 AtomicContext atomic = (AtomicContext)event.getSource();
+//                 // if destroyable, queue the context to have its component 
implementation instance released
+//                 if (atomic.isDestroyable()) {
+//                     if (contexts == null) {
+//                         ScopeRuntimeException e = new 
ScopeRuntimeException("Shutdown queue not found for key");
+//                         e.setIdentifier(sessionKey.toString());
+//                         throw e;
+//                     }
+//                 }
+//            }
+            contexts.add(context);
         }
     }
 
@@ -102,43 +106,44 @@
     }
 
     public void registerFactory(ContextFactory<Context> configuration) {
-        contextFactorys.put(configuration.getName(), configuration);
+        contextFactories.put(configuration.getName(), configuration);
     }
 
     public Context getContext(String ctxName) {
+        assert(ctxName != null): "No context name specified";
         checkInit();
-        if (ctxName == null) {
-            return null;
-        }
-        // try{
-        Map<String, Context> ctxs = getSessionContext();
-        if (ctxs == null) {
-            return null;
-        }
-        Context ctx = ctxs.get(ctxName);
-        if (ctx == null) {
+        Map<String, Context> ctxs = getSessionContexts();
+        Context context = ctxs.get(ctxName);
+        if (context == null) {
             // the configuration was added after the session had started, so 
create a context now and start it
-            ContextFactory<Context> configuration = 
contextFactorys.get(ctxName);
+            ContextFactory<Context> configuration = 
contextFactories.get(ctxName);
             if (configuration != null) {
-                ctx = configuration.createContext();
-                ctx.addListener(this);
-                ctx.start();
-                ctxs.put(ctx.getName(), ctx);
+                context = configuration.createContext();
+                context.start();
+                if (context instanceof AtomicContext){
+                    ((AtomicContext)context).init();
+                }
+
+                ctxs.put(context.getName(), context);
+                List<Context> shutdownQueue = 
destroyQueues.get(getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER));
+                synchronized(shutdownQueue){
+                    shutdownQueue.add(context);
+                }
+                context.addListener(this);
             }
         }
-        return ctx;
+        return context;
     }
 
     public Context getContextByKey(String ctxName, Object key) {
         checkInit();
-        if (key == null && ctxName == null) {
-            return null;
-        }
-        Map components = contexts.get(key);
-        if (components == null) {
+        assert(ctxName != null): "No context name specified";
+        assert(key != null): "No key specified";
+        Map ctxs = contexts.get(key);
+        if (ctxs == null) {
             return null;
         }
-        return (Context) components.get(ctxName);
+        return (Context) ctxs.get(ctxName);
     }
 
     public void removeContext(String ctxName) {
@@ -149,9 +154,8 @@
 
     public void removeContextByKey(String ctxName, Object key) {
         checkInit();
-        if (key == null || ctxName == null) {
-            return;
-        }
+        assert(ctxName != null): "No context name specified";
+        assert(key != null): "No key specified";
         Map components = contexts.get(key);
         if (components == null) {
             return;
@@ -160,33 +164,15 @@
         Map<String, Context> definitions = contexts.get(key);
         Context ctx = definitions.get(ctxName);
         if (ctx != null){
-            destroyableContexts.get(key).remove(ctx);
+            destroyQueues.get(key).remove(ctx);
         }
         definitions.remove(ctxName);
     }
 
-
-    /**
-     * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing 
components that need to be notified of scope shutdown or
-     * null if none found.
-     */
-    protected Context[] getShutdownContexts(Object key) {
-        /*
-         * This method will be called from the Listener which is associated 
with a different thread than the request. So, just
-         * grab the key directly
-         */
-        Queue<AtomicContext> queue = destroyableContexts.get(key);
-        if (queue != null) {
-            // create 0-length array since Queue.size() has O(n) traversal
-            return queue.toArray(new AtomicContext[0]);
-        }
-        return null;
-    }
-
     /**
      * Returns and, if necessary, creates a context for the current sesion
      */
-    private Map<String, Context> getSessionContext() throws 
CoreRuntimeException {
+    private Map<String, Context> getSessionContexts() throws 
CoreRuntimeException {
         Object key = 
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
         if (key == null) {
             throw new ScopeRuntimeException("Session key not set in request 
context");
@@ -195,29 +181,29 @@
         if (m != null) {
             return m; // already created, return
         }
-        Map<String, Context> sessionContext = new ConcurrentHashMap<String, 
Context>(contextFactorys.size());
-        for (ContextFactory<Context> config : contextFactorys.values()) {
+        Map<String, Context> sessionContext = new ConcurrentHashMap<String, 
Context>(contextFactories.size());
+        for (ContextFactory<Context> config : contextFactories.values()) {
             Context context = config.createContext();
-            context.addListener(this);
             context.start();
             sessionContext.put(context.getName(), context);
         }
 
-        Queue<AtomicContext> shutdownQueue = new 
ConcurrentLinkedQueue<AtomicContext>();
+        List<Context> shutdownQueue = new ArrayList<Context>();
         contexts.put(key, sessionContext);
-        destroyableContexts.put(key, shutdownQueue);
+        destroyQueues.put(key, shutdownQueue);
         // initialize eager components. Note this cannot be done when we 
initially create each context since a component may
         // contain a forward reference to a component which has not been 
instantiated
         for (Context context : sessionContext.values()) {
             if (context instanceof AtomicContext) {
                 AtomicContext atomic = (AtomicContext) context;
                 if (atomic.isEagerInit()) {
-                    context.notify();  // Notify the instance
-                    //if (atomic.isDestroyable()) {
-                    shutdownQueue.add(atomic);
-                    //}
+                    atomic.init();  // Notify the instance
+                    synchronized(shutdownQueue){
+                        shutdownQueue.add(context);
+                    }
                 }
             }
+            context.addListener(this);
         }
         return sessionContext;
     }
@@ -227,7 +213,33 @@
      */
     private void destroyComponentContext(Object key) {
         contexts.remove(key);
-        destroyableContexts.remove(key);
+        destroyQueues.remove(key);
+    }
+
+
+    private synchronized void shutdownContexts(Object key) {
+        List<Context> contexts = destroyQueues.get(key);
+        if (contexts == null || contexts.size() == 0) {
+             return;
+        }
+        // shutdown destroyable instances in reverse instantiation order
+        ListIterator<Context> iter = contexts.listIterator(contexts.size());
+        while(iter.hasPrevious()){
+            Context context = iter.previous();
+            if (context.getLifecycleState() == RUNNING) {
+                //removeContextByKey(context.getName(), key);
+                try {
+                    if (context instanceof AtomicContext){
+                        System.out.println(":"+context.getName());
+                        ((AtomicContext)context).destroy();
+                    }
+                    context.stop();
+                } catch (TargetException e) {
+                    // TODO send a monitoring event
+                    // log.error("Error releasing instance [" + 
context.getName() + "]",e);
+                }
+            }
+        }
     }
 
 }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
 Thu Apr 13 17:18:23 2006
@@ -19,7 +19,6 @@
 import org.apache.tuscany.core.builder.ContextFactory;
 import org.apache.tuscany.core.context.EventContext;
 import org.apache.tuscany.core.context.Context;
-import org.apache.tuscany.core.context.RuntimeEventListener;
 import org.apache.tuscany.core.context.CoreRuntimeException;
 import org.apache.tuscany.core.context.event.Event;
 
@@ -31,10 +30,10 @@
  * 
  * @version $Rev$ $Date$
  */
-public class StatelessScopeContext extends AbstractScopeContext implements 
RuntimeEventListener {
+public class StatelessScopeContext extends AbstractScopeContext {
 
    // Component contexts keyed by name
-    private Map<String, Context> contextMap;
+    private Map<String, Context> contexts;
 
     public StatelessScopeContext(EventContext eventContext) {
         super(eventContext);
@@ -46,23 +45,21 @@
             throw new IllegalStateException("Scope must be in UNINITIALIZED 
state [" + lifecycleState + "]");
         }
         lifecycleState = RUNNING;
-        prepare();
     }
 
     public synchronized void stop() {
         if (lifecycleState != RUNNING) {
             throw new IllegalStateException("Scope in wrong state [" + 
lifecycleState + "]");
         }
-        contextMap = null;
+        contexts = null;
         lifecycleState = STOPPED;
     }
 
     public void registerFactory(ContextFactory<Context> configuration) {
-        contextFactorys.put(configuration.getName(), configuration);
-        if (lifecycleState == RUNNING) {
-            contextMap.put(configuration.getName(), 
configuration.createContext());
+        contextFactories.put(configuration.getName(), configuration);
+        if (contexts != null) {
+            contexts.put(configuration.getName(), 
configuration.createContext());
         }
-
     }
 
     public void onEvent(Event event){
@@ -74,7 +71,8 @@
     }
 
     public Context getContext(String ctxName) {
-        return contextMap.get(ctxName);
+        prepare();
+        return contexts.get(ctxName);
     }
 
     public Context getContextByKey(String ctxName, Object key) {
@@ -82,32 +80,27 @@
     }
 
     public void removeContext(String ctxName) {
-        removeContextByKey(ctxName, null);
+        if (contexts == null){
+            return;
+        }
+        contexts.remove(ctxName);
     }
 
     public void removeContextByKey(String ctxName, Object key) {
-        contextMap.remove(ctxName);
-    }
-
-    /**
-     * Always returns null since stateless components cannot be shutdown
-     */
-    protected Context[] getShutdownContexts(Object key) {
-        return null;
+        removeContext(ctxName);
     }
 
     private void prepare() throws CoreRuntimeException {
         if (lifecycleState != RUNNING) {
             throw new IllegalStateException("Scope not in INITIALIZED state [" 
+ lifecycleState + "]");
         }
-        if (contextMap == null) {
-            contextMap = new ConcurrentHashMap<String, Context> ();
-            for (ContextFactory<Context> config : contextFactorys.values()) {
-                for (int i = 0; i < contextFactorys.size(); i++) {
+        if (contexts == null) {
+            contexts = new ConcurrentHashMap<String, Context> ();
+            for (ContextFactory<Context> config : contextFactories.values()) {
+                for (int i = 0; i < contextFactories.size(); i++) {
                     Context context = config.createContext();
-                    context.addListener(this);
                     context.start();
-                    contextMap.put(context.getName(), context);
+                    contexts.put(context.getName(), context);
                 }
 
             }


Reply via email to