[jbpm-commits] JBoss JBPM SVN: r1941 - in jbossbpm/spec/trunk/modules: api/src/main/java/org/jboss/bpm/model and 7 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Aug 20 10:07:10 EDT 2008


Author: thomas.diesler at jboss.com
Date: 2008-08-20 10:07:10 -0400 (Wed, 20 Aug 2008)
New Revision: 1941

Added:
   jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/
   jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/StartEventSignalTest.java
Modified:
   jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/client/ExecutionManager.java
   jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/AbstractElement.java
   jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/Process.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ExecutionManagerImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ProcessManagerImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/RunnableToken.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/AbstractElementImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ActivityImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EndEventImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EventImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/FlowObjectImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/GatewayImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessBuilderImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ReceiveTaskImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/SendTaskImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/StartEventImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TaskImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TokenExecutorImpl.java
   jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/runtime/DelegatingExecutionContext.java
   jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/gateway/parallel/ParallelGatewayMergeTest.java
   jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/pattern/control/synchronization/SynchronizationTest.java
Log:
More Synchronization tests

Modified: jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/client/ExecutionManager.java
===================================================================
--- jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/client/ExecutionManager.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/client/ExecutionManager.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -23,7 +23,11 @@
 
 // $Id: $
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 import org.jboss.bpm.model.Process;
+import org.jboss.bpm.model.StartEvent;
 import org.jboss.bpm.runtime.Attachments;
 
 /**
@@ -34,6 +38,9 @@
  */
 public abstract class ExecutionManager
 {
+  private int maxProcessThreads = 10;
+  private ExecutorService procExecutor = Executors.newFixedThreadPool(maxProcessThreads);
+  
   // Hide public constructor
   protected ExecutionManager()
   {
@@ -49,10 +56,26 @@
   }
   
   /**
-   * Start the Process and return a Future
+   * Get the process executor service
+   */
+  public ExecutorService getProcessExecutor()
+  {
+    return procExecutor;
+  }
+
+  /**
+   * Start the Process
    * 
    * @param proc The Process to start
    * @param att The Attachments in the ExecutionContext
    */
   public abstract void startProcess(Process proc, Attachments att);
+
+  /**
+   * Start the Process from a given start event
+   * 
+   * @param start The StartEvent that triggers the process
+   * @param att The Attachments in the ExecutionContext
+   */
+  public abstract void startProcess(StartEvent start, Attachments att);
 }

Modified: jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/AbstractElement.java
===================================================================
--- jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/AbstractElement.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/AbstractElement.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -28,7 +28,7 @@
 import javax.management.ObjectName;
 
 /**
- * The parrent of all BPMN elements
+ * The parrent of all Elements
  * 
  * @author thomas.diesler at jboss.com
  * @since 08-Jul-2008

Modified: jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/Process.java
===================================================================
--- jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/Process.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/api/src/main/java/org/jboss/bpm/model/Process.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -142,7 +142,7 @@
    * <p/>
    * This method until the process ends without timeout.
    */
-  void waitForEnd();
+  ProcessStatus waitForEnd();
   
   /**
    * All Tokens that are generated at the Start Event for that Process must eventually arrive at an End Event. 
@@ -150,5 +150,5 @@
    * <p/>
    * This method until the process ends with a given timeout.
    */
-  void waitForEnd(long timeout);
+  ProcessStatus waitForEnd(long timeout);
 }
\ No newline at end of file

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ExecutionManagerImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ExecutionManagerImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ExecutionManagerImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -25,6 +25,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
 
 import javax.management.ObjectName;
 
@@ -40,12 +41,14 @@
 import org.jboss.bpm.model.Signal;
 import org.jboss.bpm.model.StartEvent;
 import org.jboss.bpm.model.Assignment.AssignTime;
+import org.jboss.bpm.model.Process.ProcessStatus;
 import org.jboss.bpm.model.Signal.SignalType;
 import org.jboss.bpm.ri.model.impl.ExpressionEvaluator;
 import org.jboss.bpm.ri.model.impl.ProcessImpl;
 import org.jboss.bpm.ri.model.impl.RuntimeProcessImpl;
 import org.jboss.bpm.ri.model.impl.SequenceFlowImpl;
 import org.jboss.bpm.ri.model.impl.TokenExecutorImpl;
+import org.jboss.bpm.ri.model.impl.TokenExecutorImpl.StartCallback;
 import org.jboss.bpm.ri.runtime.DelegatingToken;
 import org.jboss.bpm.ri.runtime.MutableToken;
 import org.jboss.bpm.ri.runtime.RuntimeProcess;
