[jbpm-commits] JBoss JBPM SVN: r4924 - in jbpm4/trunk/modules: pvm/src/main/java/org/jbpm/pvm/internal/model and 3 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu May 28 03:17:23 EDT 2009


Author: tom.baeyens at jboss.com
Date: 2009-05-28 03:17:22 -0400 (Thu, 28 May 2009)
New Revision: 4924

Added:
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java
Removed:
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivityMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTakeMessage.java
Modified:
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ActivityImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExceptionHandlerImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java
   jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
   jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/EventTest.java
   jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/TransitionEventsTest.java
Log:
JBPM-2277 refactor execution state, atomic operations and job information

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -52,6 +52,7 @@
     
     JobDbSession jobDbSession = environment.get(JobDbSession.class);
     jobDbSession.delete(this);
+
     return null;
   }
 

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -52,9 +52,6 @@
   /** the time the lock on this jobImpl expires. */
   protected Date lockExpirationTime;
 
-  /** any information that subclasses might use in a specific way. */
-  protected String info;
-
   /** stack trace of the exception that occurred during command execution. */
   protected String exception;
   

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ActivityImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ActivityImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ActivityImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -400,6 +400,16 @@
     return ! (continuation==Continuation.SYNCHRONOUS);
   }
 
+  public boolean contains(ActivityImpl activity) {
+    while (activity!=null) {
+      if (activity.getParent()==this) {
+        return true;
+      }
+      activity = activity.getParentActivity();
+    }
+    return false;
+  }
+
   // getters and setters //////////////////////////////////////////////////////
   
   public ObservableElementImpl getParent() {

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -37,6 +37,7 @@
   private static final long serialVersionUID = 1L;
 
   protected String name;
+  protected ObservableElementImpl observableElement;
   protected List<EventListenerReference> listenerReferences;
   protected Continuation continuation = Continuation.SYNCHRONOUS;
 
@@ -100,4 +101,10 @@
   public void setContinuation(Continuation continuation) {
     this.continuation = continuation;
   }
+  public ObservableElementImpl getObservableElement() {
+    return observableElement;
+  }
+  public void setObservableElement(ObservableElementImpl observableElement) {
+    this.observableElement = observableElement;
+  }
 }
\ No newline at end of file

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExceptionHandlerImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExceptionHandlerImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExceptionHandlerImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -33,6 +33,7 @@
 import org.jbpm.api.listener.EventListener;
 import org.jbpm.api.model.OpenProcessDefinition;
 import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.model.op.AtomicOperation;
 import org.jbpm.pvm.internal.model.op.MoveToChildActivity;
 import org.jbpm.pvm.internal.wire.Descriptor;
 
@@ -196,7 +197,7 @@
         if (transition!=null) {
           log.trace(toString()+" takes transition "+transitionName);
           execution.setTransition(transition);
-          execution.performAtomicOperationSync(ExecutionImpl.TRANSITION_END_ACTIVITY);
+          execution.performAtomicOperationSync(AtomicOperation.TRANSITION_END_ACTIVITY);
         } else {
           log.info("WARNING: "+toString()+" couldn't find transition "+transitionName+" on "+activity);
         }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -40,9 +40,7 @@
 import org.jbpm.api.activity.ActivityExecution;
 import org.jbpm.api.client.ClientProcessDefinition;
 import org.jbpm.api.client.ClientProcessInstance;
-import org.jbpm.api.cmd.CommandService;
 import org.jbpm.api.env.Environment;
-import org.jbpm.api.env.Transaction;
 import org.jbpm.api.job.Timer;
 import org.jbpm.api.listener.EventListenerExecution;
 import org.jbpm.api.model.Activity;
@@ -56,7 +54,6 @@
 import org.jbpm.api.session.RepositorySession;
 import org.jbpm.api.session.TimerSession;
 import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.env.PvmEnvironment;
 import org.jbpm.pvm.internal.hibernate.HibernatePvmDbSession;
 import org.jbpm.pvm.internal.history.HistoryEvent;
 import org.jbpm.pvm.internal.history.HistorySession;
@@ -68,14 +65,8 @@
 import org.jbpm.pvm.internal.history.events.ProcessInstanceStart;
 import org.jbpm.pvm.internal.job.MessageImpl;
 import org.jbpm.pvm.internal.model.op.AtomicOperation;
-import org.jbpm.pvm.internal.model.op.ExecuteActivity;
-import org.jbpm.pvm.internal.model.op.ExecuteEventListener;
 import org.jbpm.pvm.internal.model.op.MoveToChildActivity;
-import org.jbpm.pvm.internal.model.op.MoveToParentActivity;
 import org.jbpm.pvm.internal.model.op.Signal;
-import org.jbpm.pvm.internal.model.op.TransitionEndActivity;
-import org.jbpm.pvm.internal.model.op.TransitionStartActivity;
-import org.jbpm.pvm.internal.model.op.TransitionTake;
 import org.jbpm.pvm.internal.util.EqualsUtil;
 import org.jbpm.pvm.internal.util.Priority;
 
@@ -92,15 +83,6 @@
 
   private static final Log log = Log.getLog(Execution.class.getName());
   
-  // atomic operations 
-  public static final AtomicOperation EXECUTE_ACTIVITY = new ExecuteActivity();
-  public static final AtomicOperation TRANSITION_END_ACTIVITY = new TransitionEndActivity();
-  public static final AtomicOperation TRANSITION_TAKE = new TransitionTake();
-  public static final AtomicOperation TRANSITION_START_ACTIVITY = new TransitionStartActivity();
-  public static final AtomicOperation PROPAGATE_TO_PARENT = new MoveToParentActivity();
-
-  // persistent member fields /////////////////////////////////////////////////
-  
   /** an optional name for this execution.  can be used to 
    * differentiate concurrent paths of execution like e.g. 
    * the 'shipping' and 'billing' paths. */
@@ -146,9 +128,6 @@
   /** persistent activity reference */
   protected String activityName;
 
-  protected Integer transitionSourceIndex;
-  protected String transitionSourceName;
-
   // transient cached indicators of the current position //////////////////////
 
   /** transient cached process definition.  persistence is managed in {@link #processDefinitionId} */
@@ -160,12 +139,12 @@
   /** transition is not to be made persistable by default */
   protected TransitionImpl transition;
 
-  /** the activity from which the transition was taken.  This can be different from 
-   * the transition source in case a transition of an eclosing activity was taken. */
-  protected ActivityImpl transitionSource;
-
   protected EventImpl event;
 
+  protected AtomicOperation eventCompletedOperation;
+
+  protected int eventListenerIndex;
+
   protected ObservableElementImpl eventSource;
 
   // cached named executions //////////////////////////////////////////////////
@@ -212,7 +191,7 @@
     fireHistoryEvent(new ProcessInstanceStart());
     fire(Event.START, getProcessDefinition());
     if (getActivity()!=null) {
-      scopedExecution.performAtomicOperation(EXECUTE_ACTIVITY);
+      scopedExecution.performAtomicOperation(AtomicOperation.EXECUTE_ACTIVITY);
     }
   }
 
