[jbpm-commits] JBoss JBPM SVN: r2441 - in projects/spec/trunk/modules: api/src/main/java/org/jbpm/api/service and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Sep 29 15:56:05 EDT 2008


Author: thomas.diesler at jboss.com
Date: 2008-09-29 15:56:05 -0400 (Mon, 29 Sep 2008)
New Revision: 2441

Added:
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionServiceImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ProcessServiceImpl.java
Removed:
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionManagerImpl.java
Modified:
   projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/Node.java
   projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/PropertySupport.java
   projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/service/ProcessService.java
   projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/service/signal/SignalServiceTest.java
   projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/pattern/control/sequence/SequenceTest.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EndEventImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EventImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/NodeImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/ProcessImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/PropertyImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/StartEventImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/TaskImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/DelegatingExecutionContext.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/TokenExecutorImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/PersistenceServiceImpl.java
   projects/spec/trunk/modules/impl/src/main/resources/jbpm-cfg-beans.xml
Log:
Pattern controll sequence - pass

Modified: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/Node.java
===================================================================
--- projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/Node.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/Node.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -42,11 +42,11 @@
   String getName();
 
   /** Get the associated ExecutionHandler */
-  ExecutionHandler getExecutionHandler();
+  ExecutionHandler getExecutionHandler(boolean defaultHandler);
 
   /** Get the associated SignalHandler */
-  SignalHandler getSignalHandler();
+  SignalHandler getSignalHandler(boolean defaultHandler);
 
   /** Get the associated FlowHandler */
-  FlowHandler getFlowHandler();
+  FlowHandler getFlowHandler(boolean defaultHandler);
 }
\ No newline at end of file

Modified: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/PropertySupport.java
===================================================================
--- projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/PropertySupport.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/PropertySupport.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -41,5 +41,5 @@
   /**
    * Get the list of property names
    */
-  Set<String> getPropertyNames();
+  Set<Property> getProperties();
 }
\ No newline at end of file