@@ -64,48 +67,77 @@
 public class ExecutionManagerImpl extends ExecutionManager
 {
   // provide logging
-  private static final Log log = LogFactory.getLog(ExecutionManager.class);
+  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(final Process proc, final Attachments att)
   {
-    final ProcessImpl procImpl = (ProcessImpl)proc;
-    procImpl.setProcessStatus(Process.ProcessStatus.Active);
-
-    SignalManager signalManager = SignalManager.locateSignalManager();
-    signalManager.throwSignal(proc.getName(), new Signal(proc.getName(), SignalType.SYSTEM_PROCESS_ENTER));
-
+    // Setup the StartCallback that will be called from the Token Executor
     final RuntimeProcessImpl rtProc = new RuntimeProcessImpl(proc);
-    final RunnableProcess runnableProcess = new RunnableProcess(rtProc, att);
-    TokenExecutorImpl.StartCallback callback = new TokenExecutorImpl.StartCallback()
+    final RunnableProcess runnableProcess = new RunnableProcess(rtProc);
+    runtimeProcesses.put(proc.getID(), rtProc);
+    
+    StartCallback startCallback = new StartCallback()
     {
       public void start(Token token)
       {
-        processStartTimeAssignments(procImpl, token);
-        
-        Thread executorThread = new Thread(runnableProcess);
-        procImpl.setExecutorThread(executorThread);
-        executorThread.start();
+        // Process start time assignments
+        startTimeAssignments(proc, token);
+
+        // Execute the Process through the ExecutorService
+        ExecutorService processExecutor = getProcessExecutor();
+        log.debug("Execute runnableProcess");
+        processExecutor.execute(runnableProcess);
+        //new Thread(runnableProcess).start();
+
+        synchronized (proc)
+        {
+          // Wait for the process to become active
+          while (proc.getProcessStatus() == ProcessStatus.Ready)
+          {
+            try
+            {
+              log.debug("Wait for process to become active");
+              proc.wait();
+              log.debug("Notified: " + proc);
+            }
+            catch (InterruptedException ex)
+            {
+              log.error(ex);
+            }
+          }
+        }
       }
     };
-    TokenExecutor tokenExecutor = new TokenExecutorImpl(rtProc, callback);
-    rtProc.setTokenExecutor(tokenExecutor);
-    addRuntimeProcess(rtProc);
+    rtProc.setTokenExecutor(new TokenExecutorImpl(rtProc, startCallback));
 
-    StartEvent start = getStartEvent(procImpl);
+    // Get the None Start Event if there is one and start the initial flow
+    StartEvent start = getNoneStartEvent(proc);
     if (start != null)
-    {
-      TokenImpl token = new TokenImpl(att);
-      tokenExecutor.create(token, new InitialFlow(start));
-      tokenExecutor.start(token);
-    }
+      startProcessInternal(start, att);
   }
 
-  private StartEvent getStartEvent(ProcessImpl proc)
+  @Override
+  public void startProcess(StartEvent start, Attachments att)
   {
+    startProcessInternal(start, att);
+  }
+
+  private synchronized void startProcessInternal(StartEvent start, Attachments att)
+  {
+    ObjectName procID = start.getProcess().getID();
+    RuntimeProcess rtProc = runtimeProcesses.get(procID);
+    TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
+    TokenImpl token = new TokenImpl(att);
+    tokenExecutor.create(token, new InitialFlow(start));
+    tokenExecutor.start(token);
+  }
+
+  private StartEvent getNoneStartEvent(Process proc)
+  {
     StartEvent start = null;
     for (StartEvent aux : proc.getFlowObjects(StartEvent.class))
     {
@@ -118,9 +150,9 @@
     }
     return start;
   }
-  
+
   // Evaluate the Start time assignments
-  private void processStartTimeAssignments(ProcessImpl proc, Token token)
+  private void startTimeAssignments(Process proc, Token token)
   {
     DelegatingToken delegatingToken = new DelegatingToken((MutableToken)token);
     ExecutionContext exContext = token.getExecutionContext();
@@ -151,78 +183,73 @@
   }
 
   /**
-   * Get a {@link RuntimeProcess} for a given processID
-   * @return null if there is no such process
+   * The runnable Process
    */
-  public RuntimeProcess getRuntimeProcess(ObjectName procID)
-  {
-    return runtimeProcesses.get(procID);
-  }
-  
-  protected void addRuntimeProcess(RuntimeProcess rtProc)
-  {
-    ObjectName procID = rtProc.getProcess().getID();
-    runtimeProcesses.put(procID, rtProc);
-  }
-  
-  protected void removeRuntimeProcess(RuntimeProcess rtProc)
-  {
-    runtimeProcesses.remove(rtProc.getProcess().getID());
-  }
-  
   class RunnableProcess implements Runnable
   {
-    RuntimeProcess rtProc;
-    Attachments att;
+    private RuntimeProcess rtProc;
 
-    public RunnableProcess(RuntimeProcess rtProc, Attachments att)
+    public RunnableProcess(RuntimeProcess rtProc)
     {
       this.rtProc = rtProc;
-      this.att = att;
     }
 
     public void run()
     {
+      log.debug("RunnableProcess started");
+
       TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
-      ProcessImpl proc = (ProcessImpl)rtProc.getProcess();
-      
+      ProcessImpl procImpl = (ProcessImpl)rtProc.getProcess();
+      Process proc = rtProc.getProcess();
+
+      SignalManager signalManager = SignalManager.locateSignalManager();
+
+      ObjectName procID = proc.getID();
       String procName = proc.getName();
-      Process.ProcessStatus procStatus = proc.getProcessStatus();
-      boolean hasActiveTokens = tokenExecutor.hasRunnableTokens();
       try
       {
         synchronized (proc)
         {
-          while (procStatus == Process.ProcessStatus.Active && hasActiveTokens)
+          procImpl.setProcessStatus(ProcessStatus.Active);
+          signalManager.throwSignal(proc.getName(), new Signal(proc.getName(), SignalType.SYSTEM_PROCESS_ENTER));
+
+          // Notify that the Process is Active
+          proc.notifyAll();
+
+          // Wait until there are no more runnable tokens
+          while (tokenExecutor.hasRunnableTokens())
           {
             try
             {
+              log.debug("Start Waiting");
               proc.wait();
+              log.debug("Stop Waiting");
             }
             catch (InterruptedException ex)
             {
               log.error("Executor thread interrupted");
             }
-            procStatus = proc.getProcessStatus();
-            hasActiveTokens = tokenExecutor.hasRunnableTokens();
           }
-          log.debug("End execution thread [status=" + procStatus + ",tokens=" + tokenExecutor.getRunnableTokens() + "]");
+          log.debug("End execution thread [proc=" + procName + ",status=" + proc.getProcessStatus() + "]");
         }
       }
       finally
       {
-        SignalManager signalManager = SignalManager.locateSignalManager();
         signalManager.throwSignal(procName, new Signal(procName, Signal.SignalType.SYSTEM_PROCESS_EXIT));
 
-        if (procStatus == Process.ProcessStatus.Active)
+        synchronized (proc)
         {
-          ProcessImpl procImpl = (ProcessImpl)rtProc.getProcess();
-          procImpl.setProcessStatus(Process.ProcessStatus.Completed);
+          if (proc.getProcessStatus() == ProcessStatus.Active)
+            procImpl.setProcessStatus(ProcessStatus.Completed);
+
+          ProcessManager procManager = ProcessManager.locateProcessManager();
+          procManager.unregisterProcess(proc);
+          runtimeProcesses.remove(procID);
+
+          // Notify the Process
+          log.debug("Notify Process");
+          proc.notifyAll();
         }
-
-        ProcessManager procManager = ProcessManager.locateProcessManager();
-        procManager.unregisterProcess(rtProc.getProcess());
-        removeRuntimeProcess(rtProc);
       }
     }
   }

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ProcessManagerImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ProcessManagerImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/ProcessManagerImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -28,7 +28,8 @@
 import org.jboss.bpm.client.DialectHandler;
 import org.jboss.bpm.client.DialectRegistry;
 import org.jboss.bpm.client.ProcessManager;
-
+import org.jboss.bpm.model.Process;
+import org.jboss.bpm.ri.model.impl.ProcessImpl;
 /**
  * The process manager is the entry point to create, find and otherwise manage processes.
  * 
@@ -46,4 +47,20 @@
   {
     this.dialectRegistry = dialectRegistry;
   }
+
+  @Override
+  public void registerProcess(Process proc)
+  {
+    super.registerProcess(proc);
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    procImpl.registerElement(proc);
+  }
+
+  @Override
+  public void unregisterProcess(Process proc)
+  {
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    procImpl.unregisterElement(proc);
+    super.unregisterProcess(proc);
+  }
 }

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/RunnableToken.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/RunnableToken.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/client/RunnableToken.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -28,6 +28,7 @@
 import org.jboss.bpm.model.ConnectingObject;
 import org.jboss.bpm.model.FlowObject;
 import org.jboss.bpm.model.Process;
+import org.jboss.bpm.model.Process.ProcessStatus;
 import org.jboss.bpm.ri.model.impl.FlowObjectImpl;
 import org.jboss.bpm.ri.model.impl.ProcessImpl;
 import org.jboss.bpm.ri.runtime.DelegatingToken;
@@ -67,7 +68,7 @@
   public void run()
   {
     TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
-    ProcessImpl procImpl = (ProcessImpl)rtProc.getProcess();
+    Process proc = rtProc.getProcess();
     try
     {
       ConnectingObject flow = token.getFlow();
@@ -75,8 +76,8 @@
         throw new IllegalStateException("Cannot obtain initial flow");
 
       TokenStatus tokStatus = token.getTokenStatus();
-      Process.ProcessStatus procStatus = procImpl.getProcessStatus();
-      while (procStatus == Process.ProcessStatus.Active && tokStatus == TokenStatus.Started)
+      ProcessStatus procStatus = proc.getProcessStatus();
+      while (procStatus == ProcessStatus.Active && tokStatus == TokenStatus.Started)
       {
         flow = token.getFlow();
 
@@ -85,7 +86,7 @@
         SignalHandler sigHandler = getSignalHandler(targetFlowObject);
 
         // Synchronize execution on the target FlowObject
-        synchronized (procImpl)
+        synchronized (targetFlowObject)
         {
           try
           {
@@ -111,28 +112,22 @@
           {
             sigHandler.throwExitSignal();
           }
+          
+          tokStatus = token.getTokenStatus();
+          procStatus = proc.getProcessStatus();
         }
-
-        tokStatus = token.getTokenStatus();
-        procStatus = procImpl.getProcessStatus();
       }
     }
     catch (RuntimeException rte)
     {
-      log.error("Process aborted: " + procImpl, rte);
-      procImpl.setProcessStatus(Process.ProcessStatus.Aborted);
-      procImpl.setRuntimeException(rte);
+      log.error("Process aborted: " + proc, rte);
+      ((ProcessImpl)proc).setRuntimeException(rte);
+      tokenExecutor.destroy(token);
     }
     finally
     {
       if (token.getTokenStatus() != TokenStatus.Suspended)
-        token.setTokenStatus(TokenStatus.Destroyed);
-      
-      synchronized (procImpl)
-      {
-        // Notify the ExecutionManager when a token terminates
-        procImpl.notifyAll();
-      }
+        tokenExecutor.destroy(token);
     }
   }
 

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/AbstractElementImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/AbstractElementImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/AbstractElementImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -26,16 +26,13 @@
 import javax.management.ObjectName;
 
 import org.jboss.bpm.model.AbstractElement;
-import org.jboss.bpm.model.ConnectingObject;
 import org.jboss.bpm.model.Constants;
-import org.jboss.bpm.model.Event;
-import org.jboss.bpm.model.Gateway;
 import org.jboss.bpm.model.ObjectNameFactory;
 import org.jboss.bpm.model.Process;
-import org.jboss.bpm.model.Task;
 import org.jboss.util.id.UID;
 
 /**
+ * The parrent of all Elements
  * 
  * @author thomas.diesler at jboss.com
  * @since 08-Jul-2008
@@ -43,53 +40,51 @@
 @SuppressWarnings("serial")
 public class AbstractElementImpl implements AbstractElement
 {
-  private ObjectName id;
+  protected ObjectName id;
 
+  /**
+   * Get the ID of this element
+   */
   public ObjectName getID()
   {
+    if (id == null)
+    {
+      StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
+      str.append("type=Other,id=" + new UID());
+      id = ObjectNameFactory.create(str.toString());
+    }
     return id;
   }
 
   /**
-   * Initialize the flow object
+   * Called when the process is created
    */
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    assignElementID();
+    // nothing to do
   }
 