@@ -400,9 +379,9 @@
     checkActive();
     propagation = Propagation.EXPLICIT;
     if (getActivity()!=null) {
-      performAtomicOperation(new Signal(signal, parameters, getActivity()));
+      performAtomicOperation(new Signal(signal, parameters));
     } else if (transition!=null) {
-      performAtomicOperation(ExecutionImpl.TRANSITION_START_ACTIVITY);
+      performAtomicOperation(AtomicOperation.TRANSITION_START_ACTIVITY);
     } else {
       throw new JbpmException("execution is not in a activity or in a transition");
     }
@@ -452,11 +431,12 @@
     checkActive();
 
     setPropagation(Propagation.EXPLICIT);
-    setTransition((TransitionImpl) transition);
 
-    performAtomicOperation(TRANSITION_END_ACTIVITY);
+    setTransition((TransitionImpl) transition);
+    
+    fire(Event.END, getActivity(), AtomicOperation.TRANSITION_END_ACTIVITY);
   }
-  
+
   public void take(Transition transition, Execution execution) {
     ((ExecutionImpl)execution).take(transition);
   }
@@ -512,7 +492,7 @@
       // if there is a parent activity
       if (parentActivity!=null) {
         // propagate to the parent
-        performAtomicOperation(PROPAGATE_TO_PARENT);
+        performAtomicOperation(AtomicOperation.PROPAGATE_TO_PARENT);
         
       }  else {
         // When we don't know how to proceed, i don't know if it's best to 
@@ -532,13 +512,46 @@
     setActivity((ActivityImpl) activity);
   }
 
+  // events ///////////////////////////////////////////////////////////////////
+  
+  public void fire(String eventName, ObservableElement eventSource) {
+    fire(eventName, (ObservableElementImpl) eventSource, null);
+  }
+
+  public void fire(String eventName, ObservableElementImpl observableElement, AtomicOperation eventCompletedOperation) {
+    EventImpl event = findEvent(observableElement, eventName);
+    if (event!=null) {
+      setEvent(event);
+      setEventSource(observableElement);
+      setEventListenerIndex(0);
+      setEventCompletedOperation(eventCompletedOperation);
+      performAtomicOperation(AtomicOperation.EXECUTE_EVENT_LISTENER);
+    } else {
+      if (eventCompletedOperation!=null) {
+        performAtomicOperationSync(eventCompletedOperation);
+      }
+    }
+  }
+  
+  public static EventImpl findEvent(ObservableElementImpl observableElement, String eventName) {
+    if (observableElement==null) {
+      return null;
+    }
+    
+    EventImpl event = observableElement.getEvent(eventName);
+    if (event!=null) {
+      return event;
+    }
+    
+    return findEvent(observableElement.getParent(), eventName);
+  }
+
   // execution : internal methods /////////////////////////////////////////////
 
   public void moveTo(ActivityImpl destination) {
     // move the execution to the destination
     setActivity(destination);
     transition = null;
-    transitionSource = null;
   }
 
   public ExecutionImpl startActivity(ActivityImpl activity) {
@@ -559,6 +572,8 @@
     return propagatingExecution;
   }
 
+  // asynchronous continuations ////////////////////////////////////////////////  
+
   public synchronized void performAtomicOperation(AtomicOperation operation) {
     if (operation.isAsync(this)) {
       sendContinuationMessage(operation);
@@ -567,8 +582,6 @@
     }
   }
   
-  // asynchronous continuations ////////////////////////////////////////////////  
-
   public void sendContinuationMessage(AtomicOperation operation) {
     Environment environment = Environment.getCurrent();
     MessageSession messageSession = environment.get(MessageSession.class);
@@ -603,52 +616,6 @@
     }
   }
 
-  // events ///////////////////////////////////////////////////////////////////
-
-  /** @see Execution#fire(String, ObservableElement) */
-  public void fire(String eventName, ObservableElement eventSource) {
-    fire(eventName, eventSource, (ObservableElementImpl) eventSource);
-  }
-
-  /** fires the event on the given *processElement* and then propagates the event 
-   * up to the *processElement* parent chain. */
-  void fire(String eventName, ObservableElement eventSource, ObservableElementImpl observableElement) {
-    if (observableElement!=null) {
-      EventImpl event = (EventImpl) observableElement.getEvent(eventName);
-      if (event!=null) {
-        if (log.isTraceEnabled()) {
-          if (observableElement==eventSource) {
-            log.trace("firing "+event+" on "+eventSource);
-          } else {
-            log.trace("firing "+event+" on "+observableElement+", propagated from source "+eventSource);
-          }
-        }
-        fire(event, eventSource, observableElement);
-      }
-      propagateEvent(eventName, eventSource, observableElement);
-    }
-  }
-
-  /** this method enables specific process languages to overwrite the event propagation behaviour */
-  protected void propagateEvent(String eventName, ObservableElement eventSource, ObservableElementImpl observableElement) {
-    fire(eventName, eventSource, observableElement.getParent());
-  }
-
-  /** fires the given event without propagation */
-  public void fire(EventImpl event, ObservableElement eventSource, ObservableElement observableElement) {
-    List<EventListenerReference> eventListenerReferences = event.getListenerReferences();
-    if (eventListenerReferences!=null) {
-      for (EventListenerReference eventListenerReference: eventListenerReferences) {
-        ExecuteEventListener executeEventListenerOperation = new ExecuteEventListener(eventListenerReference, event, (ObservableElementImpl) eventSource, observableElement);
-        if (eventListenerReference.isAsync()) {
-          sendContinuationMessage(executeEventListenerOperation);
-        } else {
-          executeEventListenerOperation.perform(this);
-        }
-      }
-    }
-  }
-
   public void handleException(ObservableElementImpl observableElement,
                               EventImpl event,
                               EventListenerReference eventListenerReference,
@@ -690,23 +657,6 @@
     ExceptionHandlerImpl.rethrow(exception, rethrowMessage+": "+exception.getMessage());
   }
   
-
-  /** searches for an event up the process element parent hierarchy starting 
-   * from the given process element and returns an event or null if no such 
-   * event exists. */ 
-  EventImpl findEvent(String eventName, ObservableElementImpl observableElement) {
-    EventImpl event = null;
-    while ( (event==null)
-            && (observableElement!=null)
-          ) {
-      event = (EventImpl) observableElement.getEvent(eventName);
-      if (event==null) {
-        observableElement = observableElement.getParent();
-      }
-    }
-    return event;
-  }
-
   // comments /////////////////////////////////////////////////////////////////
   
   public Comment createComment(String message) {
@@ -1070,62 +1020,43 @@
     return activityName;
   }
 
-  // transition getter and setter /////////////////////////////////////////////
-  // this getter and setter is special because persistence is based on the   // 
-  // transition index of the current activity.                               //
-  /////////////////////////////////////////////////////////////////////////////
+  // special getters and setters /////////////////////////////////////////////////
 
