]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionScope.java
Runtime improvements
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / org / argeo / slc / core / execution / ExecutionScope.java
index adbf18aed7d1903d477f83c4d50b31b2a8200329..7deb9f5788923bef2c6a1368a7664be308cc140d 100644 (file)
@@ -1,19 +1,78 @@
 package org.argeo.slc.core.execution;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
 import org.springframework.beans.factory.ObjectFactory;
 import org.springframework.beans.factory.config.Scope;
 
 public class ExecutionScope implements Scope {
        private final static Log log = LogFactory.getLog(ExecutionScope.class);
 
+       private final ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
+
+       public final ThreadLocal<String> executionContextBeanName = new ThreadLocal<String>();
+
        public Object get(String name, ObjectFactory objectFactory) {
 
                if (log.isTraceEnabled())
                        log.trace("Getting scoped bean " + name);
-               return ExecutionContext.findOrAddScopedObject(name, objectFactory);
+
+               // check if an execution context is defined for this thread
+               if (executionContext.get() == null) {
+                       // if not, we expect objectFactory to produce an ExecutionContext
+                       Object obj = objectFactory.getObject();
+                       if (obj instanceof ExecutionContext) {
+                               // Check whether we are in an execution
+                               // FIXME: do it more properly (not static)
+                               // see https://www.argeo.org/bugzilla/show_bug.cgi?id=82
+                               if (!ExecutionAspect.inModuleExecution.get())
+                                       log
+                                                       .error("An execution context is being instatiated outside an execution."
+                                                                       + " Please check that your references to execution contexts."
+                                                                       + " This may lead to unexpected behaviour and will be rejected in the future.");
+
+                               // store the ExecutionContext in the ThreadLocal
+                               executionContext.set((ExecutionContext) obj);
+                               executionContextBeanName.set(name);
+                               if (log.isDebugEnabled()) {
+                                       log.debug("Execution context #"
+                                                       + executionContext.get().getUuid()
+                                                       + " instantiated. (beanName="
+                                                       + executionContextBeanName.get() + ")");
+//                                     Thread.dumpStack();
+                               }
+                               return obj;
+                       } else {
+                               throw new SlcException(
+                                               "Expected an ExecutionContext, got an object of class "
+                                                               + obj.getClass()
+                                                               + " for bean "
+                                                               + name
+                                                               + ": make sure that you have porperly set scope=\"execution\" where required");
+                       }
+               }
+
+               if (name.equals(executionContextBeanName.get())) {
+                       return executionContext.get();
+               } else {
+                       // see if the executionContext already knows the object
+                       Object obj = executionContext.get().findScopedObject(name);
+                       if (obj == null) {
+                               obj = objectFactory.getObject();
+                               if (!(obj instanceof ExecutionContext)) {
+                                       executionContext.get().addScopedObject(name, obj);
+                               } else {
+                                       throw new SlcException(
+                                                       "Only one ExecutionContext can be defined per Thread");
+                               }
+                       }
+                       return obj;
+               }
 
                // if (ExecutionContext.getScopedObjects().containsKey(name)) {
                // // returns cached instance
@@ -32,12 +91,17 @@ public class ExecutionScope implements Scope {
        }
 
        public String getConversationId() {
-               return ExecutionContext.getCurrentStackUuid();
+
+               return executionContext.get().getUuid();
+       }
+
+       public Boolean hasExecutionContext() {
+               return executionContext.get() != null;
        }
 
        public void registerDestructionCallback(String name, Runnable callback) {
                // TODO: implement it
-               //throw new UnsupportedOperationException();
+               // throw new UnsupportedOperationException();
        }
 
        public Object remove(String name) {