-  protected void assignElementID()
+  /**
+   * Called when the process is registered
+   */
+  protected void registerElement(Process proc)
   {
-    StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
-    if (this instanceof Event)
-    {
-      Event event = (Event)this;
-      str.append("type=Event,name=" + event.getName());
-    }
-    else if (this instanceof Process)
-    {
-      Process proc = (Process)this;
-      str.append("type=Process,name=" + proc.getName());
-    }
-    else if (this instanceof Task)
-    {
-      Task task = (Task)this;
-      str.append("type=Task,name=" + task.getName());
-    }
-    else if (this instanceof Gateway)
-    {
-      Gateway gateway = (Gateway)this;
-      str.append("type=Gateway,name=" + gateway.getName());
-    }
-    else if (this instanceof ConnectingObject)
-    {
-      str.append("type=Flow");
-    }
-    else
-    {
-      str.append("type=Other");
-    }
-    str.append(",id=" + new UID());
-    this.id = ObjectNameFactory.create(str.toString());
+    // nothing to do
   }
+
+  /**
+   * Called when the process is unregistered
+   */
+  protected void unregisterElement(Process proc)
+  {
+    // nothing to do
+  }
+
+  /**
+   * Called when the process is destroyed
+   */
+  protected void destroyElement(Process proc)
+  {
+    // nothing to do
+  }
 }
\ No newline at end of file

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ActivityImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ActivityImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ActivityImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -35,6 +35,7 @@
 import org.jboss.bpm.model.InputSet;
 import org.jboss.bpm.model.MutablePropertySupport;
 import org.jboss.bpm.model.OutputSet;
+import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.Property;
 import org.jboss.bpm.model.SequenceFlow;
 import org.jboss.bpm.ri.runtime.MutableToken;
@@ -299,9 +300,9 @@
   }
 
   @Override
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    super.initialize(proc);
+    super.createElement(proc);
 
     // Validate InputSets
     for (InputSet inSet : inputSets)

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EndEventImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EndEventImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EndEventImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -33,6 +33,7 @@
 import org.jboss.bpm.model.EndEvent;
 import org.jboss.bpm.model.EventDetail;
 import org.jboss.bpm.model.MessageEventDetail;
+import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.SequenceFlow;
 import org.jboss.bpm.model.Signal;
 import org.jboss.bpm.model.EventDetail.EventDetailType;