Modified: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/service/ProcessService.java
===================================================================
--- projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/service/ProcessService.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/service/ProcessService.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -39,7 +39,7 @@
 import org.slf4j.LoggerFactory;
 
 /**
- * The marker interface for all Services
+ * The ProcessService is the entry point to create, find and otherwise manage processes.
  * 
  * @author thomas.diesler at jboss.com
  * @since 25-Sep-2008

Modified: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/service/signal/SignalServiceTest.java
===================================================================
--- projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/service/signal/SignalServiceTest.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/service/signal/SignalServiceTest.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -56,7 +56,7 @@
     assertEquals("HelloWorld", signals.get(0).getMessage());
 
     // test the the signal can be retrieved by type
-    assertEquals("No signal", 0, getSignals(SignalType.SYSTEM_PROCESS_ENTER));
-    assertEquals("One signal", 1, getSignals(SignalType.USER_SIGNAL));
+    assertEquals("No signal", 0, getSignals(SignalType.SYSTEM_PROCESS_ENTER).size());
+    assertEquals("One signal", 1, getSignals(SignalType.USER_SIGNAL).size());
   }
 }

Modified: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/pattern/control/sequence/SequenceTest.java
===================================================================
--- projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/pattern/control/sequence/SequenceTest.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/pattern/control/sequence/SequenceTest.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -26,7 +26,6 @@
 import java.io.IOException;
 import java.util.List;
 
-import org.jbpm.api.client.Deployment;
 import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.Process;
 import org.jbpm.api.model.Signal;

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EndEventImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EndEventImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EndEventImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -31,9 +31,17 @@
 
 import org.jbpm.api.Constants;
 import org.jbpm.api.InvalidProcessException;
+import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.EndEvent;
 import org.jbpm.api.model.SequenceFlow;
+import org.jbpm.api.model.Signal;
 import org.jbpm.api.model.builder.ObjectNameFactory;
+import org.jbpm.api.runtime.ExecutionContext;
+import org.jbpm.api.runtime.FlowHandler;
+import org.jbpm.api.runtime.SignalHandler;
+import org.jbpm.api.runtime.Token;
+import org.jbpm.api.runtime.TokenExecutor;
+import org.jbpm.api.service.SignalService;
 import org.jbpm.ri.model.builder.SingleInFlowSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -99,6 +107,63 @@
     inFlows.add(inFlow);
   }
 
+  @Override
+  protected SignalHandler getDefaultSignalHandler()
+  {
+    return new SignalHandler()
+    {
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      SignalService sigService = engine.getService(SignalService.class);
+      public void throwEnterSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_END_EVENT_ENTER);
+        sigService.throwSignal(signal);
+      }
+
+      public void throwExitSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_END_EVENT_EXIT);
+        sigService.throwSignal(signal);
+        
+        // Destroy the token
+        ExecutionContext exContext = token.getExecutionContext();
+        EndSignalCallback callback = exContext.removeAttachment(EndSignalCallback.class);
+        callback.destroyToken(token);
+      }
+    };
+  }
+  
+  @Override
+  protected FlowHandler getDefaultFlowHandler()
+  {
+    return new FlowHandler()
+    {
+      public void execute(TokenExecutor tokenExecutor, Token token)
+      {
+        log.debug("End reached in: " + getName());
+        ExecutionContext exContext = token.getExecutionContext();
+        exContext.addAttachment(EndSignalCallback.class, new EndSignalCallback(tokenExecutor));
+      }
+    };
+  }
+
+  /**
+   * The callback that destroys the token AFTER the SYSTEM_END_EVENT_EXIT signal
+   */
+  static class EndSignalCallback
+  {
+    TokenExecutor tokenExecutor;
+    public EndSignalCallback(TokenExecutor tokenExecutor)
+    {
+      this.tokenExecutor = tokenExecutor;
+    }
+
+    void destroyToken(Token token)
+    {
+      tokenExecutor.destroy(token);
+    }
+  }
+  
   public String toString()
   {
     return "EndEvent[" + getName() + "]";

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EventImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EventImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/EventImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -29,8 +29,13 @@
 import javax.persistence.MappedSuperclass;
 
 import org.jbpm.api.Constants;
+import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.Event;
+import org.jbpm.api.model.Signal;
 import org.jbpm.api.model.builder.ObjectNameFactory;
+import org.jbpm.api.runtime.SignalHandler;
+import org.jbpm.api.runtime.Token;
+import org.jbpm.api.service.SignalService;
 
 /**
  * An Event is something that “happens” during the course of a business process. <p/> These Events affect the flow of
@@ -72,4 +77,25 @@
   {
     return eventType;
   }
+
+  @Override
+  protected SignalHandler getDefaultSignalHandler()
+  {
+    return new SignalHandler()
+    {
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      SignalService sigService = engine.getService(SignalService.class);
+      public void throwEnterSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_EVENT_ENTER);
+        sigService.throwSignal(signal);
+      }
+
+      public void throwExitSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_EVENT_EXIT);
+        sigService.throwSignal(signal);
+      }
+    };
+  }
 }
\ No newline at end of file

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/NodeImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/NodeImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/NodeImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -52,10 +52,13 @@
 import org.jbpm.api.runtime.FlowHandler;
 import org.jbpm.api.runtime.SignalHandler;
 import org.jbpm.api.runtime.Token;
+import org.jbpm.api.runtime.TokenExecutor;
 import org.jbpm.ri.model.builder.MultipleInFlowSupport;
 import org.jbpm.ri.model.builder.MultipleOutFlowSupport;
 import org.jbpm.ri.model.builder.SingleInFlowSupport;
 import org.jbpm.ri.model.builder.SingleOutFlowSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A Flow Object is one of the set of following graphical objects: Event, Activity, and
@@ -67,9 +70,11 @@
 @Inheritance(strategy = InheritanceType.JOINED)
 public abstract class NodeImpl extends AbstractElementImpl implements Node
 {
-  // provide serial version UID
   private static final long serialVersionUID = 1L;
 
+  // provide logging
+  final static Logger log = LoggerFactory.getLogger(NodeImpl.class);
+  
   @Basic
   private String name;
 
@@ -92,12 +97,20 @@
   private Set<Property> properties = new HashSet<Property>();
 
   @Basic
-  private String executionHandler;
+  private String execHandler;
+  private transient ExecutionHandler customExecHandler;
+  private transient ExecutionHandler defaultExecHandler;
+  
   @Basic
-  private String signalHandler;
+  private String sigHandler;
+  private transient SignalHandler customSignalHandler;
+  private transient SignalHandler defaultSignalHandler;
+  
   @Basic
   private String flowHandler;
-  
+  private transient FlowHandler customFlowHandler;
+  private transient FlowHandler defaultFlowHandler;
+
   public NodeImpl(String name)
   {
     this.name = name;
@@ -118,12 +131,11 @@
     return nodeIndex;
   }
 
-  // Persistence method
   public void setNodeIndex(int nodeIndex)
   {
     this.nodeIndex = nodeIndex;
   }
-
+  
   public String getName()
   {
     return name;
@@ -133,7 +145,7 @@
   {
     this.name = name;
   }
-
+  
   public Property getProperty(String name)
   {
     for (Property prop : properties)
@@ -144,14 +156,9 @@
     return null;
   }
 
-  public Set<String> getPropertyNames()
+  public Set<Property> getProperties()
   {
-    Set<String> propNames = new HashSet<String>();
-    for (Property prop : properties)
-    {
-      propNames.add(prop.getName());
-    }
-    return Collections.unmodifiableSet(propNames);
+    return Collections.unmodifiableSet(properties);
   }
 
   public List<SequenceFlow> getInFlows()
@@ -164,8 +171,19 @@
     return outFlows;
   }
 
-  public ExecutionHandler getExecutionHandler()
+  public ExecutionHandler getExecutionHandler(boolean defaultHandler)
   {
+    if (customExecHandler == null && execHandler != null)
+      customExecHandler = loadHandlerInstance(ExecutionHandler.class, execHandler);
+    
+    if (defaultExecHandler == null)
+      defaultExecHandler = getDefaultExecutionHandler();
+      
+    return defaultHandler ? defaultExecHandler : customExecHandler;
+  }
+
+  protected ExecutionHandler getDefaultExecutionHandler()
+  {
     return new ExecutionHandler()
     {
       public void execute(Token token)
@@ -175,10 +193,69 @@
     };
   }
 
-  public abstract FlowHandler getFlowHandler();
+  public SignalHandler getSignalHandler(boolean defaultHandler)
+  {
+    if (customSignalHandler == null && sigHandler != null)
+      customSignalHandler = loadHandlerInstance(SignalHandler.class, sigHandler);
+    
+    if (defaultSignalHandler == null)
+      defaultSignalHandler = getDefaultSignalHandler();
+      
+    return defaultHandler ? defaultSignalHandler : customSignalHandler;
+  }
+  
+  protected abstract SignalHandler getDefaultSignalHandler();
 
-  public abstract SignalHandler getSignalHandler();
+  public FlowHandler getFlowHandler(boolean defaultHandler)
+  {
+    if (customFlowHandler == null && flowHandler != null)
+      customFlowHandler = loadHandlerInstance(FlowHandler.class, flowHandler);
+    
+    if (defaultFlowHandler == null)
+      defaultFlowHandler = getDefaultFlowHandler();
+      
+    return defaultHandler ? defaultFlowHandler : customFlowHandler;
+  }
 
+  protected FlowHandler getDefaultFlowHandler()
+  {
+    final Node thisNode = this;
+    return new FlowHandler()
+    {
+      public void execute(TokenExecutor tokenExecutor, Token token)
+      {
+        if (getOutFlows().size() == 1)
+        {
+          SequenceFlow outFlow = getOutFlows().get(0);
+          tokenExecutor.move(token, outFlow);
+        }
+        else
+        {
+          throw new IllegalStateException("Cannot use default flow handler on " + thisNode + " with: " + getOutFlows());
+        }
+      }
+    };
+  }
+
+  @SuppressWarnings("unchecked")
+  private <T> T loadHandlerInstance(Class<T> clazz, String className)
+  {
+    T handler = null;
+    if (className != null)
+    {
+      try
+      {
+        ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
+        handler = (T)ctxLoader.loadClass(className).newInstance();
+      }
+      catch (Exception ex)
+      {
+        log.error("Cannot load handler instance: " + className, ex);
+      }
+    }
+    return handler;
+  }
+
   @Override
   protected void initialize(Process proc)
   {

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/ProcessImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/ProcessImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/ProcessImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -42,7 +42,6 @@
 import org.hibernate.annotations.IndexColumn;
 import org.jbpm.api.Constants;
 import org.jbpm.api.InvalidProcessException;
-import org.jbpm.api.NotImplementedException;
 import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.EndEvent;
 import org.jbpm.api.model.Node;
@@ -66,7 +65,7 @@
 {
   private static final long serialVersionUID = 1L;
   
-  // Provide logging
+  // provide logging
   final static Logger log = LoggerFactory.getLogger(ProcessImpl.class);
 
   @Basic
@@ -135,14 +134,9 @@
     return null;
   }
 
-  public Set<String> getPropertyNames()
+  public Set<Property> getProperties()
   {
-    Set<String> propNames = new HashSet<String>();
-    for (Property prop : properties)
-    {
-      propNames.add(prop.getName());
-    }
-    return Collections.unmodifiableSet(propNames);
+    return Collections.unmodifiableSet(properties);
   }
   
   public void addNode(NodeImpl nodeImpl)
@@ -291,7 +285,9 @@
    */
   private ProcessStatus waitForEndInternal(long timeout)
   {
-    throw new NotImplementedException();
+    ProcessEngine engine = ProcessEngine.getProcessEngine();
+    ExecutionService exService = engine.getService(ExecutionService.class);
+    return exService.waitForEnd(this, timeout);
   }
 
   public String toString()

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/PropertyImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/PropertyImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/PropertyImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -25,6 +25,8 @@
 
 import javax.persistence.Basic;
 import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
 
 import org.jbpm.api.model.Property;
 
@@ -39,6 +41,10 @@
 {
   private static final long serialVersionUID = 1L;
   
+  @Id @GeneratedValue
+  @SuppressWarnings("unused")
+  private Integer id;
+  
   @Basic
   private String name;
   

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/StartEventImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/StartEventImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/StartEventImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -31,9 +31,14 @@
 
 import org.jbpm.api.Constants;
 import org.jbpm.api.InvalidProcessException;
+import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.SequenceFlow;
+import org.jbpm.api.model.Signal;
 import org.jbpm.api.model.StartEvent;
 import org.jbpm.api.model.builder.ObjectNameFactory;
+import org.jbpm.api.runtime.SignalHandler;
+import org.jbpm.api.runtime.Token;
+import org.jbpm.api.service.SignalService;
 import org.jbpm.ri.model.builder.SingleOutFlowSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,6 +101,27 @@
     outFlows.add(outFlow);
   }
 
+  @Override
+  protected SignalHandler getDefaultSignalHandler()
+  {
+    return new SignalHandler()
+    {
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      SignalService sigService = engine.getService(SignalService.class);
+      public void throwEnterSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_START_EVENT_ENTER);
+        sigService.throwSignal(signal);
+      }
+
+      public void throwExitSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_START_EVENT_EXIT);
+        sigService.throwSignal(signal);
+      }
+    };
+  }
+  
   public String toString()
   {
     return "StartEvent[" + getName() + "]";

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/TaskImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/TaskImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/TaskImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -31,9 +31,14 @@
 
 import org.jbpm.api.Constants;
 import org.jbpm.api.InvalidProcessException;
+import org.jbpm.api.client.ProcessEngine;
 import org.jbpm.api.model.SequenceFlow;
+import org.jbpm.api.model.Signal;
 import org.jbpm.api.model.Task;
 import org.jbpm.api.model.builder.ObjectNameFactory;
+import org.jbpm.api.runtime.SignalHandler;
+import org.jbpm.api.runtime.Token;
+import org.jbpm.api.service.SignalService;
 import org.jbpm.ri.model.builder.SingleInFlowSupport;
 import org.jbpm.ri.model.builder.SingleOutFlowSupport;
 
@@ -108,6 +113,27 @@
     outFlows.add(outFlow);
   }
 