-  public void setTransition(TransitionImpl transition) {
-    this.transition = transition;
-    if (transition==null) {
-      this.transitionSource = null;
-      this.transitionSourceName = null;
-      this.transitionSourceIndex = null;
-    } else {
-      this.transitionSource = transition.getSource();
-      this.transitionSourceName = transitionSource.getName();
-      this.transitionSourceIndex = transition.getSourceIndex();
+  public boolean hasAsyncEndEvent(List<ActivityImpl> leftActivities) {
+    for (ActivityImpl leftActivity : leftActivities) {
+      EventImpl endEvent = leftActivity.getEvent(Event.END);
+      if ( (endEvent!=null)
+           && (endEvent.isAsync())
+         ) {
+        return true;
+      }
     }
+    return false;
   }
 
-  public TransitionImpl getTransition() {
-    if ( (transition==null)
-         && (transitionSourceIndex!=null)
-       ) {
-      transition = (TransitionImpl) getTransitionSource().getOutgoingTransitions().get(transitionSourceIndex);
+  public List<Comment> getComments() {
+    if (comments==null) {
+      return Collections.emptyList();
     }
-    return transition;
+    return new ArrayList<Comment>(comments);
   }
-  
-  public ActivityImpl getTransitionSource() {
-    if ( (transitionSource==null)
-         && (transitionSourceName!=null)
-       ) {
-      transitionSource = getProcessDefinition().findActivity(transitionSourceName);
-    }
-    return transitionSource;
-  }
 
-  
-
-  // getters and setters /////////////////////////////////////////////////////////
-  
-  
   public boolean isProcessInstance() {
     return parent==null;
   }
 
-  public List<Comment> getComments() {
-    if (comments==null) {
-      return Collections.emptyList();
-    }
-    return new ArrayList<Comment>(comments);
+  // getters and setters /////////////////////////////////////////////////////////
+  
+  public TransitionImpl getTransition() {
+    return transition;
   }
-
-  public Event getEvent() {
+  public void setTransition(TransitionImpl transition) {
+    this.transition = transition;
+  }
+  public EventImpl getEvent() {
     return event;
   }
-  public ObservableElement getEventSource() {
+  public ObservableElementImpl getEventSource() {
     return eventSource;
   }
   public Collection<Execution> getExecutions() {
@@ -1212,16 +1143,16 @@
   public String getProcessDefinitionId() {
     return processDefinitionId;
   }
-
-  public boolean hasAsyncEndEvent(List<ActivityImpl> leftActivities) {
-    for (ActivityImpl leftActivity : leftActivities) {
-      EventImpl endEvent = leftActivity.getEvent(Event.END);
-      if ( (endEvent!=null)
-           && (endEvent.isAsync())
-         ) {
-        return true;
-      }
-    }
-    return false;
+  public int getEventListenerIndex() {
+    return eventListenerIndex;
   }
+  public void setEventListenerIndex(int eventListenerIndex) {
+    this.eventListenerIndex = eventListenerIndex;
+  }
+  public AtomicOperation getEventCompletedOperation() {
+    return eventCompletedOperation;
+  }
+  public void setEventCompletedOperation(AtomicOperation eventCompletedOperation) {
+    this.eventCompletedOperation = eventCompletedOperation;
+  }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -59,6 +59,7 @@
   /** event factory method that also establishes the bidirectional relation. */
   public EventImpl createEvent(String eventName) {
     EventImpl event = new EventImpl();
+    event.setObservableElement(this);
     event.setName(eventName);
     return addEvent(event);
   }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,16 +21,38 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
+import org.jbpm.api.JbpmException;
 import org.jbpm.pvm.internal.job.MessageImpl;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
 
 /**
  * @author Tom Baeyens
  */
-public interface AtomicOperation {
+public abstract class AtomicOperation {
+
+  public static final AtomicOperation EXECUTE_ACTIVITY = new ExecuteActivity();
+  public static final AtomicOperation PROPAGATE_TO_PARENT = new MoveToParentActivity();
+  public static final AtomicOperation TRANSITION_TAKE = new TransitionTake();
+  public static final AtomicOperation TRANSITION_START_ACTIVITY = new TransitionStartActivity();
+  public static final AtomicOperation EXECUTE_EVENT_LISTENER = new ExecuteEventListener();
+  public static final AtomicOperation TRANSITION_END_ACTIVITY = new TransitionEndActivity();
+
+  public abstract boolean isAsync(ExecutionImpl execution);
+  public abstract MessageImpl<?> createAsyncMessage(ExecutionImpl execution);
+  public abstract void perform(ExecutionImpl execution);
   
-  boolean isAsync(ExecutionImpl execution);
-  MessageImpl<?> createAsyncMessage(ExecutionImpl execution);
+  public static AtomicOperation parseAtomicOperation(String text) {
+    if (text==null) {
+      return null;
+    }
 
-  void perform(ExecutionImpl execution);
+    if (TRANSITION_END_ACTIVITY.toString().equals(text)) return TRANSITION_END_ACTIVITY; 
+    if (EXECUTE_EVENT_LISTENER.toString().equals(text)) return EXECUTE_EVENT_LISTENER; 
+    if (EXECUTE_ACTIVITY.toString().equals(text)) return EXECUTE_ACTIVITY; 
+    if (TRANSITION_TAKE.toString().equals(text)) return TRANSITION_TAKE; 
+    if (TRANSITION_START_ACTIVITY.toString().equals(text)) return TRANSITION_START_ACTIVITY; 
+    if (PROPAGATE_TO_PARENT.toString().equals(text)) return PROPAGATE_TO_PARENT;
+
+    throw new JbpmException("invalid atomic operation text: "+text);
+  }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -30,7 +30,7 @@
 import org.jbpm.pvm.internal.model.ExecutionImpl.Propagation;
 import org.jbpm.pvm.internal.util.Clock;
 
-public class ExecuteActivity implements AtomicOperation {
+public class ExecuteActivity extends AtomicOperation {
   
   private static Log log = Log.getLog(ExecuteActivity.class.getName());
   

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -43,7 +43,7 @@
   public Object execute(Environment environment) throws Exception {
     AsyncContinuations.restoreState(execution);
     
-    execution.performAtomicOperationSync(ExecutionImpl.EXECUTE_ACTIVITY);
+    execution.performAtomicOperationSync(AtomicOperation.EXECUTE_ACTIVITY);
 
     JobDbSession jobDbSession = environment.get(JobDbSession.class);
     jobDbSession.delete(this);

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,6 +21,8 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
+import java.util.List;
+
 import org.jbpm.api.listener.EventListener;
 import org.jbpm.api.model.ObservableElement;
 import org.jbpm.internal.log.Log;
@@ -34,54 +36,96 @@
 /**
  * @author Tom Baeyens
  */
-public class ExecuteEventListener implements AtomicOperation {
+public class ExecuteEventListener extends AtomicOperation {
   
   private static Log log = Log.getLog(ExecuteEventListener.class.getName());
   
-  protected EventListenerReference eventListenerReference;
-  protected EventImpl event;
-  protected ObservableElementImpl eventSource;
-  protected ObservableElement observableElement;
+  public boolean isAsync(ExecutionImpl execution) {
+    int eventListenerIndex = execution.getEventListenerIndex();
+    EventImpl event = execution.getEvent();
+    
+    if ( (eventListenerIndex==0)
+         && (event.isAsync())
+       ) {
+      return true;
+    }
+    
+    List<EventListenerReference> eventListenerReferences = event.getListenerReferences();
+    if ( (eventListenerReferences==null)
+         || (eventListenerReferences.isEmpty())
+       ) {
+      return false;
+    }
 
-  public ExecuteEventListener(EventListenerReference eventListenerReference, EventImpl event, ObservableElementImpl eventSource, ObservableElement observableElement) {
-    this.eventListenerReference = eventListenerReference;
-    this.event = event;
-    this.eventSource = eventSource;
-    this.observableElement = observableElement;
-  }
-
-  public boolean isAsync(ExecutionImpl execution) {
+    EventListenerReference eventListenerReference = eventListenerReferences.get(eventListenerIndex);
     return eventListenerReference.isAsync();
   }
 
   public void perform(ExecutionImpl execution) {
-    try {
-      execution.setEvent(event);
-      execution.setEventSource(eventSource);
-
-      if ( (observableElement.equals(eventSource)) // this event is not propagated
-              || (eventListenerReference.isPropagationEnabled()) // propagation is allowed
-            ) {
+    EventImpl event = execution.getEvent();
+    ObservableElementImpl observableElement = event.getObservableElement();
+    int eventListenerIndex = execution.getEventListenerIndex();
+    List<EventListenerReference> eventListenerReferences = event.getListenerReferences();
+    if ( (eventListenerReferences!=null)
+         && (!eventListenerReferences.isEmpty())
+       ) {
+      EventListenerReference eventListenerReference = eventListenerReferences.get(eventListenerIndex);
+      ObservableElement eventSource = execution.getEventSource();
+      if ((eventSource == observableElement) || (eventListenerReference.isPropagationEnabled())) {
         EventListener eventListener = eventListenerReference.get();
-        
-        log.trace("executing "+eventListener+" for "+event);
+        log.trace("executing " + eventListener + " for " + event);
         try {
           // TODO can/should this invocation be unified with the exception handler invocation of the event notification method?
           eventListener.notify(execution);
         } catch (Exception e) {
-          log.trace("exception during action: "+e);
-          execution.handleException((ObservableElementImpl) observableElement, event, eventListenerReference, e, "couldn't run action "+eventListener);
+          log.trace("exception during action: " + e);
+          execution.handleException((ObservableElementImpl) observableElement, event, eventListenerReference, e, "couldn't run action " + eventListener);
         }
       }
-      
-    } finally {
-      execution.setEvent(null);
-      execution.setEventSource(null);
+      // increment the event listener index
+      eventListenerIndex++;
+      execution.setEventListenerIndex(eventListenerIndex);
     }
+    
+    // if there are more listeners in this event
+    if ( (eventListenerReferences!=null)
+         && (eventListenerIndex < eventListenerReferences.size())
+       ) {
+      // execute the next listener
+      execution.performAtomicOperation(AtomicOperation.EXECUTE_EVENT_LISTENER);
+
+    } else {
+      // there are no more listeners in this event
+
+      ObservableElementImpl parent = observableElement.getParent();
+      // find the next event with listeners
+      EventImpl propagatedEvent = ExecutionImpl.findEvent(parent, event.getName());
+
+      // if there is an propagated event with listeners 
+      if (propagatedEvent != null) {
+        // propagate to the that event
+        execution.setEvent(propagatedEvent);
+        execution.setEventListenerIndex(0);
+        execution.performAtomicOperation(AtomicOperation.EXECUTE_EVENT_LISTENER);
+
+      } else {
+        // event is completed, perform the eventCompletedOperation 
+        AtomicOperation eventCompletedOperation = execution.getEventCompletedOperation();
+
+        execution.setEvent(null);
+        execution.setEventSource(null);
+        execution.setEventListenerIndex(0);
+        execution.setEventCompletedOperation(null);
+
+        if (eventCompletedOperation != null) {
+          execution.performAtomicOperation(eventCompletedOperation);
+        }
+      }
+    }
   }
 
   public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
-    return new ExecuteEventListenerMessage(execution, observableElement, event, eventListenerReference);
+    return new ExecuteEventListenerMessage(execution);
   }
 
   public String toString() {

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,79 +21,141 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.jbpm.api.env.Environment;
-import org.jbpm.api.listener.EventListener;
-import org.jbpm.api.model.ObservableElement;
-import org.jbpm.api.session.RepositorySession;
 import org.jbpm.pvm.internal.job.MessageImpl;
+import org.jbpm.pvm.internal.jobexecutor.JobDbSession;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.EventImpl;
-import org.jbpm.pvm.internal.model.EventListenerReference;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
 import org.jbpm.pvm.internal.model.ObservableElementImpl;
 import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
 import org.jbpm.pvm.internal.model.TransitionImpl;
 
-
 /**
  * @author Tom Baeyens
  */
 public class ExecuteEventListenerMessage extends MessageImpl<Object> {
 
+  private static final String KEY_EVENT_COMPLETED_OPERATION = "ECO";
+  private static final String KEY_EVENT_LISTENER_INDEX = "ELI";
+  private static final String KEY_EVENT_NAME = "EN";
+  private static final String KEY_EVENT_OBSERVABLE_PARENT_LEVEL = "EOPL";
+  private static final String KEY_TRANSITION_SOURCE_INDEX = "TSI";
+  private static final String KEY_TRANSITION_SOURCE = "TS";
+  private static final String KEY_EVENT_SOURCE_TRANSITION = "EST";
+  private static final String KEY_EVENT_SOURCE_ACTIVITY = "ESA";
+  private static final String KEY_EVENT_SOURCE_PROCESS_DEFINITION = "ESPD";
+  private static final String KEY_STATE = "S";
+  
   private static final long serialVersionUID = 1L;
 
-  protected String processDefinitionId;
-  protected String activityName;
-  protected Integer transitionIndex;
-  protected String eventName;
-  protected Integer eventListenerIndex;
-  
   public ExecuteEventListenerMessage() {
   }
 
-  public ExecuteEventListenerMessage(ExecutionImpl execution, ObservableElement observableElement, EventImpl event, EventListenerReference eventListenerReference) {
+  public ExecuteEventListenerMessage(ExecutionImpl execution) {
     super(execution);
-    if (observableElement instanceof ProcessDefinitionImpl) {
-      ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl) observableElement;
-      processDefinitionId = processDefinition.getId(); 
-    } else if (observableElement instanceof ActivityImpl) {
-      ActivityImpl activity = (ActivityImpl) observableElement;
-      processDefinitionId = activity.getProcessDefinition().getId();
-      activityName = activity.getName();
-    } else if (observableElement instanceof TransitionImpl) {
-      TransitionImpl transition = (TransitionImpl) observableElement;
-      processDefinitionId = transition.getProcessDefinition().getId();
-      activityName = transition.getSource().getName();
-      transitionIndex = transition.getSource().getOutgoingTransitions().indexOf(transition);
+    
+    Map<String, Object> asyncExecutionInfo = new HashMap<String, Object>();
+    
+    TransitionImpl transition = execution.getTransition();
+    if (transition!=null) {
+      ActivityImpl source = transition.getSource();
+      asyncExecutionInfo.put(KEY_TRANSITION_SOURCE, source.getName());
+      asyncExecutionInfo.put(KEY_TRANSITION_SOURCE_INDEX, source.getOutgoingTransitions().indexOf(transition));
     }
+
+    asyncExecutionInfo.put(KEY_STATE, execution.getState());
+
+    ObservableElementImpl eventSource = (ObservableElementImpl) execution.getEventSource();
+    if (eventSource instanceof ProcessDefinitionImpl) {
+      asyncExecutionInfo.put(KEY_EVENT_SOURCE_PROCESS_DEFINITION, null);
+      
+    } else if (eventSource instanceof ActivityImpl) {
+      asyncExecutionInfo.put(KEY_EVENT_SOURCE_ACTIVITY, eventSource.getName());
+      
+    } else if (eventSource instanceof TransitionImpl) {
+      asyncExecutionInfo.put(KEY_EVENT_SOURCE_TRANSITION, null);
+    }
+
+    EventImpl event = execution.getEvent();
+    asyncExecutionInfo.put(KEY_EVENT_OBSERVABLE_PARENT_LEVEL, getEventObservableParentLevel(eventSource, event.getObservableElement()));
+    asyncExecutionInfo.put(KEY_EVENT_NAME, event.getName());
     
-    eventName = event.getName();
-    eventListenerIndex = event.getListenerReferences().indexOf(eventListenerReference);
+    asyncExecutionInfo.put(KEY_EVENT_LISTENER_INDEX, execution.getEventListenerIndex());
+    
+    AtomicOperation eventCompletedOperation = execution.getEventCompletedOperation();
+    String eventCompletedOperationText = null;
+    if (eventCompletedOperation!=null) {
+      eventCompletedOperationText = eventCompletedOperation.toString();
+    }
+    asyncExecutionInfo.put(KEY_EVENT_COMPLETED_OPERATION, eventCompletedOperationText);
+    
+    setConfiguration(asyncExecutionInfo);
   }
 
+  public Integer getEventObservableParentLevel(ObservableElementImpl eventSource, ObservableElementImpl observableElement) {
+    int parentLevel = 0;
+    while (eventSource!=observableElement) {
+      parentLevel++;
+      eventSource = eventSource.getParent();
+    }
+    return parentLevel;
+  }
+
   public Object execute(Environment environment) throws Exception {
-    ObservableElementImpl observableElement = null;
+    Map<String, Object> asyncExecutionInfo = (Map) getConfiguration();
+
+    String transitionSourceName = (String) asyncExecutionInfo.get(KEY_TRANSITION_SOURCE);
+    TransitionImpl transition = null;
+    if (transitionSourceName!=null) {
+      ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
+      ActivityImpl transitionSource = processDefinition.findActivity(transitionSourceName);
+      Integer transitionIndex = (Integer) asyncExecutionInfo.get(KEY_TRANSITION_SOURCE_INDEX);
+      transition = (TransitionImpl) transitionSource.getOutgoingTransitions().get(transitionIndex);
+      execution.setTransition(transition);
+    }
+
+    if (asyncExecutionInfo.containsKey(KEY_EVENT_SOURCE_PROCESS_DEFINITION)){
+      ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
+      execution.setEventSource(processDefinition);
+
+    } else if (asyncExecutionInfo.containsKey(KEY_EVENT_SOURCE_ACTIVITY)){
+      ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
+      String activityName = (String) asyncExecutionInfo.get(KEY_EVENT_SOURCE_ACTIVITY);
+      ActivityImpl activity = processDefinition.findActivity(activityName);
+      execution.setEventSource(activity);
     
-    RepositorySession repositorySession = environment.get(RepositorySession.class);
-    ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl) repositorySession.findProcessDefinitionById(processDefinitionId);
-    if (activityName!=null) {
-      ActivityImpl activity = processDefinition.findActivity(activityName);
-      if (transitionIndex!=null) {
-        TransitionImpl transition = (TransitionImpl) activity.getOutgoingTransitions().get(transitionIndex);
-        observableElement = transition;
-      } else {
-        observableElement = activity;
-      }
-    } else {
-      observableElement = processDefinition;
+    } else if (asyncExecutionInfo.containsKey(KEY_EVENT_SOURCE_TRANSITION)){
+      execution.setEventSource(transition);
     }
     
+    ObservableElementImpl observableElement = (ObservableElementImpl) execution.getEventSource();
+    int parentLevel = (Integer) asyncExecutionInfo.get(KEY_EVENT_OBSERVABLE_PARENT_LEVEL);
+    for (int i=0; i<parentLevel; parentLevel++) {
+      observableElement = observableElement.getParent();
+    }
+    
+    String eventName = (String) asyncExecutionInfo.get(KEY_EVENT_NAME);
     EventImpl event = observableElement.getEvent(eventName);
-    EventListenerReference eventListenerReference = event.getListenerReferences().get(eventListenerIndex);
-    EventListener eventListener = eventListenerReference.get();
+    execution.setEvent(event);
     
-    eventListener.notify(execution);
+    Integer eventListenerIndex = (Integer) asyncExecutionInfo.get(KEY_EVENT_LISTENER_INDEX);
+    execution.setEventListenerIndex(eventListenerIndex);
+
+    String eventCompletedOperationText = (String) asyncExecutionInfo.get(KEY_EVENT_COMPLETED_OPERATION);
+    AtomicOperation eventCompletedOperation = AtomicOperation.parseAtomicOperation(eventCompletedOperationText);
+    execution.setEventCompletedOperation(eventCompletedOperation);
     
+    execution.setState((String) asyncExecutionInfo.get(KEY_STATE));
+
+    execution.performAtomicOperationSync(AtomicOperation.EXECUTE_EVENT_LISTENER);
+    
+    JobDbSession jobDbSession = environment.get(JobDbSession.class);
+    jobDbSession.delete(this);
+
     return null;
   }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -29,7 +29,7 @@
 /**
  * @author Tom Baeyens
  */
-public class MoveToChildActivity implements AtomicOperation {
+public class MoveToChildActivity extends AtomicOperation {
   
   ActivityImpl activity;
 
@@ -40,7 +40,7 @@
   public void perform(ExecutionImpl execution) {
     execution.setActivity(activity);
     ExecutionImpl propagatingExecution = execution.startActivity(activity);
-    propagatingExecution.performAtomicOperation(ExecutionImpl.EXECUTE_ACTIVITY);
+    propagatingExecution.performAtomicOperation(AtomicOperation.EXECUTE_ACTIVITY);
   }
 
   public boolean isAsync(ExecutionImpl execution) {

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -28,7 +28,7 @@
 /**
  * @author Tom Baeyens
  */
-public class MoveToParentActivity implements AtomicOperation {
+public class MoveToParentActivity extends AtomicOperation {
 
   public void perform(ExecutionImpl execution) {
     ActivityImpl activity = execution.getActivity();
@@ -36,7 +36,7 @@
     ExecutionImpl propagatingExecution = execution.endActivity(activity);
     
     propagatingExecution.setActivity(parentActivity);
-    propagatingExecution.performAtomicOperation(new Signal(null, null, parentActivity));
+    propagatingExecution.performAtomicOperation(new Signal(null, null));
   }
 
   public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
@@ -46,4 +46,8 @@
   public boolean isAsync(ExecutionImpl execution) {
     return false;
   }
+  
+  public String toString() {
+    return "MoveToParentActivity";
+  }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -34,18 +34,16 @@
 /**
  * @author Tom Baeyens
  */
-public class Signal implements AtomicOperation {
+public class Signal extends AtomicOperation {
 
   private static final Log log = Log.getLog(Signal.class.getName());
 
   String signalName;
   Map<String, ?> parameters;
-  ActivityImpl activity;
 
-  public Signal(String signalName, Map<String, ?> parameters, ActivityImpl activity) {
+  public Signal(String signalName, Map<String, ?> parameters) {
     this.signalName = signalName;
     this.parameters = parameters;
-    this.activity = activity;
   }
 
   public boolean isAsync(ExecutionImpl execution) {
@@ -53,6 +51,8 @@
   }
 
   public void perform(ExecutionImpl execution) {
+    ActivityImpl activity = execution.getActivity();
+    
     if (execution.getName()!=null) {
       log.debug(execution.toString()+" signals "+activity);
     } else {
@@ -82,6 +82,6 @@
   }
 
   public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
-    return new SignalMessage(execution, signalName, activity);
+    return null;
   }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,12 +21,14 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
+import java.util.Map;
+
 import org.jbpm.api.Execution;
 import org.jbpm.api.env.Environment;
 import org.jbpm.pvm.internal.job.MessageImpl;
 import org.jbpm.pvm.internal.jobexecutor.JobDbSession;
+import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ActivityImpl;
 
 /**
  * @author Tom Baeyens
@@ -36,21 +38,21 @@
   private static final long serialVersionUID = 1L;
   
   String signalName;
-  ActivityImpl activity;
+  Map<String, ?> parameters;
 
   public SignalMessage() {
   }
 
-  public SignalMessage(ExecutionImpl execution, String signalName, ActivityImpl activity) {
+  public SignalMessage(ExecutionImpl execution, String signalName, Map<String, ?> parameters) {
     super(execution);
     this.signalName = signalName;
-    this.activity = activity;
+    this.parameters = parameters;
   }
 
   public Object execute(Environment environment) throws Exception {
     execution.setState(Execution.STATE_ACTIVE_ROOT);
     
-    Signal signal = new Signal(signalName, null, activity);
+    Signal signal = new Signal(signalName, parameters);
     execution.performAtomicOperationSync(signal);
     
     JobDbSession jobDbSession = environment.get(JobDbSession.class);

Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -1,97 +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.pvm.internal.model.op;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.job.MessageImpl;
-import org.jbpm.pvm.internal.model.ActivityImpl;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ObservableElementImpl;
-import org.jbpm.pvm.internal.model.TransitionImpl;
-
-public class TransitionEndActivity implements AtomicOperation {
-
-  private static final TransitionTake TRANSITION_TAKE = new TransitionTake();
-  
-  private static Log log = Log.getLog(TransitionEndActivity.class.getName());
-
-  public boolean isAsync(ExecutionImpl execution) {
-    TransitionImpl transition = execution.getTransition();
-    List<ActivityImpl> leftActivities = getActivitiesLeft(execution.getActivity(), transition.getDestination());
-    return execution.hasAsyncEndEvent(leftActivities);
-  }
-
-  public void perform(ExecutionImpl execution) {
-    TransitionImpl transition = execution.getTransition();
-
-    if (execution.getName() != null) {
-      log.debug(execution.toString() + " takes " + transition);
-    } else {
-      log.debug("taking " + transition);
-    }
-
-    List<ActivityImpl> leftActivities = getActivitiesLeft(execution.getActivity(), transition.getDestination());
-    ExecutionImpl propagatingExecution = endActivity(execution, leftActivities);
-    
-    propagatingExecution.performAtomicOperation(TRANSITION_TAKE);
-  }
-
-  public static ExecutionImpl endActivity(ExecutionImpl execution, List<ActivityImpl> leftActivities) {
-    ExecutionImpl propagatingExecution = execution;
-    for (ActivityImpl leftActivity : leftActivities) {
-      propagatingExecution = propagatingExecution.endActivity(leftActivity);
-    }
-    propagatingExecution.setActivity(null);
-    return propagatingExecution;
-  }
-
-  List<ActivityImpl> getActivitiesLeft(ActivityImpl source, ActivityImpl destination) {
-    List<ActivityImpl> activitiesLeft = new ArrayList<ActivityImpl>();
-
-    if (source.equals(destination)) {
-      activitiesLeft.add(source);
-    } else {
-      List<ObservableElementImpl> destinationChain = destination.getParentChain();
-
-      if (!destinationChain.contains(source)) {
-        ActivityImpl sourceActivity = source;
-        while ((sourceActivity != null) && (!destinationChain.contains(sourceActivity))) {
-          activitiesLeft.add(sourceActivity);
-          sourceActivity = sourceActivity.getParentActivity();
-        }
-      }
-    }
-
-    return activitiesLeft;
-  }
-
-  public String toString() {
-    return "TakeTransition";
-  }
-
-  public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
-    return new TransitionEndActivityMessage(execution);
-  }
-}
\ No newline at end of file

Copied: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java (from rev 4923, jbpm4/branches/tbaeyens/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java)
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -0,0 +1,67 @@
+/*
+ * 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.pvm.internal.model.op;
+
+import org.jbpm.api.model.Event;
+import org.jbpm.pvm.internal.job.MessageImpl;
+import org.jbpm.pvm.internal.model.ActivityImpl;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.ObservableElementImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class TransitionEndActivity extends AtomicOperation {
+
+  public boolean isAsync(ExecutionImpl execution) {
+    return false;
+  }
+
+  public void perform(ExecutionImpl execution) {
+    ActivityImpl activity = execution.getActivity();
+    
+    ExecutionImpl propagatingExecution = execution;
+    if (activity.isLocalScope()) {
+      propagatingExecution = execution.destroyScope(activity);
+    }
+
+    ActivityImpl parentActivity = activity.getParentActivity();
+    ActivityImpl destination = execution.getTransition().getDestination();
+    if ( (parentActivity!=null)
+         && (!parentActivity.contains(destination))
+       ) {
+      propagatingExecution.setActivity(parentActivity);
+      propagatingExecution.fire(Event.END, parentActivity, AtomicOperation.TRANSITION_END_ACTIVITY);
+    } else {
+      propagatingExecution.performAtomicOperation(AtomicOperation.TRANSITION_TAKE);
+    }
+  }
+
+  public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
+    throw new UnsupportedOperationException("please implement me");
+  }
+
+  public String toString() {
+    return "TransitionEndActivity";
+  }
+}

Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivityMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivityMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivityMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -1,58 +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.pvm.internal.model.op;
-
-import org.jbpm.api.Execution;
-import org.jbpm.api.env.Environment;
-import org.jbpm.pvm.internal.job.MessageImpl;
-import org.jbpm.pvm.internal.jobexecutor.JobDbSession;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-
-/**
- * @author Tom Baeyens
- */
-public class TransitionEndActivityMessage extends MessageImpl<Object> {
-
-  private static final long serialVersionUID = 1L;
-
-  public TransitionEndActivityMessage() {
-  }
-
-  public TransitionEndActivityMessage(ExecutionImpl execution) {
-    super(execution);
-  }
-
-  public Object execute(Environment environment) throws Exception {
-    AsyncContinuations.restoreState(execution);
-
-    execution.performAtomicOperationSync(ExecutionImpl.TRANSITION_END_ACTIVITY);
-    
-    JobDbSession jobDbSession = environment.get(JobDbSession.class);
-    jobDbSession.delete(this);
-
-    return null;
-  }
-
-  public String toString() {
-    return "TakeTransitionMessage["+dbid+"]";
-  }
-}

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,68 +21,74 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
-import java.util.LinkedList;
-import java.util.List;
-
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.model.Event;
 import org.jbpm.pvm.internal.job.MessageImpl;
+import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ActivityImpl;
-import org.jbpm.pvm.internal.model.ObservableElementImpl;
+import org.jbpm.pvm.internal.model.TransitionImpl;
 
 /**
  * @author Tom Baeyens
  */
-public class TransitionStartActivity implements AtomicOperation {
+public class TransitionStartActivity extends AtomicOperation {
   
   public boolean isAsync(ExecutionImpl execution) {
     return false;
   }
 
   public void perform(ExecutionImpl execution) {
-    ActivityImpl destination = execution.getTransition().getDestination();
-    execution.setActivity(destination);
-    List<ActivityImpl> enteredActivities = getActivitiesEntered(execution.getTransitionSource(), destination);
+    TransitionImpl transition = execution.getTransition();
+    ActivityImpl source = transition.getSource();
+    ActivityImpl destination = transition.getDestination();
     
-    ExecutionImpl propagatingExecution = execution;
-    for (ActivityImpl enteredActivity : enteredActivities) {
-      propagatingExecution = propagatingExecution.startActivity(enteredActivity);
-    }
-    
-    propagatingExecution.setActivity(destination);
-    propagatingExecution.setTransition(null);
-    
-    propagatingExecution.performAtomicOperation(ExecutionImpl.EXECUTE_ACTIVITY);
-  }
-  
-  public List<ActivityImpl> getActivitiesEntered(ActivityImpl origin, ActivityImpl destination) {
-    LinkedList<ActivityImpl> activitiesEntered = new LinkedList<ActivityImpl>();
-    
-    if (origin.equals(destination)) {
-      activitiesEntered.add(destination);
+    ActivityImpl activity = execution.getActivity();
+    if (activity==null) {
+      // find outer most activity to start
+      activity = destination;
+      while ( (activity.getParentActivity()!=null)
+              && (!activity.getParentActivity().contains(source))
+            ) {
+        activity = activity.getParentActivity();
+      }
       
+    } else if (activity==destination){
+      activity = null;
+
     } else {
-      List<ObservableElementImpl> sourceChain = origin.getParentChain();
-      
-      if (!sourceChain.contains(destination)) {
-        ActivityImpl destinationActivity = destination;
-        while ( (destinationActivity!=null)
-                && (!sourceChain.contains(destinationActivity))
-              ) {
-          activitiesEntered.addFirst(destinationActivity);
-          destinationActivity = destinationActivity.getParentActivity(); 
-        }
+      ActivityImpl parent = activity;
+      activity = destination;
+      while ( (activity!=null)
+              && (activity.getParent()!=parent) 
+            ) {
+        activity = activity.getParentActivity();
       }
+      if (activity==null) {
+        throw new JbpmException("implementation bug: couldn't find parent "+parent+" around destination "+destination);
+      }
     }
 
-    return activitiesEntered;
+    if (activity==null) {
+      execution.setTransition(null);
+      execution.performAtomicOperation(AtomicOperation.EXECUTE_ACTIVITY);
+   
+    } else {
+      execution.setActivity(activity);
+
+      ExecutionImpl propagatingExecution = execution;
+      if (activity.isLocalScope()) {
+        propagatingExecution = execution.createScope(activity);
+      }
+
+      propagatingExecution.fire(Event.START, activity, AtomicOperation.TRANSITION_START_ACTIVITY);
+    }
   }
-
   
-  public String toString() {
-    return "ProceedToDestination";
+  public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+    throw new UnsupportedOperationException("please implement me");
   }
 
-  public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
-    return new TransitionStartActivityMessage(execution);
+  public String toString() {
+    return "TransitionStartActivity";
   }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -21,7 +21,6 @@
  */
 package org.jbpm.pvm.internal.model.op;
 
-import org.jbpm.api.Execution;
 import org.jbpm.api.env.Environment;
 import org.jbpm.pvm.internal.job.MessageImpl;
 import org.jbpm.pvm.internal.jobexecutor.JobDbSession;
@@ -44,7 +43,7 @@
   public Object execute(Environment environment) throws Exception {
     AsyncContinuations.restoreState(execution);
 
-    execution.performAtomicOperationSync(ExecutionImpl.TRANSITION_START_ACTIVITY);
+    execution.performAtomicOperationSync(AtomicOperation.TRANSITION_START_ACTIVITY);
     
     JobDbSession jobDbSession = environment.get(JobDbSession.class);
     jobDbSession.delete(this);

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -23,7 +23,6 @@
 
 import org.jbpm.api.model.Event;
 import org.jbpm.pvm.internal.job.MessageImpl;
-import org.jbpm.pvm.internal.model.EventImpl;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
 import org.jbpm.pvm.internal.model.TransitionImpl;
 
@@ -31,21 +30,23 @@
 /**
  * @author Tom Baeyens
  */
-public class TransitionTake implements AtomicOperation {
+public class TransitionTake extends AtomicOperation {
 
   public boolean isAsync(ExecutionImpl execution) {
-    TransitionImpl transition = execution.getTransition();
-    EventImpl event = transition.getEvent(Event.TAKE);
-    return ((event!=null) && (event.isAsync()));
+    return false;
   }
 
   public void perform(ExecutionImpl execution) {
     TransitionImpl transition = execution.getTransition();
-    execution.fire(Event.TAKE, transition);
-    execution.performAtomicOperation(ExecutionImpl.TRANSITION_START_ACTIVITY);
+    execution.setActivity(null);
+    execution.fire(Event.TAKE, transition, AtomicOperation.TRANSITION_START_ACTIVITY);
   }
 
   public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
-    return new TransitionTakeMessage(execution);
+    return null;
   }
+
+  public String toString() {
+    return "TransitionTake";
+  }
 }

Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTakeMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTakeMessage.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTakeMessage.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -1,59 +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.pvm.internal.model.op;
-
-import org.jbpm.api.Execution;
-import org.jbpm.api.env.Environment;
-import org.jbpm.pvm.internal.job.MessageImpl;
-import org.jbpm.pvm.internal.jobexecutor.JobDbSession;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-
-
-/**
- * @author Tom Baeyens
- */
-public class TransitionTakeMessage extends MessageImpl<Object> {
-
-  private static final long serialVersionUID = 1L;
-
-  public TransitionTakeMessage() {
-  }
-
-  public TransitionTakeMessage(ExecutionImpl execution) {
-    super(execution);
-  }
-
-  public Object execute(Environment environment) throws Exception {
-    AsyncContinuations.restoreState(execution);
-
-    execution.performAtomicOperationSync(ExecutionImpl.TRANSITION_TAKE);
-    
-    JobDbSession jobDbSession = environment.get(JobDbSession.class);
-    jobDbSession.delete(this);
-
-    return null;
-  }
-
-  public String toString() {
-    return "TransitionTakeMessage["+dbid+"]";
-  }
-}

Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml	2009-05-28 07:17:22 UTC (rev 4924)
@@ -30,8 +30,6 @@
     
     <property name="activityName" column="ACTIVITYNAME_" />
     <property name="processDefinitionId" column="PROCDEFID_" />
-    <property name="transitionSourceName" column="TRANSRC_" />
-    <property name="transitionSourceIndex" column="TRANSRCIDX_" />
 
     <property name="hasVariables" column="HASVARS_" />
     <map name="variables"
@@ -206,7 +204,6 @@
     <property name="isExclusive" column="ISEXCLUSIVE_" />
     <property name="lockOwner" column="LOCKOWNER_" />
     <property name="lockExpirationTime" column="LOCKEXPTIME_" index="IDX_JOBLOCKEXP" />
-    <property name="info" column="INFO_" />
     <property name="exception" column="EXCEPTION_" type="text" />
     <property name="retries" column="RETRIES_" index="IDX_JOBRETRIES" />
     
@@ -233,19 +230,7 @@
 
     <subclass name="org.jbpm.pvm.internal.job.MessageImpl" discriminator-value="Msg">
       <subclass name="org.jbpm.pvm.internal.model.op.ExecuteActivityMessage" discriminator-value="ExeAct" />
-      <subclass name="org.jbpm.pvm.internal.model.op.SignalMessage" discriminator-value="Signal">
-        <property name="signalName" column="SIGNAL_" />
-      </subclass>
-      <subclass name="org.jbpm.pvm.internal.model.op.TransitionEndActivityMessage" discriminator-value="TrEndAct" />
-      <subclass name="org.jbpm.pvm.internal.model.op.TransitionTakeMessage" discriminator-value="TrTake" />
-      <subclass name="org.jbpm.pvm.internal.model.op.TransitionStartActivityMessage" discriminator-value="TrStartAct" />
-      <subclass name="org.jbpm.pvm.internal.model.op.ExecuteEventListenerMessage" discriminator-value="ExeEvtLst">
-        <property name="processDefinitionId" column="PROCDEF_" />
-        <property name="activityName" column="ACT_" />
-        <property name="transitionIndex" column="TRIDX_" />
-        <property name="eventName" column="EVENT_" />
-        <property name="eventListenerIndex" column="EVTLSTIDX_" />
-      </subclass>
+      <subclass name="org.jbpm.pvm.internal.model.op.ExecuteEventListenerMessage" discriminator-value="ExeEvtLsnr" />
       <subclass name="org.jbpm.pvm.internal.job.CommandMessage" discriminator-value="Cmd" />
     </subclass>
     

Modified: jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/EventTest.java
===================================================================
--- jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/EventTest.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/EventTest.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -231,44 +231,4 @@
       execution.end();
     }
   }
-
-  public static class RecordingProcessDefinition extends ProcessDefinitionImpl {
-    private static final long serialVersionUID = 1L;
-    protected ExecutionImpl newProcessInstance() {
-      return new RecordingExecution();
-    }
-  }
-  
-  public static class RecordingExecution extends ExecutionImpl {
-    private static final long serialVersionUID = 1L;
-    List<String> events = new ArrayList<String>();
-    public void fire(String eventName, ObservableElement eventSource) {
-      events.add(eventName+" on "+eventSource);
-    }
-  }
-  
-  public void testBasicEventSequence() {
-    ClientProcessDefinition processDefinition = ProcessDefinitionBuilder
-    .startProcess("basic", new RecordingProcessDefinition())
-      .startActivity("initial", new AutomaticActivity())
-        .initial()
-        .transition("end")
-      .endActivity()
-      .startActivity("end", new EndState())
-      .endActivity()
-    .endProcess();
-
-    RecordingExecution execution = (RecordingExecution) processDefinition.startProcessInstance();
-
-    int index = 0;
-    assertEquals("start on process(basic)", execution.events.get(index));
-    index++;
-    assertEquals("end on activity(initial)", execution.events.get(index));
-    index++;
-    assertEquals("take on (initial)-->(end)", execution.events.get(index));
-    index++;
-    assertEquals("start on activity(end)", execution.events.get(index));
-    index++;
-    assertEquals("end on process(basic)", execution.events.get(index));
-  }
 }

Modified: jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/TransitionEventsTest.java
===================================================================
--- jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/TransitionEventsTest.java	2009-05-27 21:43:23 UTC (rev 4923)
+++ jbpm4/trunk/modules/test-pojo/src/main/java/org/jbpm/test/activities/TransitionEventsTest.java	2009-05-28 07:17:22 UTC (rev 4924)
@@ -45,7 +45,48 @@
     }
   }
 
+  public void testBasicEvents(){
+    Recorder fromListener = new Recorder();
+    Recorder toListener = new Recorder();
+    Recorder transitionListener = new Recorder();
 
+    /*
+    +------+        +----+    
+    | from |------->| to |
+    +------+        +----+    
+    */
+    
+    ClientProcessDefinition processDefinition = ProcessDefinitionBuilder
+    .startProcess("p")
+      .startActivity("from", new WaitState())
+        .initial()
+        .startEvent(Event.END) 
+          .listener(fromListener)
+        .endEvent()
+        .startFlow("to")
+          .listener(transitionListener)
+        .endFlow()
+      .endActivity()
+      .startActivity("to", new WaitState())
+        .startEvent(Event.START) 
+          .listener(toListener)
+        .endEvent()
+      .endActivity()
+    .endProcess();
+
+    ClientExecution execution = processDefinition.startProcessInstance();
+    execution.signal();
+
+    assertEquals("[event(end) on activity(from)]", 
+            fromListener.events.toString());
+
+    assertEquals("[event(take) on (from)-->(to)]", 
+            transitionListener.events.toString());
+
+    assertEquals("[event(start) on activity(to)]", 
+            toListener.events.toString());
+  }
+
   public void testCompositeLeave(){
     Recorder processListener = new Recorder();
     Recorder outsideListener = new Recorder();




More information about the jbpm-commits mailing list