@@ -134,9 +135,9 @@
   }
 
   @Override
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    super.initialize(proc);
+    super.createElement(proc);
     
     // Initialize Results
     for (EventDetail result : getResult())

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EventImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EventImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/EventImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -21,14 +21,18 @@
  */
 package org.jboss.bpm.ri.model.impl;
 
+import javax.management.ObjectName;
+
+import org.jboss.bpm.model.Constants;
 import org.jboss.bpm.model.Event;
+import org.jboss.bpm.model.ObjectNameFactory;
+import org.jboss.util.id.UID;
 
 //$Id$
 
 /**
- * An Event is something that “happens” during the course of a business process. 
- * <p/>
- * These Events affect the flow of the Process and usually have a cause or an impact.
+ * An Event is something that “happens” during the course of a business process. <p/> These Events affect the flow of
+ * the Process and usually have a cause or an impact.
  * 
  * @author thomas.diesler at jboss.com
  * @since 08-Jul-2008
@@ -40,4 +44,16 @@
   {
     super(name);
   }
+
+  @Override
+  public ObjectName getID()
+  {
+    if (id == null)
+    {
+      StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
+      str.append("type=Event,name=" + getName() + ",id=" + new UID());
+      id = ObjectNameFactory.create(str.toString());
+    }
+    return id;
+  }
 }
\ No newline at end of file

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/FlowObjectImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/FlowObjectImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/FlowObjectImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -56,7 +56,7 @@
 public abstract class FlowObjectImpl extends GraphicalElementImpl implements FlowObject, HandlerSetterSupport
 {
   private String name;
-  private ProcessImpl proc;
+  private Process proc;
   private FlowHandler flowHandler;
   private SignalHandler signalHandler;
   private ExecutionHandler executionHandler;
@@ -212,9 +212,9 @@
   }
 
   @Override
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    super.initialize(proc);
+    super.createElement(proc);
     this.proc = proc;
 
     // Check required name

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/GatewayImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/GatewayImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/GatewayImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -29,16 +29,21 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.management.ObjectName;
+
 import org.jboss.bpm.client.SignalManager;
 import org.jboss.bpm.model.ConnectingObject;
+import org.jboss.bpm.model.Constants;
 import org.jboss.bpm.model.Gate;
 import org.jboss.bpm.model.Gateway;
+import org.jboss.bpm.model.ObjectNameFactory;
 import org.jboss.bpm.model.SequenceFlow;
 import org.jboss.bpm.model.Signal;
 import org.jboss.bpm.model.SequenceFlow.ConditionType;
 import org.jboss.bpm.runtime.ExecutionHandler;
 import org.jboss.bpm.runtime.SignalHandler;
 import org.jboss.bpm.runtime.Token;
+import org.jboss.util.id.UID;
 
 /**
  * Gateways are modelling elements that are used to control how Sequence Flow interact as they converge and diverge
@@ -64,6 +69,18 @@
     super(name);
   }
 
+  @Override
+  public ObjectName getID()
+  {
+    if (id == null)
+    {
+      StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
+      str.append("type=Gateway,name=" + getName() + ",id=" + new UID());
+      id = ObjectNameFactory.create(str.toString());
+    }
+    return id;
+  }
+  
   public List<Gate> getGates()
   {
     return Collections.unmodifiableList(new ArrayList<Gate>(gates.values()));

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessBuilderImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessBuilderImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessBuilderImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -85,16 +85,13 @@
 
   public Process getProcess()
   {
-    if (getProcessInternal() == null)
-      throw new IllegalStateException("No process has been added");
-    getProcessInternal().initialize();
-    return getProcessInternal();
+    ProcessImpl internalProc = getProcessInternal();
+    internalProc.createElement(internalProc);
+    return internalProc;
   }
 
   public Process getProcessForInclude()
   {
-    if (getProcessInternal() == null)
-      throw new IllegalStateException("No process has been added");
     return getProcessInternal();
   }
 

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ProcessImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -23,10 +23,6 @@
 
 //$Id$
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -41,17 +37,20 @@
 import org.jboss.bpm.ProcessTimeoutException;
 import org.jboss.bpm.client.ProcessManager;
 import org.jboss.bpm.model.Assignment;
+import org.jboss.bpm.model.Constants;
 import org.jboss.bpm.model.EndEvent;
 import org.jboss.bpm.model.FlowObject;
 import org.jboss.bpm.model.InputSet;
 import org.jboss.bpm.model.Message;
 import org.jboss.bpm.model.MutablePropertySupport;
+import org.jboss.bpm.model.ObjectNameFactory;
 import org.jboss.bpm.model.OutputSet;
 import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.Property;
 import org.jboss.bpm.model.StartEvent;
 import org.jboss.bpm.ri.client.ProcessManagerImpl;
 import org.jboss.bpm.runtime.Attachments;
+import org.jboss.util.id.UID;
 
 /**
  * A Process is any Activity performed within a company or organization.
@@ -76,12 +75,22 @@
   // The process assignments
   private List<Assignment> assignments = new ArrayList<Assignment>();
   // the status of the process
-  private Process.ProcessStatus status = Process.ProcessStatus.None;
+  private ProcessStatus status = ProcessStatus.None;
   // The possible exception that caused the process to abort
   private RuntimeException runtimeException;
-  // The thread of the executor
-  private Thread executorThread;
 
+  @Override
+  public ObjectName getID()
+  {
+    if (id == null)
+    {
+      StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
+      str.append("type=Process,name=" + getName() + ",id=" + new UID());
+      id = ObjectNameFactory.create(str.toString());
+    }
+    return id;
+  }
+  
   public ProcessImpl(String name)
   {
     this.name = name;
@@ -143,7 +152,7 @@
     Property prop = getProperty(name);
     return prop != null ? prop.getValue(clazz) : null;
   }
-  
+
   public List<Property> getProperties()
   {
     return Collections.unmodifiableList(props);
@@ -177,39 +186,17 @@
   public void setRuntimeException(RuntimeException rte)
   {
     this.runtimeException = rte;
+    setProcessStatus(ProcessStatus.Aborted);
   }
 
   public List<FlowObject> getFlowObjects()
   {
-
-    if (status == Process.ProcessStatus.None)
+    if (status == ProcessStatus.None)
       return flowObjects;
 
     return Collections.unmodifiableList(flowObjects);
   }
 
-  /**
-   * A naive copy implementation that relies on serialization
-   */
-  public Process copyProcess()
-  {
-    try
-    {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      ObjectOutputStream oos = new ObjectOutputStream(baos);
-      oos.writeObject(this);
-      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-      ObjectInputStream ois = new ObjectInputStream(bais);
-      ProcessImpl proc = (ProcessImpl)ois.readObject();
-      proc.assignElementID();
-      return proc;
-    }
-    catch (Exception ex)
-    {
-      throw new InvalidProcessException("Cannot create a copy of: " + this, ex);
-    }
-  }
-
   public ObjectName startProcess()
   {
     return startProcess(null);
@@ -219,10 +206,10 @@
   {
     ProcessManager pm = ProcessManager.locateProcessManager();
 
-    if (status == Process.ProcessStatus.Aborted || status == Process.ProcessStatus.Completed)
+    if (status == ProcessStatus.Aborted || status == ProcessStatus.Completed)
       resetProcess();
 
-    if (status != Process.ProcessStatus.Ready)
+    if (status != ProcessStatus.Ready)
       throw new IllegalStateException("Cannot start process in state: " + status);
 
     // Register the process if needed
@@ -244,18 +231,18 @@
       FlowObjectImpl foImpl = (FlowObjectImpl)fo;
       foImpl.reset();
     }
-    status = Process.ProcessStatus.Ready;
+    status = ProcessStatus.Ready;
     runtimeException = null;
   }
 