+  @Override
+  protected SignalHandler getDefaultSignalHandler()
+  {
+    return new SignalHandler()
+    {
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      SignalService sigService = engine.getService(SignalService.class);
+      public void throwEnterSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_TASK_ENTER);
+        sigService.throwSignal(signal);
+      }
+
+      public void throwExitSignal(Token token)
+      {
+        Signal signal = new Signal(getKey(), Signal.SignalType.SYSTEM_TASK_EXIT);
+        sigService.throwSignal(signal);
+      }
+    };
+  }
+  
   public String toString()
   {
     return "Task[" + getTaskType() + "," + getName() + "]";

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/DelegatingExecutionContext.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/DelegatingExecutionContext.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/DelegatingExecutionContext.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -28,29 +28,28 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.jboss.bpm.model.Activity;
-import org.jboss.bpm.model.FlowObject;
-import org.jboss.bpm.model.Process;
-import org.jboss.bpm.model.Property;
-import org.jboss.bpm.runtime.ExecutionContext;
+import org.jbpm.api.model.Node;
+import org.jbpm.api.model.Property;
+import org.jbpm.api.runtime.ExecutionContext;
+import org.jbpm.api.model.Process;
 
 /**
- * An ExecutionContext that delegates to the current {@link Activity} or {@link Process} for property rerieval.
+ * An ExecutionContext that delegates to the current {@link Node} or {@link Process} for property rerieval.
  * 
  * @author Thomas.Diesler at jboss.com
  * @since 15-Aug-2008
  */
 public class DelegatingExecutionContext implements ExecutionContext
 {
-  private FlowObject flowObject;
+  private Node node;
   private ExecutionContext delegate;
   private String activityPrefix;
   private String procPrefix;
   private Process proc;
 
-  DelegatingExecutionContext(FlowObject flowObject, ExecutionContext delegate)
+  DelegatingExecutionContext(Node flowObject, ExecutionContext delegate)
   {
-    this.flowObject = flowObject;
+    this.node = flowObject;
     this.delegate = delegate;
 
     proc = flowObject.getProcess();
@@ -63,11 +62,10 @@
     Object value = null;
 
     // Get activity property
-    if (flowObject instanceof Activity && name.startsWith(activityPrefix))
+    if (name.startsWith(activityPrefix))
     {
-      Activity activity = (Activity)flowObject;
       String key = name.substring(activityPrefix.length());
-      Property prop = activity.getProperty(key);
+      Property prop = node.getProperty(key);
       if (prop != null)
       {
         value = prop.getValue();
@@ -99,14 +97,10 @@
     Collection<Key> keys = new ArrayList<Key>(delegate.getAttachmentKeys());
 
     // Add activity property keys
-    if (flowObject instanceof Activity)
+    for (Property prop : node.getProperties())
     {
-      Activity activity = (Activity)flowObject;
-      for (Property prop : activity.getProperties())
-      {
-        Key key = new Key(null, activityPrefix + prop.getName());
-        keys.add(key);
-      }
+      Key key = new Key(null, activityPrefix + prop.getName());
+      keys.add(key);
     }
 
     // Add process property keys
@@ -171,7 +165,7 @@
 
   public String toString()
   {
-    Map<Key,Object> combined = new HashMap<Key,Object>();
+    Map<Key, Object> combined = new HashMap<Key, Object>();
     for (Key key : getAttachmentKeys())
     {
       if (key.getClassPart() != null)

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/TokenExecutorImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/TokenExecutorImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/TokenExecutorImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -34,14 +34,16 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jbpm.api.model.Node;
+import org.jbpm.api.model.Process;
 import org.jbpm.api.model.SequenceFlow;
 import org.jbpm.api.model.Process.ProcessStatus;
+import org.jbpm.api.runtime.ExecutionHandler;
+import org.jbpm.api.runtime.FlowHandler;
+import org.jbpm.api.runtime.SignalHandler;
 import org.jbpm.api.runtime.Token;
 import org.jbpm.api.runtime.TokenExecutor;
 import org.jbpm.api.runtime.Token.TokenStatus;
-import org.jbpm.ri.model.NodeImpl;
 import org.jbpm.ri.model.ProcessImpl;
-import org.jbpm.api.model.Process;
 
 /**
  * The {@link FlowHandler} invokes the TokenExecutor to schedule {@link ConnectingObject} objects together with their
@@ -221,12 +223,13 @@
         while (procStatus == ProcessStatus.Active && tokStatus == TokenStatus.Started)
         {
           // Get the target and its handlers
-          Node flowObject = token.getFlow().getTargetRef();
-          NodeImpl flowObjectImpl = (NodeImpl)flowObject;
-          SignalHandler sigHandler = getSignalHandler(flowObject);
+          Node node = token.getFlow().getTargetRef();
+          SignalHandler sigHandler = getSignalHandler(node);
+          ExecutionHandler execHandler = getExecutionHandler(node);
+          FlowHandler flowHandler = getFlowHandler(node);
 
           // Synchronize execution on the target FlowObject
-          synchronized (flowObject)
+          synchronized (node)
           {
             // Create a Token that includes properties from the current Activity
             DelegatingToken tokCopy = new DelegatingToken(token);
@@ -235,10 +238,10 @@
             sigHandler.throwEnterSignal(tokCopy);
 
             // Execute the target FlowObject
-            flowObjectImpl.execute(tokCopy);
+            execHandler.execute(tokCopy);
 
             // Transfer the token to the FlowHandler
-            flowObjectImpl.executeFlowHandler(tokenExecutor, tokCopy);
+            flowHandler.execute(tokenExecutor, tokCopy);
 
             // Throw the Exit Signal
             sigHandler.throwExitSignal(tokCopy);
@@ -290,19 +293,20 @@
 
     private SignalHandler getSignalHandler(Node target)
     {
-      HandlerSupport handlerSupport = getHandlerSupport(target);
-      SignalHandler handler = handlerSupport.getSignalHandler();
-      if (handler == null)
-        throw new IllegalStateException("Cannot obtain signal handler from: " + target);
+      SignalHandler customHandler = target.getSignalHandler(false);
+      return customHandler != null ? customHandler : target.getSignalHandler(true);
+    }
 
-      return handler;
+    private ExecutionHandler getExecutionHandler(Node target)
+    {
+      ExecutionHandler customHandler = target.getExecutionHandler(false);
+      return customHandler != null ? customHandler : target.getExecutionHandler(true);
     }
 
-    private HandlerSupport getHandlerSupport(FlowObject fo)
+    private FlowHandler getFlowHandler(Node target)
     {
-      if (fo instanceof HandlerSupport == false)
-        throw new IllegalStateException("Flow object does not implement handler support: " + fo);
-      return (HandlerSupport)fo;
+      FlowHandler customHandler = target.getFlowHandler(false);
+      return customHandler != null ? customHandler : target.getFlowHandler(true);
     }
 
     @Override

Deleted: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionManagerImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionManagerImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionManagerImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -1,354 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.ri.service;
-
-// $Id$
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.management.ObjectName;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jbpm.api.BPMException;
-import org.jbpm.api.InvalidProcessException;
-import org.jbpm.api.ProcessTimeoutException;
-import org.jbpm.api.client.ProcessEngine;
-import org.jbpm.api.model.Process;
-import org.jbpm.api.model.Signal;
-import org.jbpm.api.model.StartEvent;
-import org.jbpm.api.model.Process.ProcessStatus;
-import org.jbpm.api.model.Signal.SignalType;
-import org.jbpm.api.model.StartEvent.TriggerType;
-import org.jbpm.api.runtime.Attachments;
-import org.jbpm.api.runtime.TokenExecutor;
-import org.jbpm.api.service.ExecutionService;
-import org.jbpm.api.service.ProcessService;
-import org.jbpm.api.service.SignalService;
-import org.jbpm.ri.model.ProcessImpl;
-import org.jbpm.ri.model.SequenceFlowImpl;
-import org.jbpm.ri.runtime.RuntimeProcess;
-import org.jbpm.ri.runtime.RuntimeProcessImpl;
-import org.jbpm.ri.runtime.TokenImpl;
-
-/**
- * The process manager is the entry point to create, find and otherwise manage processes.
- * 
- * @author thomas.diesler at jboss.com
- * @since 18-Jun-2008
- */
-public class ExecutionManagerImpl extends ExecutionService
-{
-  // provide logging
-  private static final Log log = LogFactory.getLog(ExecutionManagerImpl.class);
-
-  // The map of active runtime processes
-  private Map<ObjectName, RuntimeProcess> runtimeProcesses = new HashMap<ObjectName, RuntimeProcess>();
-
-  @Override
-  public void startProcess(Process proc, Attachments att)
-  {
-    // Prepare the process for start
-    startProcessPrepare(proc);
-    
-    // Get the None Start Event if there is one and start the initial flow
-    StartEvent start = getNoneStartEvent(proc);
-    if (start != null)
-    {
-      if (proc.getProcessStatus() == ProcessStatus.Active)
-        throw new IllegalStateException("Cannot start an already active process");
-      
-      startProcessInternal(start, att);
-    }
-  }
-
-  @Override
-  public void startProcess(StartEvent start, Attachments att)
-  {
-    // Prepare the process for start
-    startProcessPrepare(start.getProcess());
-    
-    startProcessInternal(start, att);
-  }
-
-  private synchronized void startProcessInternal(StartEvent start, Attachments att)
-  {
-    @SuppressWarnings("serial")
-    class InitialFlow extends SequenceFlowImpl
-    {
-      InitialFlow(StartEvent start)
-      {
-        super(start.getName());
-        setTargetRef(start);
-      }
-    }
-    
-    Process proc = start.getProcess();
-    RuntimeProcess rtProc = getRuntimeProcess(proc, false);
-    boolean startProcessThread = (rtProc == null); 
-
-    // Create initial Token
-    TokenImpl initialToken = new TokenImpl(att);
-    InitialFlow initialFlow = new InitialFlow(start);
-    initialToken.setFlow(initialFlow);
-    
-    // Register the initial Token 
-    rtProc = getRuntimeProcess(proc, true);
-    TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
-    tokenExecutor.create(initialToken, initialFlow);
-    
-    // Start a new process thread
-    if (startProcessThread)
-    {
-      RunnableProcess runnable = new RunnableProcess(rtProc);
-      getProcessExecutor().execute(runnable);
-      synchronized (proc)
-      {
-        while (proc.getProcessStatus() != ProcessStatus.Active)
-        {
-          try
-          {
-            proc.wait();
-          }
-          catch (InterruptedException ex)
-          {
-            log.error(ex);
-          }
-        }
-      }
-    }
-    
-    // Do the start time assignments
-    // startTimeAssignments(proc, initialToken);
-    
-    // Start the initial token
-    tokenExecutor.start(initialToken);
-  }
-
-  private void startProcessPrepare(Process proc)
-  {
-    // Reset the process if already terminated
-    ProcessImpl procImpl = (ProcessImpl)proc;
-    if (isProcessTerminated(proc))
-      procImpl.resetProcess();
-    
-    ProcessStatus procStatus = proc.getProcessStatus();
-    if (procStatus != ProcessStatus.Ready && procStatus != ProcessStatus.Active)
-      throw new IllegalStateException("Cannot start process in state: " + procStatus);
-
-    // Register the process if needed
-    ProcessEngine engine = ProcessEngine.getProcessEngine();
-    ProcessService procService = engine.getService(ProcessService.class);
-    if (procService.getProcessByKey(proc.getKey()) == null)
-      procService.registerProcess(proc);
-  }
-
-  public ProcessStatus waitForEnd(Process proc)
-  {
-    return waitForEndInternal(proc, 0);
-  }
-
-  public ProcessStatus waitForEnd(Process proc, long timeout)
-  {
-    return waitForEndInternal(proc, timeout);
-  }
-
-  /**
-   * Wait for the Process to end. All Tokens that are generated at the Start Event for that Process must eventually
-   * arrive at an End Event. The Process will be in a running state until all Tokens are consumed. If the process was
-   * aborted this method throws the causing RuntimeException if avaialable.
-   */
-  private ProcessStatus waitForEndInternal(Process proc, long timeout)
-  {
-    ProcessImpl procImpl = (ProcessImpl)proc;
-    
-    ProcessStatus status = proc.getProcessStatus();
-    if (status == ProcessStatus.None)
-      throw new IllegalStateException("Cannot wait for process in state: " + status);
-
-    // Wait a little for the process to end
-    boolean forever = (timeout < 1);
-    long now = System.currentTimeMillis();
-    long until = now + timeout;
-    try
-    {
-      while (forever || now < until)
-      {
-        synchronized (proc)
-        {
-          if (isProcessTerminated(proc))
-          {
-            if (procImpl.getRuntimeException() != null)
-            {
-              throw new BPMException("Process aborted", procImpl.getRuntimeException());
-            }
-            else
-            {
-              break;
-            }
-          }
-          
-          // Start waiting to get notified
-          long waitTimeout = forever ? 0 : until - now;
-          proc.wait(waitTimeout);
-        }
-        now = System.currentTimeMillis();
-      }
-      
-      // Throw timeout exception if it took too long
-      if (isProcessTerminated(proc) == false)
-      {
-        RuntimeException rte = new ProcessTimeoutException("Process timeout after " + timeout + "ms for: " + proc.getKey());
-        procImpl.setRuntimeException(rte);
-        log.error(rte);
-        throw rte;
-      }
-    }
-    catch (InterruptedException ex)
-    {
-      log.warn(ex);
-    }
-    finally
-    {
-      // Unregister the process if not done already
-      // this could happen when the Process never received a start signal
-      // and then we get here because of a ProcessTimeoutException
-      ProcessEngine engine = ProcessEngine.getProcessEngine();
-      ProcessService procService = engine.getService(ProcessService.class);
-      if (procService.getProcessByKey(proc.getKey()) != null)
-        procService.unregisterProcess(proc);
-    }
-
-    
-    status = proc.getProcessStatus();
-    return status;
-  }
-  
-  private boolean isProcessTerminated(Process proc)
-  {
-    ProcessStatus status = proc.getProcessStatus();
-    return status == ProcessStatus.Cancelled || status == ProcessStatus.Completed || status == ProcessStatus.Aborted;
-  }
-  
-  private StartEvent getNoneStartEvent(Process proc)
-  {
-    StartEvent start = null;
-    for (StartEvent aux : proc.getNodes(StartEvent.class))
-    {
-      if (aux.getTriggerType() == TriggerType.None)
-      {
-        if (start != null)
-          throw new InvalidProcessException("Process cannot have multiple start events with no trigger");
-        start = aux;
-      }
-    }
-    return start;
-  }
-
-  private RuntimeProcess getRuntimeProcess(Process proc, boolean createNew)
-  {
-    RuntimeProcess rtProcess;
-    synchronized (runtimeProcesses)
-    {
-      rtProcess = runtimeProcesses.get(proc.getKey());
-      if (rtProcess == null && createNew)
-      {
-        rtProcess = new RuntimeProcessImpl(proc);
-        runtimeProcesses.put(proc.getKey(), rtProcess);
-      }
-    }
-    return rtProcess;
-  }
-
-  /***************************************************************
-   * The runnable Process
-   */
-  class RunnableProcess implements Runnable
-  {
-    private RuntimeProcess rtProc;
-
-    public RunnableProcess(RuntimeProcess rtProc)
-    {
-      this.rtProc = rtProc;
-    }
-
-    public void run()
-    {
-      TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
-      ProcessImpl procImpl = (ProcessImpl)rtProc.getProcess();
-      Process proc = rtProc.getProcess();
-
-      ProcessEngine engine = ProcessEngine.getProcessEngine();
-      SignalService sigService = engine.getService(SignalService.class);
-      
-      ObjectName procID = proc.getKey();
-      String procName = proc.getName();
-      try
-      {
-        synchronized (proc)
-        {
-          procImpl.setProcessStatus(ProcessStatus.Active);
-          sigService.throwSignal(new Signal(procID, SignalType.SYSTEM_PROCESS_ENTER));
-
-          // Notify that the process is now Active
-          proc.notifyAll();
-        }
-        
-        synchronized (rtProc)
-        {
-          // Wait until there are no more runnable tokens
-          while (tokenExecutor.hasRunnableTokens())
-          {
-            try
-            {
-              rtProc.wait();
-            }
-            catch (InterruptedException ex)
-            {
-              log.error(ex);
-            }
-          }
-          
-          log.debug("End execution thread [proc=" + procName + ",status=" + proc.getProcessStatus() + "]");
-          
-          if (proc.getProcessStatus() == ProcessStatus.Active)
-            procImpl.setProcessStatus(ProcessStatus.Completed);
-        }
-      }
-      finally
-      {
-        sigService.throwSignal(new Signal(procID, Signal.SignalType.SYSTEM_PROCESS_EXIT));
-
-        synchronized (proc)
-        {
-          ProcessService procService = engine.getService(ProcessService.class);
-          procService.unregisterProcess(proc);
-          runtimeProcesses.remove(procID);
-          
-          // Notify that the process has now ended
-          proc.notifyAll();
-        }
-      }
-    }
-  }
-}
\ No newline at end of file

Copied: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionServiceImpl.java (from rev 2439, projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionManagerImpl.java)
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionServiceImpl.java	                        (rev 0)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ExecutionServiceImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -0,0 +1,354 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.ri.service;
+
+// $Id$
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.ObjectName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jbpm.api.BPMException;
+import org.jbpm.api.InvalidProcessException;
+import org.jbpm.api.ProcessTimeoutException;
+import org.jbpm.api.client.ProcessEngine;
+import org.jbpm.api.model.Process;
+import org.jbpm.api.model.Signal;
+import org.jbpm.api.model.StartEvent;
+import org.jbpm.api.model.Process.ProcessStatus;
+import org.jbpm.api.model.Signal.SignalType;
+import org.jbpm.api.model.StartEvent.TriggerType;
+import org.jbpm.api.runtime.Attachments;
+import org.jbpm.api.runtime.TokenExecutor;
+import org.jbpm.api.service.ExecutionService;
+import org.jbpm.api.service.ProcessService;
+import org.jbpm.api.service.SignalService;
+import org.jbpm.ri.model.ProcessImpl;
+import org.jbpm.ri.model.SequenceFlowImpl;
+import org.jbpm.ri.runtime.RuntimeProcess;
+import org.jbpm.ri.runtime.RuntimeProcessImpl;
+import org.jbpm.ri.runtime.TokenImpl;
+
+/**
+ * The process manager is the entry point to create, find and otherwise manage processes.
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 18-Jun-2008
+ */
+public class ExecutionServiceImpl extends ExecutionService
+{
+  // provide logging
+  private static final Log log = LogFactory.getLog(ExecutionServiceImpl.class);
+
+  // The map of active runtime processes
+  private Map<ObjectName, RuntimeProcess> runtimeProcesses = new HashMap<ObjectName, RuntimeProcess>();
+
+  @Override
+  public void startProcess(Process proc, Attachments att)
+  {
+    // Prepare the process for start
+    startProcessPrepare(proc);
+    
+    // Get the None Start Event if there is one and start the initial flow
+    StartEvent start = getNoneStartEvent(proc);
+    if (start != null)
+    {
+      if (proc.getProcessStatus() == ProcessStatus.Active)
+        throw new IllegalStateException("Cannot start an already active process");
+      
+      startProcessInternal(start, att);
+    }
+  }
+
+  @Override
+  public void startProcess(StartEvent start, Attachments att)
+  {
+    // Prepare the process for start
+    startProcessPrepare(start.getProcess());
+    
+    startProcessInternal(start, att);
+  }
+
+  private synchronized void startProcessInternal(StartEvent start, Attachments att)
+  {
+    @SuppressWarnings("serial")
+    class InitialFlow extends SequenceFlowImpl
+    {
+      InitialFlow(StartEvent start)
+      {
+        super(start.getName());
+        setTargetRef(start);
+      }
+    }
+    
+    Process proc = start.getProcess();
+    RuntimeProcess rtProc = getRuntimeProcess(proc, false);
+    boolean startProcessThread = (rtProc == null); 
+
+    // Create initial Token
+    TokenImpl initialToken = new TokenImpl(att);
+    InitialFlow initialFlow = new InitialFlow(start);
+    initialToken.setFlow(initialFlow);
+    
+    // Register the initial Token 
+    rtProc = getRuntimeProcess(proc, true);
+    TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
+    tokenExecutor.create(initialToken, initialFlow);
+    
+    // Start a new process thread
+    if (startProcessThread)
+    {
+      RunnableProcess runnable = new RunnableProcess(rtProc);
+      getProcessExecutor().execute(runnable);
+      synchronized (proc)
+      {
+        while (proc.getProcessStatus() != ProcessStatus.Active)
+        {
+          try
+          {
+            proc.wait();
+          }
+          catch (InterruptedException ex)
+          {
+            log.error(ex);
+          }
+        }
+      }
+    }
+    
+    // Do the start time assignments
+    // startTimeAssignments(proc, initialToken);
+    
+    // Start the initial token
+    tokenExecutor.start(initialToken);
+  }
+
+  private void startProcessPrepare(Process proc)
+  {
+    // Reset the process if already terminated
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    if (isProcessTerminated(proc))
+      procImpl.resetProcess();
+    
+    ProcessStatus procStatus = proc.getProcessStatus();
+    if (procStatus != ProcessStatus.Ready && procStatus != ProcessStatus.Active)
+      throw new IllegalStateException("Cannot start process in state: " + procStatus);
+
+    // Register the process if needed
+    ProcessEngine engine = ProcessEngine.getProcessEngine();
+    ProcessService procService = engine.getService(ProcessService.class);
+    if (procService.getProcessByKey(proc.getKey()) == null)
+      procService.registerProcess(proc);
+  }
+
+  public ProcessStatus waitForEnd(Process proc)
+  {
+    return waitForEndInternal(proc, 0);
+  }
+
+  public ProcessStatus waitForEnd(Process proc, long timeout)
+  {
+    return waitForEndInternal(proc, timeout);
+  }
+
+  /**
+   * Wait for the Process to end. All Tokens that are generated at the Start Event for that Process must eventually
+   * arrive at an End Event. The Process will be in a running state until all Tokens are consumed. If the process was
+   * aborted this method throws the causing RuntimeException if avaialable.
+   */
+  private ProcessStatus waitForEndInternal(Process proc, long timeout)
+  {
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    
+    ProcessStatus status = proc.getProcessStatus();
+    if (status == ProcessStatus.None)
+      throw new IllegalStateException("Cannot wait for process in state: " + status);
+
+    // Wait a little for the process to end
+    boolean forever = (timeout < 1);
+    long now = System.currentTimeMillis();
+    long until = now + timeout;
+    try
+    {
+      while (forever || now < until)
+      {
+        synchronized (proc)
+        {
+          if (isProcessTerminated(proc))
+          {
+            if (procImpl.getRuntimeException() != null)
+            {
+              throw new BPMException("Process aborted", procImpl.getRuntimeException());
+            }
+            else
+            {
+              break;
+            }
+          }
+          
+          // Start waiting to get notified
+          long waitTimeout = forever ? 0 : until - now;
+          proc.wait(waitTimeout);
+        }
+        now = System.currentTimeMillis();
+      }
+      
+      // Throw timeout exception if it took too long
+      if (isProcessTerminated(proc) == false)
+      {
+        RuntimeException rte = new ProcessTimeoutException("Process timeout after " + timeout + "ms for: " + proc.getKey());
+        procImpl.setRuntimeException(rte);
+        log.error(rte);
+        throw rte;
+      }
+    }
+    catch (InterruptedException ex)
+    {
+      log.warn(ex);
+    }
+    finally
+    {
+      // Unregister the process if not done already
+      // this could happen when the Process never received a start signal
+      // and then we get here because of a ProcessTimeoutException
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      ProcessService procService = engine.getService(ProcessService.class);
+      if (procService.getProcessByKey(proc.getKey()) != null)
+        procService.unregisterProcess(proc);
+    }
+
+    
+    status = proc.getProcessStatus();
+    return status;
+  }
+  
+  private boolean isProcessTerminated(Process proc)
+  {
+    ProcessStatus status = proc.getProcessStatus();
+    return status == ProcessStatus.Cancelled || status == ProcessStatus.Completed || status == ProcessStatus.Aborted;
+  }
+  
+  private StartEvent getNoneStartEvent(Process proc)
+  {
+    StartEvent start = null;
+    for (StartEvent aux : proc.getNodes(StartEvent.class))
+    {
+      if (aux.getTriggerType() == TriggerType.None)
+      {
+        if (start != null)
+          throw new InvalidProcessException("Process cannot have multiple start events with no trigger");
+        start = aux;
+      }
+    }
+    return start;
+  }
+
+  private RuntimeProcess getRuntimeProcess(Process proc, boolean createNew)
+  {
+    RuntimeProcess rtProcess;
+    synchronized (runtimeProcesses)
+    {
+      rtProcess = runtimeProcesses.get(proc.getKey());
+      if (rtProcess == null && createNew)
+      {
+        rtProcess = new RuntimeProcessImpl(proc);
+        runtimeProcesses.put(proc.getKey(), rtProcess);
+      }
+    }
+    return rtProcess;
+  }
+
+  /***************************************************************
+   * The runnable Process
+   */
+  class RunnableProcess implements Runnable
+  {
+    private RuntimeProcess rtProc;
+
+    public RunnableProcess(RuntimeProcess rtProc)
+    {
+      this.rtProc = rtProc;
+    }
+
+    public void run()
+    {
+      TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
+      ProcessImpl procImpl = (ProcessImpl)rtProc.getProcess();
+      Process proc = rtProc.getProcess();
+
+      ProcessEngine engine = ProcessEngine.getProcessEngine();
+      SignalService sigService = engine.getService(SignalService.class);
+      
+      ObjectName procID = proc.getKey();
+      String procName = proc.getName();
+      try
+      {
+        synchronized (proc)
+        {
+          procImpl.setProcessStatus(ProcessStatus.Active);
+          sigService.throwSignal(new Signal(procID, SignalType.SYSTEM_PROCESS_ENTER));
+
+          // Notify that the process is now Active
+          proc.notifyAll();
+        }
+        
+        synchronized (rtProc)
+        {
+          // Wait until there are no more runnable tokens
+          while (tokenExecutor.hasRunnableTokens())
+          {
+            try
+            {
+              rtProc.wait();
+            }
+            catch (InterruptedException ex)
+            {
+              log.error(ex);
+            }
+          }
+          
+          log.debug("End execution thread [proc=" + procName + ",status=" + proc.getProcessStatus() + "]");
+          
+          if (proc.getProcessStatus() == ProcessStatus.Active)
+            procImpl.setProcessStatus(ProcessStatus.Completed);
+        }
+      }
+      finally
+      {
+        sigService.throwSignal(new Signal(procID, Signal.SignalType.SYSTEM_PROCESS_EXIT));
+
+        synchronized (proc)
+        {
+          ProcessService procService = engine.getService(ProcessService.class);
+          procService.unregisterProcess(proc);
+          runtimeProcesses.remove(procID);
+          
+          // Notify that the process has now ended
+          proc.notifyAll();
+        }
+      }
+    }
+  }
+}
\ No newline at end of file

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/PersistenceServiceImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/PersistenceServiceImpl.java	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/PersistenceServiceImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -23,6 +23,10 @@
 
 // $Id$
 
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
 import javax.management.ObjectName;
 
 import org.hibernate.Hibernate;
@@ -34,13 +38,8 @@
 import org.jbpm.api.ProcessNotFoundException;
 import org.jbpm.api.model.Process;
 import org.jbpm.api.service.PersistenceService;
-import org.jbpm.ri.model.AbstractElementImpl;
-import org.jbpm.ri.model.EndEventImpl;
-import org.jbpm.ri.model.NodeImpl;
+import org.jbpm.api.service.Service;
 import org.jbpm.ri.model.ProcessImpl;
-import org.jbpm.ri.model.SequenceFlowImpl;
-import org.jbpm.ri.model.StartEventImpl;
-import org.jbpm.ri.model.TaskImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,15 +53,21 @@
 {
   // Provide logging
   final Logger log = LoggerFactory.getLogger(PersistenceServiceImpl.class);
-  
+
   private String hibernateConfig;
   private SessionFactory sessionFactory;
+  private Set<String> annotatedClasses = new HashSet<String>();
 
   public void setHibernateConfig(String hibernateConfig)
   {
     this.hibernateConfig = hibernateConfig;
   }
 
+  public void setAnnotatedClasses(Set<String> annotatedClasses)
+  {
+    this.annotatedClasses = annotatedClasses;
+  }
+
   public ObjectName saveProcess(Process proc)
   {
     log.debug("START saveProcess: " + proc.getKey());
@@ -121,10 +126,11 @@
     log.debug("END deleteProcess: " + proc.getKey());
   }
 
+  @SuppressWarnings("unchecked")
   private SessionFactory getSessionFactory()
   {
     // If this property is not explicitly set in the beans config
-    // fall back to the -Ddatabase property that also activates 
+    // fall back to the -Ddatabase property that also activates
     // the corresponding mvn profiles
     if (hibernateConfig == null)
     {
@@ -135,13 +141,24 @@
     if (sessionFactory == null)
     {
       AnnotationConfiguration anConfig = new AnnotationConfiguration();
-      anConfig.addAnnotatedClass(AbstractElementImpl.class);
-      anConfig.addAnnotatedClass(EndEventImpl.class);
-      anConfig.addAnnotatedClass(NodeImpl.class);
-      anConfig.addAnnotatedClass(ProcessImpl.class);
-      anConfig.addAnnotatedClass(SequenceFlowImpl.class);
-      anConfig.addAnnotatedClass(StartEventImpl.class);
-      anConfig.addAnnotatedClass(TaskImpl.class);
+      
+      String serviceName = null;
+      try
+      {
+        ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
+        Iterator<String> itAnn = annotatedClasses.iterator();
+        while (itAnn.hasNext())
+        {
+          serviceName = itAnn.next();
+          Class<Service> serviceClass = (Class<Service>)ctxLoader.loadClass(serviceName);
+          anConfig.addAnnotatedClass(serviceClass);
+        }
+      }
+      catch (Exception ex)
+      {
+        throw new IllegalStateException("Cannot load service: " + serviceName, ex);
+      }
+
       sessionFactory = anConfig.configure(hibernateConfig).buildSessionFactory();
     }
     return sessionFactory;

Added: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ProcessServiceImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ProcessServiceImpl.java	                        (rev 0)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ProcessServiceImpl.java	2008-09-29 19:56:05 UTC (rev 2441)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.ri.service;
+
+// $Id$
+
+import org.jbpm.api.service.ProcessService;
+
+/**
+ * The ProcessService is the entry point to create, find and otherwise manage processes.
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 18-Jun-2008
+ */
+public class ProcessServiceImpl extends ProcessService
+{
+}
\ No newline at end of file


Property changes on: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/service/ProcessServiceImpl.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: projects/spec/trunk/modules/impl/src/main/resources/jbpm-cfg-beans.xml
===================================================================
--- projects/spec/trunk/modules/impl/src/main/resources/jbpm-cfg-beans.xml	2008-09-29 17:44:30 UTC (rev 2440)
+++ projects/spec/trunk/modules/impl/src/main/resources/jbpm-cfg-beans.xml	2008-09-29 19:56:05 UTC (rev 2441)
@@ -8,16 +8,35 @@
     <bean name="jBPMProcessEngine" class="org.jbpm.ri.client.ProcessEngineImpl">
       <property name="services">
         <set elementClass="org.jbpm.api.service.Service">
-          <inject bean="jBPMProcessBuilder" />
+          <inject bean="jBPMExecutionService" />
           <inject bean="jBPMPersistenceService" />
+          <inject bean="jBPMProcessBuilderService" />
+          <inject bean="jBPMProcessService" />
           <inject bean="jBPMSignalService" />
         </set>
       </property>
     </bean>
 
-    <!-- The Services -->
-    <bean name="jBPMProcessBuilder" class="org.jbpm.ri.model.builder.ProcessBuilderImpl" />
-    <bean name="jBPMPersistenceService" class="org.jbpm.ri.service.PersistenceServiceImpl" />
+    <!-- The PersistenceService -->
+    <bean name="jBPMPersistenceService" class="org.jbpm.ri.service.PersistenceServiceImpl">
+      <property name="annotatedClasses">
+        <set elementClass="java.lang.String">
+          <value>org.jbpm.ri.model.AbstractElementImpl</value>
+          <value>org.jbpm.ri.model.EndEventImpl</value>
+          <value>org.jbpm.ri.model.NodeImpl</value>
+          <value>org.jbpm.ri.model.ProcessImpl</value>
+          <value>org.jbpm.ri.model.PropertyImpl</value>
+          <value>org.jbpm.ri.model.SequenceFlowImpl</value>
+          <value>org.jbpm.ri.model.StartEventImpl</value>
+          <value>org.jbpm.ri.model.TaskImpl</value>
+        </set>
+      </property>
+    </bean>
+
+    <!-- Other Services -->
+    <bean name="jBPMExecutionService" class="org.jbpm.ri.service.ExecutionServiceImpl" />
+    <bean name="jBPMProcessBuilderService" class="org.jbpm.ri.model.builder.ProcessBuilderImpl" />
+    <bean name="jBPMProcessService" class="org.jbpm.ri.service.ProcessServiceImpl" />
     <bean name="jBPMSignalService" class="org.jbpm.ri.service.SignalServiceImpl" />
-
+    
   </deployment>




More information about the jbpm-commits mailing list