-  public void waitForEnd()
+  public ProcessStatus waitForEnd()
   {
-    waitForEndInternal(0);
+    return waitForEndInternal(0);
   }
 
-  public void waitForEnd(long timeout)
+  public ProcessStatus waitForEnd(long timeout)
   {
-    waitForEndInternal(timeout);
+    return waitForEndInternal(timeout);
   }
 
   /**
@@ -263,14 +250,11 @@
    * 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 void waitForEndInternal(long timeout)
+  private ProcessStatus waitForEndInternal(long timeout)
   {
-    if (status == Process.ProcessStatus.None || status == Process.ProcessStatus.Ready)
+    if (status != ProcessStatus.Ready && status != ProcessStatus.Active)
       throw new IllegalStateException("Cannot wait for process in state: " + status);
 
-    if (executorThread == null)
-      throw new IllegalStateException("No start signal, cannot obtain excutor thread");
-    
     // Wait a little for the process to end
     boolean forever = (timeout < 1);
     long now = System.currentTimeMillis();
@@ -279,28 +263,35 @@
     {
       while (forever || now < until)
       {
-        if (isProcessTerminated())
+        synchronized (this)
         {
-          if (getRuntimeException() != null)
-            throw new BPMException("Process aborted", getRuntimeException());
-
-          break;
+          if (isProcessTerminated())
+          {
+            if (runtimeException != null)
+            {
+              throw new BPMException("Process aborted", runtimeException);
+            }
+            else
+            {
+              break;
+            }
+          }
+          
+          // Start waiting to get notified
+          long waitTimeout = forever ? 0 : until - now;
+          log.debug("Start Waiting: " + waitTimeout + "ms");
+          wait(waitTimeout);
+          log.debug("Stop Waiting");
         }
-
-        // Join the executor thread
-        getExecutorThread().join(timeout);
         now = System.currentTimeMillis();
       }
-
+      
       // Throw timeout exception if it took too long
       if (isProcessTerminated() == false)
       {
         RuntimeException rte = new ProcessTimeoutException("Process timeout after " + timeout + "ms for: " + getID());
+        setRuntimeException(rte);
         log.error(rte);
-
-        log.error("Interrupt executor thread");
-        getExecutorThread().interrupt();
-
         throw rte;
       }
     }
@@ -315,11 +306,13 @@
       if (procManager.getProcessByID(getID()) != null)
         procManager.unregisterProcess(this);
     }
+
+    return status;
   }
 
-  private boolean isProcessTerminated()
+  private synchronized boolean isProcessTerminated()
   {
-    return status == Process.ProcessStatus.Cancelled || status == Process.ProcessStatus.Completed || status == Process.ProcessStatus.Aborted;
+    return status == ProcessStatus.Cancelled || status == ProcessStatus.Completed || status == ProcessStatus.Aborted;
   }
 
   public FlowObject getFlowObject(String name)
@@ -351,26 +344,16 @@
     return retFlowObjects;
   }
 
-  public Process.ProcessStatus getProcessStatus()
+  public synchronized ProcessStatus getProcessStatus()
   {
     return status;
   }
 
-  public void setProcessStatus(Process.ProcessStatus status)
+  public synchronized void setProcessStatus(ProcessStatus status)
   {
     this.status = status;
   }
 
-  public Thread getExecutorThread()
-  {
-    return executorThread;
-  }
-
-  public void setExecutorThread(Thread executorThread)
-  {
-    this.executorThread = executorThread;
-  }
-
   public List<Message> getMessages()
   {
     return Collections.unmodifiableList(messages);
@@ -394,13 +377,14 @@
     return null;
   }
 
-  public void initialize()
+  @Override
+  public void createElement(Process proc)
   {
-    if (status != Process.ProcessStatus.None)
+    if (status != ProcessStatus.None)
       throw new IllegalStateException("Cannot initialize process in state: " + status);
 
     // Initialize the Element
-    super.initialize(this);
+    super.createElement(this);
 
     // Set the anonymous default name
     if (getName() == null)
@@ -419,12 +403,45 @@
     for (FlowObject fo : flowObjects)
     {
       FlowObjectImpl foImpl = (FlowObjectImpl)fo;
-      foImpl.initialize(this);
+      foImpl.createElement(this);
     }
 
-    status = Process.ProcessStatus.Ready;
+    status = ProcessStatus.Ready;
   }
 
+  @Override
+  public void registerElement(Process proc)
+  {
+    super.registerElement(proc);
+    for (FlowObject fo : flowObjects)
+    {
+      FlowObjectImpl foImpl = (FlowObjectImpl)fo;
+      foImpl.registerElement(this);
+    }
+  }
+
+  @Override
+  public void unregisterElement(Process proc)
+  {
+    for (FlowObject fo : flowObjects)
+    {
+      FlowObjectImpl foImpl = (FlowObjectImpl)fo;
+      foImpl.unregisterElement(this);
+    }
+    super.unregisterElement(proc);
+  }
+
+  @Override
+  public void destroyElement(Process proc)
+  {
+    for (FlowObject fo : flowObjects)
+    {
+      FlowObjectImpl foImpl = (FlowObjectImpl)fo;
+      foImpl.destroyElement(this);
+    }
+    super.destroyElement(proc);
+  }
+  
   protected void initializeMessageRef(Message msgRef)
   {
     String msgName = msgRef.getName();
@@ -444,6 +461,6 @@
 
   public String toString()
   {
-    return "Process[" + getName() + "]";
+    return "Process[" + getName() + ",status=" + status + "]";
   }
 }
\ No newline at end of file

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ReceiveTaskImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ReceiveTaskImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/ReceiveTaskImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -30,6 +30,7 @@
 import org.jboss.bpm.NotImplementedException;
 import org.jboss.bpm.client.MessageListener;
 import org.jboss.bpm.model.Message;
+import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.Property;
 import org.jboss.bpm.model.ReceiveTask;
 import org.jboss.bpm.model.Message.Implementation;
@@ -169,13 +170,14 @@
   }
 
   @Override
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    super.initialize(proc);
+    super.createElement(proc);
 
     if (messageRef == null)
       throw new InvalidProcessException("A Message for the MessageRef attribute MUST be entered");
 
-    proc.initializeMessageRef(messageRef);
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    procImpl.initializeMessageRef(messageRef);
   }
 }
\ No newline at end of file

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/SendTaskImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/SendTaskImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/SendTaskImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -26,6 +26,7 @@
 
 import org.jboss.bpm.InvalidProcessException;
 import org.jboss.bpm.model.Message;
+import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.SendTask;
 import org.jboss.bpm.model.Message.Implementation;
 import org.jboss.bpm.runtime.Token;
@@ -79,14 +80,15 @@
   }
 
   @Override
-  protected void initialize(ProcessImpl proc)
+  protected void createElement(Process proc)
   {
-    super.initialize(proc);
+    super.createElement(proc);
 
     if (messageRef == null)
       throw new InvalidProcessException("A Message for the MessageRef attribute MUST be entered");
 
-    proc.initializeMessageRef(messageRef);
+    ProcessImpl procImpl = (ProcessImpl)proc;
+    procImpl.initializeMessageRef(messageRef);
     
     if (messageRef.getToRef() == null)
       throw new IllegalArgumentException("Message targetID cannot be null for: " + this);

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/StartEventImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/StartEventImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/StartEventImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -38,9 +38,7 @@
 import org.jboss.bpm.model.Signal;
 import org.jboss.bpm.model.SignalEventDetail;
 import org.jboss.bpm.model.StartEvent;
-import org.jboss.bpm.ri.client.ExecutionManagerImpl;
-import org.jboss.bpm.ri.runtime.RuntimeProcess;
-import org.jboss.bpm.ri.runtime.TokenImpl;
+import org.jboss.bpm.model.Process.ProcessStatus;
 import org.jboss.bpm.runtime.SignalHandler;
 import org.jboss.bpm.runtime.Token;
 import org.jboss.bpm.runtime.TokenExecutor;
@@ -61,6 +59,7 @@
 
   private SequenceFlow outFlow;
   private List<EventDetail> triggers = new ArrayList<EventDetail>();
+  private SignalListener startListener;
 
   public StartEventImpl(String name)
   {
@@ -118,9 +117,9 @@
   }
 
   @Override
-  protected void initialize(final ProcessImpl proc)
+  protected void registerElement(final Process proc)
   {
-    super.initialize(proc);
+    super.registerElement(proc);
     
     for (EventDetail eventDetail : getTrigger())
     {
@@ -130,45 +129,57 @@
       // Register the start signal listener
       if (eventDetail instanceof SignalEventDetail)
       {
-        SignalEventDetail signalEventDetail = (SignalEventDetail)eventDetail;
-        final Signal startSignal = signalEventDetail.getSignalRef();
-        final StartEvent start = this;
-        SignalListener listener = new SignalListener()
+        if (startListener == null)
         {
-          public void catchSignal(Signal signal)
+          SignalEventDetail signalEventDetail = (SignalEventDetail)eventDetail;
+          final Signal startSignal = signalEventDetail.getSignalRef();
+          final StartEvent start = this;
+          startListener = new SignalListener()
           {
-            if (startSignal.getSignalType() == signal.getSignalType() && startSignal.getMessage().equals(signal.getMessage()))
+            public void catchSignal(Signal signal)
             {
-              log.debug("catchSignal: " + signal);
-              if (proc.getProcessStatus() == Process.ProcessStatus.Active)
+              if (startSignal.getSignalType() == signal.getSignalType() && startSignal.getMessage().equals(signal.getMessage()))
               {
-                log.debug("Start process from signal: " + signal);
-                ExecutionManagerImpl exManager = (ExecutionManagerImpl)ExecutionManager.locateExecutionManager();
-                RuntimeProcess rtProc = exManager.getRuntimeProcess(start.getProcess().getID());
-                TokenExecutor tokenExecutor = rtProc.getTokenExecutor();
-                TokenImpl token = new TokenImpl(null);
-                tokenExecutor.create(token, getOutFlow());
-                tokenExecutor.start(token);
+                log.debug("catchSignal: " + signal);
+                ProcessStatus procStatus = proc.getProcessStatus();
+                if (procStatus == ProcessStatus.Ready || procStatus == ProcessStatus.Active)
+                {
+                  log.debug("Start process from signal: " + signal);
+                  ExecutionManager exManager = ExecutionManager.locateExecutionManager();
+                  exManager.startProcess(start, null);
+                }
+                else
+                {
+                  log.debug("Ignore start signal for process: " + proc);
+                }
               }
-              else
-              {
-                log.debug("Ignore start signal for process: " + proc);
-              }
             }
-          }
-          
-          public String toString()
-          {
-            return start + "." + startSignal;
-          }
-        };
-        SignalManager signalManager = SignalManager.locateSignalManager();
-        signalManager.addSignalListener(getProcess().getName(), listener);
+            
+            public String toString()
+            {
+              return start + "." + startSignal;
+            }
+          };
+          SignalManager signalManager = SignalManager.locateSignalManager();
+          signalManager.addSignalListener(getProcess().getName(), startListener);
+        }
       }
     }
   }
+  
+  @Override
+  protected void unregisterElement(final Process proc)
+  {
+    // Unregister the start signal listener
+    if (startListener != null)
+    {
+      SignalManager signalManager = SignalManager.locateSignalManager();
+      signalManager.removeSignalListener(getProcess().getName(), startListener);
+      startListener = null;
+    }
+    super.unregisterElement(proc);
+  }
 
-  
   public String toString()
   {
     return "StartEvent[" + getName() + "]";

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TaskImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TaskImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TaskImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -21,10 +21,15 @@
  */
 package org.jboss.bpm.ri.model.impl;
 
+import javax.management.ObjectName;
+
 import org.jboss.bpm.client.SignalManager;
+import org.jboss.bpm.model.Constants;
+import org.jboss.bpm.model.ObjectNameFactory;
 import org.jboss.bpm.model.Signal;
 import org.jboss.bpm.model.Task;
 import org.jboss.bpm.runtime.SignalHandler;
+import org.jboss.util.id.UID;
 
 //$Id$
 
@@ -52,6 +57,18 @@
 
   public abstract TaskType getTaskType();
 
+  @Override
+  public ObjectName getID()
+  {
+    if (id == null)
+    {
+      StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
+      str.append("type=Task,name=" + getName() + ",id=" + new UID());
+      id = ObjectNameFactory.create(str.toString());
+    }
+    return id;
+  }
+  
   public SignalHandler getSignalHandler()
   {
     SignalHandler handler = super.getSignalHandler();

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TokenExecutorImpl.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TokenExecutorImpl.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/model/impl/TokenExecutorImpl.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -36,6 +36,7 @@
 import org.jboss.bpm.model.ConnectingObject;
 import org.jboss.bpm.model.Process;
 import org.jboss.bpm.model.SequenceFlow;
+import org.jboss.bpm.model.Process.ProcessStatus;
 import org.jboss.bpm.ri.client.RunnableToken;
 import org.jboss.bpm.ri.runtime.MutableToken;
 import org.jboss.bpm.ri.runtime.RuntimeProcess;
@@ -45,8 +46,8 @@
 import org.jboss.bpm.runtime.Token.TokenStatus;
 
 /**
- * The {@link FlowHandler} invokes the TokenExecutor to schedule 
- * {@link ConnectingObject} objects together with their associated {@link Token}.
+ * The {@link FlowHandler} invokes the TokenExecutor to schedule {@link ConnectingObject} objects together with their
+ * associated {@link Token}.
  * 
  * @author thomas.diesler at jboss.com
  * @since 08-Jul-2008
@@ -55,7 +56,7 @@
 {
   // provide logging
   private static final Log log = LogFactory.getLog(TokenExecutorImpl.class);
-  
+
   public interface StartCallback
   {
     void start(Token token);
@@ -77,7 +78,7 @@
     Set<Token> tokenSet = new HashSet<Token>();
     for (RunnableToken rt : runnableTokens.values())
       tokenSet.add(rt.getToken());
-    
+
     return Collections.unmodifiableSet(tokenSet);
   }
 
@@ -85,7 +86,7 @@
   {
     return runnableTokens.size() > 0;
   }
-  
+
   public void create(Token token, SequenceFlow initialFlow)
   {
     MutableToken mutableToken = (MutableToken)token;
@@ -93,23 +94,25 @@
     RunnableToken rtToken = new RunnableToken(rtProc, mutableToken);
     runnableTokens.put(token.getTokenID(), rtToken);
   }
-  
+
   public void start(Token token)
   {
     Process proc = rtProc.getProcess();
-    if (proc.getProcessStatus() != Process.ProcessStatus.Active)
-      throw new IllegalStateException("Cannot start token to process in state: " + proc.getProcessStatus());
-    
+    ProcessStatus procStatus = proc.getProcessStatus();
+    if (procStatus != ProcessStatus.Ready && procStatus != ProcessStatus.Active)
+      throw new IllegalStateException("Cannot start token to process in state: " + procStatus);
+
     log.debug("Start Token: " + token);
     MutableToken mutableToken = (MutableToken)token;
     mutableToken.setTokenStatus(TokenStatus.Started);
-    
+
     if (startCallback != null)
     {
+      log.debug("Call start callback: " + token);
       startCallback.start(token);
       startCallback = null;
     }
-    
+
     RunnableToken rtToken = runnableTokens.get(token.getTokenID());
     executor.submit(rtToken);
   }
@@ -118,7 +121,7 @@
   {
     if (flow == null)
       throw new IllegalArgumentException("Flow cannot be null");
-    
+
     MutableToken mutableToken = (MutableToken)token;
     mutableToken.setFlow(flow);
   }
@@ -151,15 +154,15 @@
     RunnableToken rtToken = runnableTokens.get(tokenID);
     if (rtToken == null)
       throw new IllegalStateException("Not a runnable token: " + tokenID);
-    
+
     Token token = rtToken.getToken();
     if (token.getTokenStatus() != TokenStatus.Suspended)
       throw new IllegalStateException("Activate token in state: " + token.getTokenStatus());
-      
+
     log.debug("Activate Token: " + token);
     MutableToken mutableToken = (MutableToken)token;
     mutableToken.setTokenStatus(TokenStatus.Started);
-    
+
     executor.submit(rtToken);
     return token;
   }

Modified: jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/runtime/DelegatingExecutionContext.java
===================================================================
--- jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/runtime/DelegatingExecutionContext.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/ri/src/main/java/org/jboss/bpm/ri/runtime/DelegatingExecutionContext.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -53,7 +53,7 @@
     this.flowObject = flowObject;
     this.delegate = delegate;
 
-    proc = (Process)flowObject.getProcess();
+    proc = flowObject.getProcess();
     procPrefix = proc.getName() + ".";
     activityPrefix = procPrefix + flowObject.getName() + ".";
   }

Modified: jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/gateway/parallel/ParallelGatewayMergeTest.java
===================================================================
--- jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/gateway/parallel/ParallelGatewayMergeTest.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/gateway/parallel/ParallelGatewayMergeTest.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -55,14 +55,14 @@
   public void testParallelMerge() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
     // Add a signal listener that sends the other start trigger signal
     SignalManager signalManager = SignalManager.locateSignalManager();
     Signal startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "B");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     // Wait for the process to end
@@ -77,11 +77,11 @@
   public void testMergeTimeout() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     SignalManager signalManager = SignalManager.locateSignalManager();
-    signalManager.throwSignal(proc.getName(), new Signal(proc.getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
+    signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     // Wait for the process to end
     try
@@ -98,14 +98,14 @@
   public void testInvalidToken() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
     // Add a signal listener that sends the other start trigger signal
     SignalManager signalManager = SignalManager.locateSignalManager();
     Signal startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     try
@@ -118,14 +118,12 @@
       // expected
     }
 
-    // Restart the process
-    proc.startProcess();
-    
     // Add a signal listener that sends the other start trigger signal
     startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "B");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     // Wait for the process to end

Added: jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/StartEventSignalTest.java
===================================================================
--- jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/StartEventSignalTest.java	                        (rev 0)
+++ jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/StartEventSignalTest.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -0,0 +1,159 @@
+/*
+ * 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.jboss.bpm.cts.startevent;
+
+// $Id$
+
+import java.io.IOException;
+import java.util.List;
+
+import org.jboss.bpm.client.SignalListener;
+import org.jboss.bpm.client.SignalManager;
+import org.jboss.bpm.model.EventBuilder;
+import org.jboss.bpm.model.EventDetail;
+import org.jboss.bpm.model.Message;
+import org.jboss.bpm.model.MessageBuilder;
+import org.jboss.bpm.model.Process;
+import org.jboss.bpm.model.ProcessBuilder;
+import org.jboss.bpm.model.ProcessBuilderFactory;
+import org.jboss.bpm.model.Signal;
+import org.jboss.bpm.model.TaskBuilder;
+import org.jboss.bpm.model.Assignment.AssignTime;
+import org.jboss.bpm.model.Expression.ExpressionLanguage;
+import org.jboss.bpm.model.Signal.SignalType;
+import org.jboss.bpm.test.DefaultEngineTestCase;
+
+/**
+ * Test start event with signal trigger
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 06-Aug-2008
+ */
+public class StartEventSignalTest extends DefaultEngineTestCase
+{
+  public void testStart() throws Exception
+  {
+    Process proc = getProcess();
+
+    // Start the process and send start trigger signal
+    proc.startProcess();
+    SignalManager signalManager = SignalManager.locateSignalManager();
+    signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
+
+    // Wait for the process to end
+    proc.waitForEnd();
+
+    // Verify the result
+    Message endMessage = getMessages().get(0);
+    assertEquals("TaskA", endMessage.getPropertyValue("taskValue"));
+  }
+
+  public void testRestart() throws Exception
+  {
+    Process proc = getProcess();
+
+    // Start the process and send start trigger signal
+    proc.startProcess();
+    SignalManager signalManager = SignalManager.locateSignalManager();
+    signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
+
+    // Wait for the process to end
+    proc.waitForEnd();
+
+    // Start the process and send start trigger signal
+    proc.startProcess();
+    signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
+
+    // Wait for the process to end
+    proc.waitForEnd();
+
+    // Verify the result
+    List<Message> messages = getMessages();
+    assertEquals(2, messages.size());
+    assertEquals("TaskA", messages.get(0).getPropertyValue("taskValue"));
+    assertEquals("TaskA", messages.get(1).getPropertyValue("taskValue"));
+  }
+
+  public void testRestartBeforeEnd() throws Exception
+  {
+    Process proc = getProcess();
+
+    // Add a signal listener that sends the other start trigger signal
+    SignalManager signalManager = SignalManager.locateSignalManager();
+    Signal startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A");
+    signalManager.addSignalListener(proc.getName(), new TaskListener(proc.getName(), startTrigger));
+
+    // Start the process and send start trigger signal
+    proc.startProcess();
+    signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
+
+    // Wait for the process to end
+    proc.waitForEnd();
+
+    // Verify the result
+    List<Message> messages = getMessages();
+    assertEquals(2, messages.size());
+    assertEquals("TaskA", messages.get(0).getPropertyValue("taskValue"));
+    assertEquals("TaskA", messages.get(1).getPropertyValue("taskValue"));
+  }
+
+  public Process getProcess() throws IOException
+  {
+    ProcessBuilder procBuilder = ProcessBuilderFactory.newInstance().newProcessBuilder();
+    EventBuilder eventBuilder = procBuilder.addProcess(getName()).addStartEvent("StartA");
+    eventBuilder.addEventDetail(EventDetail.EventDetailType.Signal).addSignalRef(SignalType.SYSTEM_START_TRIGGER, "A")
+        .addSequenceFlow("TaskA");
+    TaskBuilder taskBuilder = procBuilder.addTask("TaskA");
+    taskBuilder.addAssignment(AssignTime.Start, ExpressionLanguage.MVEL, "'TaskA'", "taskValue");
+    taskBuilder.addSequenceFlow("End");
+    procBuilder.addEndEvent("End").addEventDetail(EventDetail.EventDetailType.Message).addMessageRef("EndMessage");
+    MessageBuilder msgBuilder = procBuilder.addMessage("EndMessage");
+    msgBuilder.addToRef(getMessageListenerID()).addProperty("taskValue", null, true);
+    Process proc = procBuilder.getProcess();
+    return proc;
+  }
+
+  public static class TaskListener implements SignalListener
+  {
+    private String fromRef;
+    private Signal nextSignal;
+
+    public TaskListener(String fromRef, Signal nextSignal)
+    {
+      this.fromRef = fromRef;
+      this.nextSignal = nextSignal;
+    }
+
+    public void catchSignal(Signal signal)
+    {
+      if (signal.getSignalType() == SignalType.SYSTEM_TASK_ENTER)
+      {
+        if (nextSignal != null)
+        {
+          SignalManager signalManager = SignalManager.locateSignalManager();
+          signalManager.throwSignal(fromRef, nextSignal);
+          nextSignal = null;
+        }
+      }
+    }
+  }
+}


Property changes on: jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/cts/startevent/StartEventSignalTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/pattern/control/synchronization/SynchronizationTest.java
===================================================================
--- jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/pattern/control/synchronization/SynchronizationTest.java	2008-08-20 13:09:23 UTC (rev 1940)
+++ jbossbpm/spec/trunk/modules/testsuite/src/test/java/org/jboss/bpm/pattern/control/synchronization/SynchronizationTest.java	2008-08-20 14:07:10 UTC (rev 1941)
@@ -55,14 +55,14 @@
   public void testParallelMerge() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
     // Add a signal listener that sends the other start trigger signal
     SignalManager signalManager = SignalManager.locateSignalManager();
     Signal startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "B");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     // Wait for the process to end
@@ -77,9 +77,9 @@
   public void testMergeTimeout() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     SignalManager signalManager = SignalManager.locateSignalManager();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
@@ -98,14 +98,14 @@
   public void testInvalidToken() throws Exception
   {
     Process proc = getProcess();
-    proc.startProcess();
 
     // Add a signal listener that sends the other start trigger signal
     SignalManager signalManager = SignalManager.locateSignalManager();
     Signal startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     try
@@ -118,14 +118,12 @@
       // expected
     }
 
-    // Restart the process
-    proc.startProcess();
-    
     // Add a signal listener that sends the other start trigger signal
     startTrigger = new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "B");
     signalManager.addSignalListener(proc.getName(), new MergeListener(proc.getName(), startTrigger));
 
-    // Send start trigger signal
+    // Start the process and send start trigger signal
+    proc.startProcess();
     signalManager.throwSignal(proc.getName(), new Signal(getName(), SignalType.SYSTEM_START_TRIGGER, "A"));
 
     // Wait for the process to end




More information about the jbpm-commits mailing list