[jbpm-commits] JBoss JBPM SVN: r3190 - in jbpm3/branches/tdiesler/modules: core/src/main/java/org/jbpm/db and 11 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Dec 4 02:28:49 EST 2008


Author: thomas.diesler at jboss.com
Date: 2008-12-04 02:28:48 -0500 (Thu, 04 Dec 2008)
New Revision: 3190

Added:
   jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/
   jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/TaskTest.java
Modified:
   jbpm3/branches/tdiesler/modules/core/pom.xml
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/db/GraphSession.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/def/Node.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Decision.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/EndState.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Fork.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Join.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/StartState.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/State.java
   jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/TaskNode.java
   jbpm3/branches/tdiesler/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/EndEventImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ExclusiveGatewayImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ParallelGatewayImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessDefinitionImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/StartEventImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/UserTaskImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/WaitStateImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/builder/ProcessBuilderImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/runtime/TokenImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/ProcessDefinitionServiceImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/TaskServiceImpl.java
   jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/deployment/DeploymentPARTest.java
Log:
WIP

Modified: jbpm3/branches/tdiesler/modules/core/pom.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/core/pom.xml	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/pom.xml	2008-12-04 07:28:48 UTC (rev 3190)
@@ -119,6 +119,11 @@
       <artifactId>hsqldb</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <!-- Plugins -->

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/db/GraphSession.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/db/GraphSession.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/db/GraphSession.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -467,6 +467,7 @@
   {
     if (processInstance == null)
       throw new JbpmException("processInstance is null in JbpmSession.deleteProcessInstance()");
+    
     log.debug("deleting process instance " + processInstance.getId());
 
     try

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/def/Node.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/def/Node.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/def/Node.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -46,8 +46,9 @@
 
 public class Node extends GraphElement implements Parsable
 {
-
   private static final long serialVersionUID = 1L;
+  
+  public enum NodeType { Node, StartState, EndState, State, Task, Fork, Join, Decission };
 
   protected List<Transition> leavingTransitions = null;
   transient Map leavingTransitionMap = null;
@@ -57,10 +58,20 @@
   protected boolean isAsync = false;
   protected boolean isAsyncExclusive = false;
 
+  
+  public NodeType getNodeType()
+  {
+    return NodeType.Node;
+  }
+  
   // event types //////////////////////////////////////////////////////////////
 
-  public static final String[] supportedEventTypes = new String[] { Event.EVENTTYPE_NODE_ENTER, Event.EVENTTYPE_NODE_LEAVE, Event.EVENTTYPE_BEFORE_SIGNAL,
-      Event.EVENTTYPE_AFTER_SIGNAL };
+  public static final String[] supportedEventTypes = new String[] { 
+    Event.EVENTTYPE_NODE_ENTER, 
+    Event.EVENTTYPE_NODE_LEAVE, 
+    Event.EVENTTYPE_BEFORE_SIGNAL,
+    Event.EVENTTYPE_AFTER_SIGNAL 
+  };
 
   public String[] getSupportedEventTypes()
   {

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -163,7 +163,11 @@
     }
 
     Node initialNode = rootToken.getNode();
-    // fire the process start event
+    fireStartEvent(initialNode);
+  }
+
+  public void fireStartEvent(Node initialNode)
+  {
     if (initialNode != null)
     {
       ExecutionContext executionContext = new ExecutionContext(rootToken);

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Decision.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Decision.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Decision.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -36,13 +36,13 @@
 import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
 import org.jbpm.jpdl.xml.JpdlXmlReader;
 import org.jbpm.jpdl.xml.Parsable;
-import org.jbpm.util.ClassLoaderUtil;
 
 /**
  * decision node.
  */
-public class Decision extends Node implements Parsable {
-  
+public class Decision extends Node implements Parsable
+{
+
   static final String NEWLINE = System.getProperty("line.separator");
   static final String DECISION_CONDITION_RESULT = "decision_condition_result";
   static final long serialVersionUID = 1L;
@@ -51,82 +51,113 @@
   Delegation decisionDelegation = null;
   String decisionExpression = null;
 
-  public Decision() {
+  public Decision()
+  {
   }
 
-  public Decision(String name) {
+  public Decision(String name)
+  {
     super(name);
   }
 
-  public void read(Element decisionElement, JpdlXmlReader jpdlReader) {
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.Decission;
+  }
 
+  public void read(Element decisionElement, JpdlXmlReader jpdlReader)
+  {
+
     String expression = decisionElement.attributeValue("expression");
     Element decisionHandlerElement = decisionElement.element("handler");
 
-    if (expression!=null) {
+    if (expression != null)
+    {
       decisionExpression = expression;
 
-    } else if (decisionHandlerElement!=null) {
+    }
+    else if (decisionHandlerElement != null)
+    {
       decisionDelegation = new Delegation();
       decisionDelegation.read(decisionHandlerElement, jpdlReader);
     }
   }
 
-  public void execute(ExecutionContext executionContext) {
+  public void execute(ExecutionContext executionContext)
+  {
     Transition transition = null;
     ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
-    try {
-      // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448) 
+    try
+    {
+      // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
       Thread.currentThread().setContextClassLoader(JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition()));
 
-      try {
-        if (decisionDelegation != null) {
+      try
+      {
+        if (decisionDelegation != null)
+        {
           DecisionHandler decisionHandler = (DecisionHandler)decisionDelegation.getInstance();
           if (decisionHandler == null)
-            decisionHandler = (DecisionHandler) decisionDelegation.instantiate();
-          
+            decisionHandler = (DecisionHandler)decisionDelegation.instantiate();
+
           String transitionName = decisionHandler.decide(executionContext);
           transition = getLeavingTransition(transitionName);
-          if (transition == null) {
+          if (transition == null)
+          {
             throw new JbpmException("decision '" + name + "' selected non existing transition '" + transitionName + "'");
           }
 
-        } else if (decisionExpression != null) {
+        }
+        else if (decisionExpression != null)
+        {
           Object result = JbpmExpressionEvaluator.evaluate(decisionExpression, executionContext);
-          if (result == null) {
+          if (result == null)
+          {
             throw new JbpmException("decision expression '" + decisionExpression + "' returned null");
           }
           String transitionName = result.toString();
           transition = getLeavingTransition(transitionName);
-          if (transition == null) {
+          if (transition == null)
+          {
             throw new JbpmException("decision '" + name + "' selected non existing transition '" + transitionName + "'");
           }
 
-        } else if (decisionConditions != null && !decisionConditions.isEmpty()) {
+        }
+        else if (decisionConditions != null && !decisionConditions.isEmpty())
+        {
           // backwards compatible mode based on separate DecisionCondition's
           Iterator iter = decisionConditions.iterator();
-          while (iter.hasNext() && (transition == null)) {
-            DecisionCondition decisionCondition = (DecisionCondition) iter.next();
+          while (iter.hasNext() && (transition == null))
+          {
+            DecisionCondition decisionCondition = (DecisionCondition)iter.next();
             Object result = JbpmExpressionEvaluator.evaluate(decisionCondition.getExpression(), executionContext);
-            if (Boolean.TRUE.equals(result)) {
+            if (Boolean.TRUE.equals(result))
+            {
               String transitionName = decisionCondition.getTransitionName();
               transition = getLeavingTransition(transitionName);
-              if (transition != null) {
+              if (transition != null)
+              {
                 transition.removeConditionEnforcement();
               }
             }
           }
 
-        } else {
+        }
+        else
+        {
           // new mode based on conditions in the transition itself
           Iterator iter = leavingTransitions.iterator();
-          while (iter.hasNext() && (transition == null)) {
-            Transition candidate = (Transition) iter.next();
+          while (iter.hasNext() && (transition == null))
+          {
+            Transition candidate = (Transition)iter.next();
 
             String conditionExpression = candidate.getCondition();
-            if (conditionExpression != null) {
+            if (conditionExpression != null)
+            {
               Object result = JbpmExpressionEvaluator.evaluate(conditionExpression, executionContext);
-              if (Boolean.TRUE.equals(result)) {
+              if (Boolean.TRUE.equals(result))
+              {
                 transition = candidate;
               }
             }
@@ -134,7 +165,8 @@
 
         }
 
-        if (transition == null) {
+        if (transition == null)
+        {
           transition = getDefaultLeavingTransition();
           log.debug("decision didn't select transition, taking default " + transition);
         }
@@ -147,25 +179,30 @@
         // node.
         transition.removeConditionEnforcement();
 
-      } catch (Exception exception) {
+      }
+      catch (Exception exception)
+      {
         raiseException(exception, executionContext);
       }
 
     }
-    finally {
+    finally
+    {
       Thread.currentThread().setContextClassLoader(surroundingClassLoader);
-    }     
-    log.debug("decision "+name+" is taking '"+transition+"'");
+    }
+    log.debug("decision " + name + " is taking '" + transition + "'");
     executionContext.leaveNode(transition);
   }
 
-  public List getDecisionConditions() {
+  public List getDecisionConditions()
+  {
     return decisionConditions;
   }
-  
-  public void setDecisionDelegation(Delegation decisionDelegation) {
+
+  public void setDecisionDelegation(Delegation decisionDelegation)
+  {
     this.decisionDelegation = decisionDelegation;
   }
-  
+
   private static Log log = LogFactory.getLog(Decision.class);
 }

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/EndState.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/EndState.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/EndState.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -25,42 +25,56 @@
 import org.jbpm.graph.def.Event;
 import org.jbpm.graph.def.Node;
 import org.jbpm.graph.def.Transition;
-import org.jbpm.graph.exe.*;
+import org.jbpm.graph.exe.ExecutionContext;
 import org.jbpm.jpdl.xml.JpdlXmlReader;
 
-public class EndState extends Node {
+public class EndState extends Node
+{
+  public static final String[] supportedEventTypes = new String[] { Event.EVENTTYPE_NODE_ENTER };
 
   private static final long serialVersionUID = 1L;
-  
+
   String endCompleteProcess = null;
 
-  public EndState() {
+  public EndState()
+  {
   }
+
+  public EndState(String name)
+  {
+    super(name);
+  }
   
-  public static final String[] supportedEventTypes = new String[]{Event.EVENTTYPE_NODE_ENTER};
-  public String[] getSupportedEventTypes() {
+  public String[] getSupportedEventTypes()
+  {
     return supportedEventTypes;
   }
 
-  public EndState(String name) {
-    super(name);
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.EndState;
   }
-  
-  public void read(Element nodeElement, JpdlXmlReader jpdlXmlReader) {
+
+  public void read(Element nodeElement, JpdlXmlReader jpdlXmlReader)
+  {
     endCompleteProcess = nodeElement.attributeValue("end-complete-process");
   }
 
-  public void execute(ExecutionContext executionContext) {
-    if ( (endCompleteProcess!=null)
-         && (endCompleteProcess.equalsIgnoreCase("true"))
-       ) {
+  public void execute(ExecutionContext executionContext)
+  {
+    if ((endCompleteProcess != null) && (endCompleteProcess.equalsIgnoreCase("true")))
+    {
       executionContext.getProcessInstance().end();
-    } else {
+    }
+    else
+    {
       executionContext.getToken().end();
     }
   }
-  
-  public Transition addLeavingTransition(Transition t) {
+
+  public Transition addLeavingTransition(Transition t)
+  {
     throw new UnsupportedOperationException("can't add a leaving transition to an end-state");
   }
 }

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Fork.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Fork.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Fork.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -33,6 +33,7 @@
 import org.jbpm.JbpmException;
 import org.jbpm.graph.action.Script;
 import org.jbpm.graph.def.Node;
+import org.jbpm.graph.def.Node.NodeType;
 import org.jbpm.graph.exe.ExecutionContext;
 import org.jbpm.graph.exe.Token;
 import org.jbpm.jpdl.xml.JpdlXmlReader;
@@ -41,26 +42,23 @@
 /**
  * specifies configurable fork behaviour.
  * 
- * <p>if this fork behaviour is not sufficient for your needs, consider 
- * writing your own custom TokenHandler.
+ * <p>
+ * if this fork behaviour is not sufficient for your needs, consider writing your own custom TokenHandler.
  * </p>
  * 
- * <p>this forkhandler can be configured in 3 ways :
+ * <p>
+ * this forkhandler can be configured in 3 ways :
  * <ul>
- *   <li>without configuration : in that case the fork will launch one 
- *       new sub-token over each of the leaving tranisions of the fork 
- *       node.
- *   </li>
- *   <li>a script : can be used to calculate a collection of transition 
- *       names at runtime.  if a script is configured, the script must have 
- *       exactly one variable with 'write' access.  that variable 
- *       should be assigned a java.util.Collection in the script 
- *       expression.
- *   </li>
+ * <li>without configuration : in that case the fork will launch one new sub-token over each of the leaving tranisions
+ * of the fork node.</li>
+ * <li>a script : can be used to calculate a collection of transition names at runtime. if a script is configured, the
+ * script must have exactly one variable with 'write' access. that variable should be assigned a java.util.Collection in
+ * the script expression.</li>
  * </ul>
  * </p>
  */
-public class Fork extends Node implements Parsable {
+public class Fork extends Node implements Parsable
+{
 
   private static final long serialVersionUID = 1L;
 
@@ -69,127 +67,169 @@
    */
   Script script = null;
 
-  public Fork() {
+  public Fork()
+  {
   }
 
-  public Fork(String name) {
+  public Fork(String name)
+  {
     super(name);
   }
 
-  public void read(Element forkElement, JpdlXmlReader jpdlReader) {
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.Fork;
+  }
+
+  public void read(Element forkElement, JpdlXmlReader jpdlReader)
+  {
     Element scriptElement = forkElement.element("script");
-    if (scriptElement!=null) {
+    if (scriptElement != null)
+    {
       log.warn("KNOWN LIMITATION: the script in a fork is not persisted.  script in fork might be removed in later versions of jPDL");
       script = new Script();
       script.read(scriptElement, jpdlReader);
     }
   }
 
-  public void execute(ExecutionContext executionContext) {
+  public void execute(ExecutionContext executionContext)
+  {
     Token token = executionContext.getToken();
-    
+
     // phase one: collect all the transitionNames
-    Collection transitionNames = null; 
+    Collection transitionNames = null;
     List forkedTokens = new ArrayList();
 
     // by default, the fork spawns a token for each leaving transition
-    if (script==null) {
+    if (script == null)
+    {
       transitionNames = getLeavingTransitionsMap().keySet();
 
-    } else { // a script is specified  
-      // if a script is specified, use that script to calculate the set 
+    }
+    else
+    { // a script is specified
+      // if a script is specified, use that script to calculate the set
       // of leaving transitions to be used for forking tokens.
       Map outputMap = null;
-      try {
+      try
+      {
         outputMap = script.eval(token);
-      } catch (Exception e) {
+      }
+      catch (Exception e)
+      {
         this.raiseException(e, executionContext);
       }
-      if (outputMap.size()==1) {
+      if (outputMap.size() == 1)
+      {
         Object result = outputMap.values().iterator().next();
-        if (result instanceof Collection) {
-          transitionNames = (Collection) result;
+        if (result instanceof Collection)
+        {
+          transitionNames = (Collection)result;
         }
       }
-      if (transitionNames==null) {
-        throw new JbpmException("script for fork '"+name+"' should produce one collection (in one writable variable): "+transitionNames);
+      if (transitionNames == null)
+      {
+        throw new JbpmException("script for fork '" + name + "' should produce one collection (in one writable variable): " + transitionNames);
       }
     }
-    
-    // TODO add some way of blocking the current token here and disable that blocking when the join reactivates this token
+
+    // TODO add some way of blocking the current token here and disable that blocking when the join reactivates this
+    // token
     // Then an exception can be thrown by in case someone tries to signal a token that is waiting in a fork.
-    // Suspend and resume can NOT be used for this since that will also suspend any related timers, tasks and messages...
-    // So a separate kind of blocking should be created for this. 
+    // Suspend and resume can NOT be used for this since that will also suspend any related timers, tasks and
+    // messages...
+    // So a separate kind of blocking should be created for this.
     // @see also http://jira.jboss.com/jira/browse/JBPM-642
 
     // phase two: create forked tokens for the collected transition names
     Iterator iter = transitionNames.iterator();
-    while (iter.hasNext()) {
-      String transitionName = (String) iter.next();
+    while (iter.hasNext())
+    {
+      String transitionName = (String)iter.next();
       forkedTokens.add(createForkedToken(token, transitionName));
     }
 
     // phase three: launch child tokens from the fork over the given transitions
     iter = forkedTokens.iterator();
-    while( iter.hasNext() ) {
-      ForkedToken forkedToken = (ForkedToken) iter.next();
+    while (iter.hasNext())
+    {
+      ForkedToken forkedToken = (ForkedToken)iter.next();
       Token childToken = forkedToken.token;
       String leavingTransitionName = forkedToken.leavingTransitionName;
       ExecutionContext childExecutionContext = new ExecutionContext(childToken);
-      if (leavingTransitionName!=null) {
+      if (leavingTransitionName != null)
+      {
         leave(childExecutionContext, leavingTransitionName);
-      } else {
+      }
+      else
+      {
         leave(childExecutionContext);
       }
     }
   }
 
-  protected ForkedToken createForkedToken(Token parent, String transitionName) {
+  protected ForkedToken createForkedToken(Token parent, String transitionName)
+  {
     // instantiate the new token
     Token childToken = new Token(parent, getTokenName(parent, transitionName));
 
     // create a forked token
     ForkedToken forkedToken = null;
     forkedToken = new ForkedToken(childToken, transitionName);
-    
+
     return forkedToken;
   }
 
-  protected String getTokenName(Token parent, String transitionName) {
+  protected String getTokenName(Token parent, String transitionName)
+  {
     String tokenName = null;
-    if ( transitionName != null ) {
-      if ( ! parent.hasChild( transitionName ) ) {
+    if (transitionName != null)
+    {
+      if (!parent.hasChild(transitionName))
+      {
         tokenName = transitionName;
-      } else {
+      }
+      else
+      {
         int i = 2;
-        tokenName = transitionName + Integer.toString( i );
-        while ( parent.hasChild( tokenName ) ) {
+        tokenName = transitionName + Integer.toString(i);
+        while (parent.hasChild(tokenName))
+        {
           i++;
-          tokenName = transitionName + Integer.toString( i );
+          tokenName = transitionName + Integer.toString(i);
         }
       }
-    } else { // no transition name
-      int size = ( parent.getChildren()!=null ? parent.getChildren().size()+1 : 1 );
+    }
+    else
+    { // no transition name
+      int size = (parent.getChildren() != null ? parent.getChildren().size() + 1 : 1);
       tokenName = Integer.toString(size);
     }
     return tokenName;
   }
 
-  public Script getScript() {
+  public Script getScript()
+  {
     return script;
   }
-  public void setScript(Script script) {
+
+  public void setScript(Script script)
+  {
     this.script = script;
   }
-  
-  static class ForkedToken {
+
+  static class ForkedToken
+  {
     Token token = null;
     String leavingTransitionName = null;
-    public ForkedToken(Token token, String leavingTransitionName) {
+
+    public ForkedToken(Token token, String leavingTransitionName)
+    {
       this.token = token;
       this.leavingTransitionName = leavingTransitionName;
     }
   }
-  
+
   private static Log log = LogFactory.getLog(Fork.class);
 }

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Join.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Join.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/Join.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -37,20 +37,19 @@
 import org.jbpm.jpdl.xml.JpdlXmlReader;
 import org.jbpm.jpdl.xml.Parsable;
 
-public class Join extends Node implements Parsable {
+public class Join extends Node implements Parsable
+{
 
   private static final long serialVersionUID = 1L;
-  
-  /** 
-   * specifies wether what type of hibernate lock should be acquired.
-   * null value defaults to LockMode.FORCE 
-   */ 
+
+  /**
+   * specifies wether what type of hibernate lock should be acquired. null value defaults to LockMode.FORCE
+   */
   String parentLockMode;
 
   /**
-   * specifies if this joinhandler is a discriminator.
-   * a descriminator reactivates the parent when the first 
-   * concurrent token enters the join. 
+   * specifies if this joinhandler is a discriminator. a descriminator reactivates the parent when the first concurrent
+   * token enters the join.
    */
   boolean isDiscriminator = false;
 
@@ -63,23 +62,32 @@
    * a script that calculates concurrent tokens at runtime.
    */
   Script script = null;
-  
+
   /**
    * reactivate the parent if the n-th token arrives in the join.
    */
   int nOutOfM = -1;
-  
 
-  public Join() {
+  public Join()
+  {
   }
 
-  public Join(String name) {
+  public Join(String name)
+  {
     super(name);
   }
 
-  public void read(Element element, JpdlXmlReader jpdlReader) {
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.Join;
+  }
+
+  public void read(Element element, JpdlXmlReader jpdlReader)
+  {
     String lock = element.attributeValue("lock");
-    if (lock != null) {
+    if (lock != null)
+    {
       LockMode lockMode = LockMode.parse(lock);
       if (lockMode != null)
         parentLockMode = lockMode.toString();
@@ -90,30 +98,35 @@
     }
   }
 
-  public void execute(ExecutionContext executionContext) {
+  public void execute(ExecutionContext executionContext)
+  {
     Token token = executionContext.getToken();
-    
+
     boolean isAbleToReactivateParent = token.isAbleToReactivateParent();
-    
-    if (!token.hasEnded()) {
+
+    if (!token.hasEnded())
+    {
       token.end(false);
     }
-    
-    // if this token is not able to reactivate the parent, 
+
+    // if this token is not able to reactivate the parent,
     // we don't need to check anything
-    if ( isAbleToReactivateParent ) {
+    if (isAbleToReactivateParent)
+    {
 
-      // the token arrived in the join and can only reactivate 
+      // the token arrived in the join and can only reactivate
       // the parent once
       token.setAbleToReactivateParent(false);
 
       Token parentToken = token.getParent();
-      
-      if ( parentToken != null ) {
-        
+
+      if (parentToken != null)
+      {
+
         JbpmContext jbpmContext = executionContext.getJbpmContext();
-        Session session = (jbpmContext!=null ? jbpmContext.getSession() : null);
-        if (session!=null) {
+        Session session = (jbpmContext != null ? jbpmContext.getSession() : null);
+        if (session != null)
+        {
           // force version increment by default (LockMode.FORCE)
           LockMode lockMode = parentLockMode != null ? LockMode.parse(parentLockMode) : LockMode.FORCE;
           log.debug("acquiring " + lockMode + " lock on " + parentToken);
@@ -124,70 +137,89 @@
         boolean reactivateParent = true;
 
         // if this is a discriminator
-        if ( isDiscriminator ) {
+        if (isDiscriminator)
+        {
           // reactivate the parent when the first token arrives in the join.
           // this must be the first token arriving, otherwise isAbleToReactivateParent()
           // should have been false above.
           reactivateParent = true;
 
-        // if a fixed set of tokenNames is specified at design time...
-        } else if ( tokenNames != null ) {
+          // if a fixed set of tokenNames is specified at design time...
+        }
+        else if (tokenNames != null)
+        {
           // check reactivation on the basis of those tokenNames
-          reactivateParent = mustParentBeReactivated(parentToken, tokenNames.iterator() );
+          reactivateParent = mustParentBeReactivated(parentToken, tokenNames.iterator());
 
-        // if a script is specified
-        } else if ( script != null ) {
+          // if a script is specified
+        }
+        else if (script != null)
+        {
 
           // check if the script returns a collection or a boolean
           Object result = null;
-          try {
-            result = script.eval( token );
-          } catch (Exception e) {
+          try
+          {
+            result = script.eval(token);
+          }
+          catch (Exception e)
+          {
             this.raiseException(e, executionContext);
           }
-          // if the result is a collection 
-          if ( result instanceof Collection ) {
-            // it must be a collection of tokenNames 
-            Collection runtimeTokenNames = (Collection) result;
-            reactivateParent = mustParentBeReactivated(parentToken, runtimeTokenNames.iterator() );
+          // if the result is a collection
+          if (result instanceof Collection)
+          {
+            // it must be a collection of tokenNames
+            Collection runtimeTokenNames = (Collection)result;
+            reactivateParent = mustParentBeReactivated(parentToken, runtimeTokenNames.iterator());
 
-
-          // if it's a boolean... 
-          } else if ( result instanceof Boolean ) {
+            // if it's a boolean...
+          }
+          else if (result instanceof Boolean)
+          {
             // the boolean specifies if the parent needs to be reactivated
             reactivateParent = ((Boolean)result).booleanValue();
           }
 
-        // if a nOutOfM is specified
-        } else if ( nOutOfM != -1 ) {
+          // if a nOutOfM is specified
+        }
+        else if (nOutOfM != -1)
+        {
 
           int n = 0;
           // wheck how many tokens already arrived in the join
           Iterator iter = parentToken.getChildren().values().iterator();
-          while ( iter.hasNext() ) {
+          while (iter.hasNext())
+          {
             Token concurrentToken = (Token)iter.next();
-            if (this.equals(concurrentToken.getNode())) {
+            if (this.equals(concurrentToken.getNode()))
+            {
               n++;
             }
           }
-          if ( n < nOutOfM ) {
+          if (n < nOutOfM)
+          {
             reactivateParent = false;
           }
-          
-        // if no configuration is specified..
-        } else {
+
+          // if no configuration is specified..
+        }
+        else
+        {
           // the default behaviour is to check all concurrent tokens and reactivate
           // the parent if the last token arrives in the join
-          reactivateParent = mustParentBeReactivated(parentToken, parentToken.getChildren().keySet().iterator() );
+          reactivateParent = mustParentBeReactivated(parentToken, parentToken.getChildren().keySet().iterator());
         }
 
         // if the parent token needs to be reactivated from this join node
-        if (reactivateParent) {
+        if (reactivateParent)
+        {
 
           // write to all child tokens that the parent is already reactivated
           Iterator iter = parentToken.getChildren().values().iterator();
-          while ( iter.hasNext() ) {
-            ((Token)iter.next()).setAbleToReactivateParent( false );
+          while (iter.hasNext())
+          {
+            ((Token)iter.next()).setAbleToReactivateParent(false);
           }
 
           // write to all child tokens that the parent is already reactivated
@@ -198,50 +230,71 @@
     }
   }
 
-  public boolean mustParentBeReactivated(Token parentToken, Iterator childTokenNameIterator) {
+  public boolean mustParentBeReactivated(Token parentToken, Iterator childTokenNameIterator)
+  {
     boolean reactivateParent = true;
-    while ( (childTokenNameIterator.hasNext())
-            && (reactivateParent) ){
-      String concurrentTokenName = (String) childTokenNameIterator.next();
-      
-      Token concurrentToken = parentToken.getChild( concurrentTokenName );
-      
-      if (concurrentToken.isAbleToReactivateParent()) {
-        log.debug("join will not yet reactivate parent: found concurrent token '"+concurrentToken+"'");
+    while ((childTokenNameIterator.hasNext()) && (reactivateParent))
+    {
+      String concurrentTokenName = (String)childTokenNameIterator.next();
+
+      Token concurrentToken = parentToken.getChild(concurrentTokenName);
+
+      if (concurrentToken.isAbleToReactivateParent())
+      {
+        log.debug("join will not yet reactivate parent: found concurrent token '" + concurrentToken + "'");
         reactivateParent = false;
       }
     }
     return reactivateParent;
   }
 
-  public String getParentLockMode() {
+  public String getParentLockMode()
+  {
     return parentLockMode;
   }
-  public void setParentLockMode(String parentLockMode) {
+
+  public void setParentLockMode(String parentLockMode)
+  {
     this.parentLockMode = parentLockMode;
   }
-  public Script getScript() {
+
+  public Script getScript()
+  {
     return script;
   }
-  public void setScript(Script script) {
+
+  public void setScript(Script script)
+  {
     this.script = script;
   }
-  public Collection getTokenNames() {
+
+  public Collection getTokenNames()
+  {
     return tokenNames;
   }
-  public void setTokenNames(Collection tokenNames) {
+
+  public void setTokenNames(Collection tokenNames)
+  {
     this.tokenNames = tokenNames;
   }
-  public boolean isDiscriminator() {
+
+  public boolean isDiscriminator()
+  {
     return isDiscriminator;
   }
-  public void setDiscriminator(boolean isDiscriminator) {
+
+  public void setDiscriminator(boolean isDiscriminator)
+  {
     this.isDiscriminator = isDiscriminator;
   }
-  public int getNOutOfM() {
+
+  public int getNOutOfM()
+  {
     return nOutOfM;
   }
-  public void setNOutOfM(int nOutOfM) {
+
+  public void setNOutOfM(int nOutOfM)
+  {
     this.nOutOfM = nOutOfM;
   }
 

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/StartState.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/StartState.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/StartState.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -41,6 +41,22 @@
     super(name);
   }
 
+  @Override
+  public String getName()
+  {
+    String name = super.getName();
+    if (name == null)
+      name = "StartState";
+    
+    return name;
+  }
+
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.StartState;
+  }
+
   // event types //////////////////////////////////////////////////////////////
 
   public static final String[] supportedEventTypes = new String[]{

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/State.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/State.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/State.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -22,20 +22,31 @@
 package org.jbpm.graph.node;
 
 import org.jbpm.graph.def.*;
+import org.jbpm.graph.def.Node.NodeType;
 import org.jbpm.graph.exe.*;
 
-public class State extends Node {
-  
+public class State extends Node
+{
+
   private static final long serialVersionUID = 1L;
 
-  public State() {
+  public State()
+  {
     this(null);
   }
-  
-  public State(String name) {
-    super( name );
+
+  public State(String name)
+  {
+    super(name);
   }
 
-  public void execute(ExecutionContext executionContext) {
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.State;
   }
+
+  public void execute(ExecutionContext executionContext)
+  {
+  }
 }

Modified: jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/TaskNode.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/TaskNode.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/main/java/org/jbpm/graph/node/TaskNode.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -21,22 +21,31 @@
  */
 package org.jbpm.graph.node;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
 
 import org.dom4j.Element;
-import org.jbpm.graph.def.*;
-import org.jbpm.graph.exe.*;
+import org.jbpm.graph.def.Node;
+import org.jbpm.graph.def.Transition;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.Token;
 import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
-import org.jbpm.jpdl.xml.*;
-import org.jbpm.taskmgmt.def.*;
-import org.jbpm.taskmgmt.exe.*;
+import org.jbpm.jpdl.xml.JpdlXmlReader;
+import org.jbpm.jpdl.xml.Parsable;
+import org.jbpm.taskmgmt.def.Task;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
 
 /**
- * is a node that relates to one or more tasks.
- * Property <code>signal</code> specifies how task completion 
- * triggers continuation of execution. 
+ * is a node that relates to one or more tasks. Property <code>signal</code> specifies how task completion triggers
+ * continuation of execution.
  */
-public class TaskNode extends Node implements Parsable {
+public class TaskNode extends Node implements Parsable
+{
 
   private static final long serialVersionUID = 1L;
 
@@ -49,122 +58,165 @@
    */
   public static final int SIGNAL_NEVER = 1;
   /**
-   * proceeds execution when the first task instance is completed.   
-   * when no tasks are created on entrance of this node, execution is continued.   
+   * proceeds execution when the first task instance is completed. when no tasks are created on entrance of this node,
+   * execution is continued.
    */
   public static final int SIGNAL_FIRST = 2;
   /**
-   * proceeds execution when the first task instance is completed.   
-   * when no tasks are created on entrance of this node, execution waits in the task node till tasks are created.   
+   * proceeds execution when the first task instance is completed. when no tasks are created on entrance of this node,
+   * execution waits in the task node till tasks are created.
    */
   public static final int SIGNAL_FIRST_WAIT = 3;
   /**
-   * proceeds execution when the last task instance is completed.
-   * when no tasks are created on entrance of this node, execution is continued.
+   * proceeds execution when the last task instance is completed. when no tasks are created on entrance of this node,
+   * execution is continued.
    */
   public static final int SIGNAL_LAST = 4;
   /**
-   * proceeds execution when the last task instance is completed.
-   * when no tasks are created on entrance of this node, execution waits in the task node till tasks are created.   
+   * proceeds execution when the last task instance is completed. when no tasks are created on entrance of this node,
+   * execution waits in the task node till tasks are created.
    */
   public static final int SIGNAL_LAST_WAIT = 5;
-  
-  public static int parseSignal(String text) {
-    if ("unsynchronized".equalsIgnoreCase(text)) {
+
+  public static int parseSignal(String text)
+  {
+    if ("unsynchronized".equalsIgnoreCase(text))
+    {
       return SIGNAL_UNSYNCHRONIZED;
-    } else if ("never".equalsIgnoreCase(text)) {
+    }
+    else if ("never".equalsIgnoreCase(text))
+    {
       return SIGNAL_NEVER;
-    } else if ("first".equalsIgnoreCase(text)) {
+    }
+    else if ("first".equalsIgnoreCase(text))
+    {
       return SIGNAL_FIRST;
-    } else if ("first-wait".equalsIgnoreCase(text)) {
+    }
+    else if ("first-wait".equalsIgnoreCase(text))
+    {
       return SIGNAL_FIRST_WAIT;
-    } else if ("last-wait".equalsIgnoreCase(text)) {
+    }
+    else if ("last-wait".equalsIgnoreCase(text))
+    {
       return SIGNAL_LAST_WAIT;
-    } else { // return default
+    }
+    else
+    { // return default
       return SIGNAL_LAST;
     }
   }
-  
-  public static String signalToString(int signal) {
-    if (signal==SIGNAL_UNSYNCHRONIZED) {
+
+  public static String signalToString(int signal)
+  {
+    if (signal == SIGNAL_UNSYNCHRONIZED)
+    {
       return "unsynchronized";
-    } else if (signal==SIGNAL_NEVER) {
+    }
+    else if (signal == SIGNAL_NEVER)
+    {
       return "never";
-    } else if (signal==SIGNAL_FIRST) {
+    }
+    else if (signal == SIGNAL_FIRST)
+    {
       return "first";
-    } else if (signal==SIGNAL_FIRST_WAIT) {
+    }
+    else if (signal == SIGNAL_FIRST_WAIT)
+    {
       return "first-wait";
-    } else if (signal==SIGNAL_LAST) {
+    }
+    else if (signal == SIGNAL_LAST)
+    {
       return "last";
-    } else if (signal==SIGNAL_LAST_WAIT) {
+    }
+    else if (signal == SIGNAL_LAST_WAIT)
+    {
       return "last-wait";
-    } else {
+    }
+    else
+    {
       return null;
     }
   }
-  
+
   Set tasks = null;
   int signal = SIGNAL_LAST;
   boolean createTasks = true;
   boolean endTasks = false;
-  
-  public TaskNode() {
+
+  public TaskNode()
+  {
   }
 
-  public TaskNode(String name) {
+  public TaskNode(String name)
+  {
     super(name);
   }
 
-  public void read(Element element, JpdlXmlReader jpdlReader) {
+  @Override
+  public NodeType getNodeType()
+  {
+    return NodeType.Task;
+  }
+
+  public void read(Element element, JpdlXmlReader jpdlReader)
+  {
     // get the signal
     String signalText = element.attributeValue("signal");
-    if (signalText!=null) {
+    if (signalText != null)
+    {
       signal = parseSignal(signalText);
     }
 
     // create tasks
     String createTasksText = element.attributeValue("create-tasks");
-    if (createTasksText!=null) {
-      if (("no".equalsIgnoreCase(createTasksText))
-           || ("false".equalsIgnoreCase(createTasksText)) ) {
+    if (createTasksText != null)
+    {
+      if (("no".equalsIgnoreCase(createTasksText)) || ("false".equalsIgnoreCase(createTasksText)))
+      {
         createTasks = false;
       }
     }
-    
+
     // create tasks
     String removeTasksText = element.attributeValue("end-tasks");
-    if (removeTasksText!=null) {
-      if (("yes".equalsIgnoreCase(removeTasksText))
-           || ("true".equalsIgnoreCase(removeTasksText)) ) {
+    if (removeTasksText != null)
+    {
+      if (("yes".equalsIgnoreCase(removeTasksText)) || ("true".equalsIgnoreCase(removeTasksText)))
+      {
         endTasks = true;
       }
     }
-    
+
     // parse the tasks
     jpdlReader.readTasks(element, this);
   }
 
-  public void addTask(Task task) {
-    if (tasks==null) tasks = new HashSet();
+  public void addTask(Task task)
+  {
+    if (tasks == null)
+      tasks = new HashSet();
     tasks.add(task);
     task.setTaskNode(this);
   }
 
   // node behaviour methods
-  /////////////////////////////////////////////////////////////////////////////
-  
-  public void execute(ExecutionContext executionContext) {
-    
+  // ///////////////////////////////////////////////////////////////////////////
+
+  public void execute(ExecutionContext executionContext)
+  {
+
     TaskMgmtInstance tmi = getTaskMgmtInstance(executionContext.getToken());
-    
+
     // if this tasknode should create instances
-    if ( (createTasks)
-         && (tasks!=null) ) {
+    if ((createTasks) && (tasks != null))
+    {
       Iterator iter = tasks.iterator();
-      while (iter.hasNext()) {
-        Task task = (Task) iter.next();
+      while (iter.hasNext())
+      {
+        Task task = (Task)iter.next();
         executionContext.setTask(task);
-        if (evaluateTaskCondition(task.getCondition(), executionContext)) {
+        if (evaluateTaskCondition(task.getCondition(), executionContext))
+        {
           tmi.createTaskInstance(task, executionContext);
         }
       }
@@ -172,7 +224,8 @@
 
     // check if we should continue execution
     boolean continueExecution;
-    switch (signal) {
+    switch (signal)
+    {
       case SIGNAL_UNSYNCHRONIZED:
         continueExecution = true;
         break;
@@ -184,93 +237,104 @@
         continueExecution = false;
     }
 
-    if (continueExecution) {
+    if (continueExecution)
+    {
       leave(executionContext);
     }
   }
-  
-  boolean evaluateTaskCondition(String condition, ExecutionContext executionContext) {
-    if (condition==null) return true;
+
+  boolean evaluateTaskCondition(String condition, ExecutionContext executionContext)
+  {
+    if (condition == null)
+      return true;
     Object result = JbpmExpressionEvaluator.evaluate(condition, executionContext);
-    if (Boolean.TRUE.equals(result)) {
+    if (Boolean.TRUE.equals(result))
+    {
       return true;
     }
     return false;
   }
 
-  public void leave(ExecutionContext executionContext, Transition transition) {
+  public void leave(ExecutionContext executionContext, Transition transition)
+  {
     TaskMgmtInstance tmi = getTaskMgmtInstance(executionContext.getToken());
-    if (tmi.hasBlockingTaskInstances(executionContext.getToken()) ) { 
-      throw new IllegalStateException("task-node '"+name+"' still has blocking tasks");
+    if (tmi.hasBlockingTaskInstances(executionContext.getToken()))
+    {
+      throw new IllegalStateException("task-node '" + name + "' still has blocking tasks");
     }
     removeTaskInstanceSynchronization(executionContext.getToken());
     super.leave(executionContext, transition);
   }
-  
+
   // task behaviour methods
-  /////////////////////////////////////////////////////////////////////////////
+  // ///////////////////////////////////////////////////////////////////////////
 
-  public boolean completionTriggersSignal(TaskInstance taskInstance) {
+  public boolean completionTriggersSignal(TaskInstance taskInstance)
+  {
     boolean completionTriggersSignal;
-    switch (signal) {
-    case SIGNAL_FIRST:
-    case SIGNAL_FIRST_WAIT:
-      completionTriggersSignal = true;
-      break;
-    case SIGNAL_LAST:
-    case SIGNAL_LAST_WAIT:
-      completionTriggersSignal = isLastToComplete(taskInstance);
-      break;
-    default:
-      completionTriggersSignal = false;
+    switch (signal)
+    {
+      case SIGNAL_FIRST:
+      case SIGNAL_FIRST_WAIT:
+        completionTriggersSignal = true;
+        break;
+      case SIGNAL_LAST:
+      case SIGNAL_LAST_WAIT:
+        completionTriggersSignal = isLastToComplete(taskInstance);
+        break;
+      default:
+        completionTriggersSignal = false;
     }
     return completionTriggersSignal;
   }
 
-  boolean isLastToComplete(TaskInstance taskInstance) {
+  boolean isLastToComplete(TaskInstance taskInstance)
+  {
     Token token = taskInstance.getToken();
     TaskMgmtInstance tmi = getTaskMgmtInstance(token);
-    
+
     boolean isLastToComplete = true;
     Iterator iter = tmi.getTaskInstances().iterator();
-    while ( iter.hasNext()
-            && (isLastToComplete) ) {
-      TaskInstance other = (TaskInstance) iter.next();
-      if ( (token!=null)
-           && (token.equals(other.getToken()))
-           && (! other.equals(taskInstance))
-           && (other.isSignalling())
-           && (!other.hasEnded())
-          ) {
+    while (iter.hasNext() && (isLastToComplete))
+    {
+      TaskInstance other = (TaskInstance)iter.next();
+      if ((token != null) && (token.equals(other.getToken())) && (!other.equals(taskInstance)) && (other.isSignalling()) && (!other.hasEnded()))
+      {
         isLastToComplete = false;
       }
     }
-    
+
     return isLastToComplete;
   }
 
-  public void removeTaskInstanceSynchronization(Token token) {
+  public void removeTaskInstanceSynchronization(Token token)
+  {
     TaskMgmtInstance tmi = getTaskMgmtInstance(token);
     Collection taskInstances = tmi.getTaskInstances();
-    if (taskInstances!=null) {
+    if (taskInstances != null)
+    {
       Iterator iter = taskInstances.iterator();
-      while (iter.hasNext()) {
-        TaskInstance taskInstance = (TaskInstance) iter.next();
-        if (token.equals(taskInstance.getToken())) {
+      while (iter.hasNext())
+      {
+        TaskInstance taskInstance = (TaskInstance)iter.next();
+        if (token.equals(taskInstance.getToken()))
+        {
           // remove signalling
-          if (taskInstance.isSignalling()) {
+          if (taskInstance.isSignalling())
+          {
             taskInstance.setSignalling(false);
           }
           // remove blocking
-          if (taskInstance.isBlocking()) {
+          if (taskInstance.isBlocking())
+          {
             taskInstance.setBlocking(false);
           }
           // if this is a non-finished task and all those
           // tasks should be finished
-          if ( (! taskInstance.hasEnded())
-               && (endTasks)
-             ) {
-            if (tasks.contains(taskInstance.getTask())) {
+          if ((!taskInstance.hasEnded()) && (endTasks))
+          {
+            if (tasks.contains(taskInstance.getTask()))
+            {
               // end this task
               taskInstance.end();
             }
@@ -280,59 +344,77 @@
     }
   }
 
-  TaskMgmtInstance getTaskMgmtInstance(Token token) {
-    return (TaskMgmtInstance) token.getProcessInstance().getInstance(TaskMgmtInstance.class);
+  TaskMgmtInstance getTaskMgmtInstance(Token token)
+  {
+    return (TaskMgmtInstance)token.getProcessInstance().getInstance(TaskMgmtInstance.class);
   }
 
   // getters and setters
-  /////////////////////////////////////////////////////////////////////////////
+  // ///////////////////////////////////////////////////////////////////////////
 
   /**
-   * is a Map with the tasks, keyed by task-name or an empty map in case 
-   * no tasks are present in this task-node. 
+   * is a Map with the tasks, keyed by task-name or an empty map in case no tasks are present in this task-node.
    */
-  public Map getTasksMap() {
+  public Map getTasksMap()
+  {
     Map tasksMap = new HashMap();
-    if (tasks!=null) {
+    if (tasks != null)
+    {
       Iterator iter = tasks.iterator();
-      while (iter.hasNext()) {
-        Task task = (Task) iter.next();
+      while (iter.hasNext())
+      {
+        Task task = (Task)iter.next();
         tasksMap.put(task.getName(), task);
       }
     }
     return tasksMap;
   }
-  
+
   /**
-   * is the task in this task-node with the given name or null if the given task 
-   * does not exist in this node. 
+   * is the task in this task-node with the given name or null if the given task does not exist in this node.
    */
-  public Task getTask(String taskName) {
-    return (Task) getTasksMap().get(taskName);
+  public Task getTask(String taskName)
+  {
+    return (Task)getTasksMap().get(taskName);
   }
 
-  public Set getTasks() {
+  public Set getTasks()
+  {
     return tasks;
   }
-  public int getSignal() {
+
+  public int getSignal()
+  {
     return signal;
   }
-  public boolean getCreateTasks() {
+
+  public boolean getCreateTasks()
+  {
     return createTasks;
   }
-  public boolean isEndTasks() {
+
+  public boolean isEndTasks()
+  {
     return endTasks;
   }
-  public void setCreateTasks(boolean createTasks) {
+
+  public void setCreateTasks(boolean createTasks)
+  {
     this.createTasks = createTasks;
   }
-  public void setEndTasks(boolean endTasks) {
+
+  public void setEndTasks(boolean endTasks)
+  {
     this.endTasks = endTasks;
   }
-  public void setSignal(int signal) {
+
+  public void setSignal(int signal)
+  {
     this.signal = signal;
   }
-  public void setTasks(Set tasks) {
+
+  public void setTasks(Set tasks)
+  {
     this.tasks = tasks;
   }
 }

Modified: jbpm3/branches/tdiesler/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java
===================================================================
--- jbpm3/branches/tdiesler/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -179,7 +179,6 @@
       processInstance.signal();
 
       processInstance = saveAndReload(processInstance);
-      processInstance = saveAndReload(processInstance);
       processInstance.signal("cancel");
 
       Collection taskInstances = processInstance.getTaskMgmtInstance().getTaskInstances();

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/EndEventImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/EndEventImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/EndEventImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -39,7 +39,7 @@
 {
   private static final long serialVersionUID = 1L;
   
-  public EndEventImpl(ProcessDefinition procDef, EndState oldEnd)
+  public EndEventImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldEnd)
   {
     super(procDef, oldEnd);
   }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ExclusiveGatewayImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ExclusiveGatewayImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ExclusiveGatewayImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -23,6 +23,8 @@
 
 // $Id$
 
+import org.hibernate.intercept.cglib.CGLIBHelper;
+import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory;
 import org.jboss.bpm.api.client.ProcessEngine;
 import org.jboss.bpm.api.model.ExclusiveGateway;
 import org.jboss.bpm.api.model.Expression;
@@ -36,6 +38,7 @@
 import org.jbpm.instantiation.Delegation;
 import org.jbpm.integration.spec.runtime.ExpressionEvaluator;
 import org.jbpm.integration.spec.runtime.TokenImpl;
+import org.jbpm.mock.CglibEnhancer;
 
 /**
  * An integration wrapper
@@ -47,11 +50,11 @@
 {
   private static final long serialVersionUID = 1L;
 
-  public ExclusiveGatewayImpl(ProcessDefinition procDef, Decision oldDecision)
+  public ExclusiveGatewayImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldNode)
   {
-    super(procDef, oldDecision);
+    super(procDef, oldNode);
     ExclusiveGatewayDecisionHandler decisionHandler = new ExclusiveGatewayDecisionHandler();
-    oldDecision.setDecisionDelegation(new Delegation(decisionHandler));
+    //oldNode.setDecisionDelegation(new Delegation(decisionHandler));
   }
 
   //@Override

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ParallelGatewayImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ParallelGatewayImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ParallelGatewayImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -25,8 +25,6 @@
 
 import org.jboss.bpm.api.model.ProcessDefinition;
 import org.jboss.bpm.incubator.model.ParallelGateway;
-import org.jbpm.graph.node.Fork;
-import org.jbpm.graph.node.Join;
 
 /**
  * An integration wrapper
@@ -38,16 +36,11 @@
 {
   private static final long serialVersionUID = 1L;
 
-  public ParallelGatewayImpl(ProcessDefinition procDef, Fork oldFork)
+  public ParallelGatewayImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldNode)
   {
-    super(procDef, oldFork);
+    super(procDef, oldNode);
   }
 
-  public ParallelGatewayImpl(ProcessDefinition procDef, Join oldJoin)
-  {
-    super(procDef, oldJoin);
-  }
-
   // @Override
   public GatewayType getGatewayType()
   {

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessDefinitionImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessDefinitionImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessDefinitionImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -37,14 +37,8 @@
 import org.jboss.bpm.api.model.SequenceFlow.ConditionType;
 import org.jboss.bpm.api.model.builder.ObjectNameFactory;
 import org.jbpm.graph.def.Transition;
+import org.jbpm.graph.def.Node.NodeType;
 import org.jbpm.graph.exe.ProcessInstance;
-import org.jbpm.graph.node.Decision;
-import org.jbpm.graph.node.EndState;
-import org.jbpm.graph.node.Fork;
-import org.jbpm.graph.node.Join;
-import org.jbpm.graph.node.StartState;
-import org.jbpm.graph.node.State;
-import org.jbpm.graph.node.TaskNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -119,7 +113,10 @@
 
   public Process newInstance()
   {
-    ProcessImpl procImpl = new ProcessImpl(engine, new ProcessInstance(oldProcDef));
+    ProcessInstance oldProc = new ProcessInstance();
+    oldProc.setProcessDefinition(oldProcDef);
+    
+    ProcessImpl procImpl = new ProcessImpl(engine, oldProc);
     return procImpl;
   }
 
@@ -154,39 +151,43 @@
       for(org.jbpm.graph.def.Node oldNode : oldProcDef.getNodes())
       {
         NodeImpl nodeImpl;
-        if (oldNode instanceof StartState)
+        NodeType nodeType = oldNode.getNodeType();
+        if (nodeType == NodeType.StartState)
         {
-          nodeImpl = new StartEventImpl(this, (StartState)oldNode);
+          nodeImpl = new StartEventImpl(this, oldNode);
         }
-        else if (oldNode instanceof State)
+        else if (nodeType == NodeType.State)
         {
-          nodeImpl = new WaitStateImpl(this, (State)oldNode);
+          nodeImpl = new WaitStateImpl(this, oldNode);
         }
-        else if (oldNode instanceof Fork)
+        else if (nodeType == NodeType.Fork)
         {
-          nodeImpl = new ParallelGatewayImpl(this, (Fork)oldNode);
+          nodeImpl = new ParallelGatewayImpl(this, oldNode);
         }
-        else if (oldNode instanceof Join)
+        else if (nodeType == NodeType.Join)
         {
-          nodeImpl = new ParallelGatewayImpl(this, (Join)oldNode);
+          nodeImpl = new ParallelGatewayImpl(this, oldNode);
         }
-        else if (oldNode instanceof Decision)
+        else if (nodeType == NodeType.Decission)
         {
-          nodeImpl = new ExclusiveGatewayImpl(this, (Decision)oldNode);
+          nodeImpl = new ExclusiveGatewayImpl(this, oldNode);
         }
-        else if (oldNode instanceof TaskNode)
+        else if (nodeType == NodeType.Task)
         {
-          nodeImpl = new UserTaskImpl(this, (TaskNode)oldNode);
+          nodeImpl = new UserTaskImpl(this, oldNode);
         }
-        else if (oldNode instanceof EndState)
+        else if (nodeType == NodeType.EndState)
         {
-          nodeImpl = new EndEventImpl(this, (EndState)oldNode);
+          nodeImpl = new EndEventImpl(this, oldNode);
         }
-        // Fallback to a general Task node
-        else
+        else if (nodeType == NodeType.Node)
         {
           nodeImpl = new TaskImpl(this, oldNode);
         }
+        else
+        {
+          throw new IllegalStateException("Unsupported node type: " + nodeType);
+        }
         
         nodes.add(nodeImpl);
       }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/ProcessImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -43,6 +43,7 @@
 import org.jboss.bpm.api.service.ProcessService;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.integration.spec.runtime.TokenImpl;
+import org.jbpm.util.Clock;
 
 /**
  * An integration wrapper
@@ -168,15 +169,19 @@
   // @Override
   public Token startProcess(Attachments contextData)
   {
-    
     ExecutionContextService ctxService = getProcessEngine().getService(ExecutionContextService.class);
     ExecutionContext bpmContext = ctxService.getExecutionContext(true);
     try
     {
       // Register the Process
       ProcessService procService = getProcessEngine().getService(ProcessService.class);
-      procService.registerProcess(this);
+      if (procService.getProcess(getKey()) == null)
+        procService.registerProcess(this);
 
+      // Initialize the members
+      oldProc.setRootToken(new org.jbpm.graph.exe.Token(oldProc));
+      oldProc.setStart(Clock.getCurrentTime());
+
       // Create the root token
       Token token = new TokenImpl(engine, oldProc.getRootToken());
 
@@ -191,8 +196,14 @@
         }
       }
 
+      // Set process to active
+      setProcessStatus(ProcessStatus.Active);
+      
+      // Fire the jbpm3 start event
+      NodeImpl initialNode = (NodeImpl)token.getCurrentNode();
+      oldProc.fireStartEvent(initialNode.getOldNode());
+      
       // Signal the root token
-      setProcessStatus(ProcessStatus.Active);
       token.signal();
 
       return token;
@@ -205,7 +216,8 @@
 
   public Token getRootToken()
   {
-    return new TokenImpl(engine, oldProc.getRootToken());
+    org.jbpm.graph.exe.Token rootToken = oldProc.getRootToken();
+    return rootToken != null ? new TokenImpl(engine, rootToken) : null;
   }
 
   public Set<Token> getTokens()

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/StartEventImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/StartEventImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/StartEventImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -23,12 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.bpm.api.InvalidProcessException;
 import org.jboss.bpm.api.NotImplementedException;
 import org.jboss.bpm.api.model.ProcessDefinition;
 import org.jboss.bpm.api.model.SequenceFlow;
 import org.jboss.bpm.api.model.StartEvent;
-import org.jbpm.graph.node.StartState;
 
 /**
  * An integration wrapper
@@ -40,15 +38,9 @@
 {
   private static final long serialVersionUID = 1L;
 
-  private StartState oldStart;
-
-  public StartEventImpl(ProcessDefinition procDef, StartState oldStart)
+  public StartEventImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldStart)
   {
     super(procDef, oldStart);
-    this.oldStart = oldStart;
-
-    if (oldStart.getName() == null)
-      throw new InvalidProcessException("StartEvent name cannot be null");
   }
 
   // @Override

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/UserTaskImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/UserTaskImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/UserTaskImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -38,7 +38,7 @@
 {
   private static final long serialVersionUID = 1L;
 
-  public UserTaskImpl(ProcessDefinition procDef, TaskNode oldTaskNode)
+  public UserTaskImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldTaskNode)
   {
     super(procDef, oldTaskNode);
   }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/WaitStateImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/WaitStateImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/WaitStateImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -23,7 +23,6 @@
 
 import org.jboss.bpm.api.model.ProcessDefinition;
 import org.jboss.bpm.api.model.WaitState;
-import org.jbpm.graph.node.State;
 
 /**
  * An integration wrapper
@@ -35,7 +34,7 @@
 {
   private static final long serialVersionUID = 1L;
 
-  public WaitStateImpl(ProcessDefinition procDef, State oldState)
+  public WaitStateImpl(ProcessDefinition procDef, org.jbpm.graph.def.Node oldState)
   {
     super(procDef, oldState);
   }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/builder/ProcessBuilderImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/builder/ProcessBuilderImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/model/builder/ProcessBuilderImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -41,6 +41,7 @@
 import org.jboss.bpm.api.model.builder.GatewayBuilder;
 import org.jboss.bpm.api.model.builder.ProcessBuilder;
 import org.jbpm.graph.def.Transition;
+import org.jbpm.graph.def.Node.NodeType;
 import org.jbpm.graph.node.Decision;
 import org.jbpm.graph.node.EndState;
 import org.jbpm.graph.node.StartState;
@@ -215,8 +216,9 @@
     for (Node node : procDefImpl.getNodes())
     {
       NodeImpl nodeImpl = (NodeImpl)node;
+      NodeType nodeType = nodeImpl.getOldNode().getNodeType();
       Set arriving = nodeImpl.getOldNode().getArrivingTransitions();
-      if (!(node instanceof StartEvent) && arriving == null)
+      if (nodeType != NodeType.StartState && arriving == null)
         throw new InvalidProcessException("Unreachable node: " + node);
     }
     
@@ -224,8 +226,9 @@
     for (Node node : procDefImpl.getNodes())
     {
       NodeImpl nodeImpl = (NodeImpl)node;
+      NodeType nodeType = nodeImpl.getOldNode().getNodeType();
       List leaving = nodeImpl.getOldNode().getLeavingTransitions();
-      if (!(node instanceof EndEvent) && leaving == null)
+      if (nodeType != NodeType.EndState && leaving == null)
         throw new InvalidProcessException("Dead end node: " + node);
     }
   }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/runtime/TokenImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/runtime/TokenImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/runtime/TokenImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -21,6 +21,7 @@
  */
 package org.jbpm.integration.spec.runtime;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -38,10 +39,15 @@
 import org.jboss.bpm.api.runtime.ExecutionContext;
 import org.jboss.bpm.api.runtime.Token;
 import org.jboss.bpm.api.service.ExecutionContextService;
+import org.jbpm.JbpmContext;
 import org.jbpm.context.exe.ContextInstance;
 import org.jbpm.graph.def.Transition;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.graph.node.StartState;
 import org.jbpm.integration.spec.model.NodeImpl;
 import org.jbpm.integration.spec.model.ProcessImpl;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
 
 /**
  * An integration wrapper
@@ -202,6 +208,24 @@
         lastFlow = currNode.getOutFlowByTransition(trans);
         oldToken.signal();
       }
+      
+      JbpmContext jbpmContext = bpmContext.getAttachment(JbpmContext.class);
+      ProcessInstance oldProc = oldToken.getProcessInstance();
+      
+      // Task instances are not saved automatically
+      TaskMgmtInstance taskMgmt = oldProc.getTaskMgmtInstance();
+      Collection<TaskInstance> taskInstances = taskMgmt.getTaskInstances();
+      if (taskInstances != null)
+      {
+        jbpmContext.getSession().save(taskMgmt);
+        oldProc.addInstance(taskMgmt);
+        
+        for (TaskInstance oldTask : taskInstances)
+          jbpmContext.getSession().save(oldTask);
+      }
+      
+      jbpmContext.save(oldToken);
+      
     }
     catch (RuntimeException rte)
     {

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/ProcessDefinitionServiceImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/ProcessDefinitionServiceImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/ProcessDefinitionServiceImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -148,6 +148,7 @@
         long oldID = procDefImpl.getOldProcessDefinition().getId();
         JbpmContext jbpmContext = bpmContext.getAttachment(JbpmContext.class);
         jbpmContext.getGraphSession().deleteProcessDefinition(oldID);
+        jbpmContext.getSession().flush();
         removed = true;
       }
     }

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/TaskServiceImpl.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/TaskServiceImpl.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/main/java/org/jbpm/integration/spec/service/TaskServiceImpl.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -24,18 +24,24 @@
 // $Id$
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 
 import javax.management.ObjectName;
 
 import org.jboss.bpm.api.client.ProcessEngine;
+import org.jboss.bpm.api.model.Process;
 import org.jboss.bpm.api.runtime.ExecutionContext;
 import org.jboss.bpm.api.service.ExecutionContextService;
+import org.jboss.bpm.api.service.ProcessService;
 import org.jboss.bpm.api.service.internal.AbstractTaskService;
 import org.jboss.bpm.api.task.Task;
 import org.jbpm.JbpmContext;
 import org.jbpm.integration.spec.task.TaskImpl;
+import org.jbpm.integration.spec.model.ProcessImpl;
 import org.jbpm.taskmgmt.exe.TaskInstance;
+import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,6 +62,41 @@
     super.setProcessEngine(engine);
   }
 
+  public List<Task> getTasksByProcess(ObjectName procID)
+  {
+    List<Task> tasks = new ArrayList<Task>();
+    
+    ExecutionContextService ctxService = getProcessEngine().getService(ExecutionContextService.class);
+    ExecutionContext bpmContext = ctxService.getExecutionContext(true);
+    try
+    {
+      ProcessService procService = getProcessEngine().getService(ProcessService.class);
+      Process proc = procService.getProcess(procID);
+      if (proc == null)
+        throw new IllegalStateException("Cannot obtain process: " + procID);
+
+      ProcessImpl procImpl = (ProcessImpl)proc;
+      TaskMgmtInstance taskMgmtInstance = procImpl.getOldProcessInstance().getTaskMgmtInstance();
+      Collection<TaskInstance> taskInstances = taskMgmtInstance.getTaskInstances();
+      if (taskInstances != null)
+      {
+        Iterator<TaskInstance> itTaskInstance = taskInstances.iterator();
+        while(itTaskInstance.hasNext())
+        {
+          TaskInstance oldTask = itTaskInstance.next();
+          Task task = new TaskImpl(getProcessEngine(), oldTask);
+          tasks.add(task);
+        }
+      }
+    }
+    finally
+    {
+      bpmContext.close();
+    }
+    
+    return tasks;
+  }
+  
   public Task getTask(ObjectName taskID)
   {
     Task task = null;
@@ -68,10 +109,6 @@
       TaskInstance oldTask = jbpmContext.getTaskInstance(adaptKey(taskID));
       task = new TaskImpl(getProcessEngine(), oldTask);
     }
-    catch (RuntimeException rte)
-    {
-      throw rte;
-    }
     finally
     {
       bpmContext.close();
@@ -94,10 +131,6 @@
         tasks.add(new TaskImpl(getProcessEngine(), oldTask));
       }
     }
-    catch (RuntimeException rte)
-    {
-      throw rte;
-    }
     finally
     {
       bpmContext.close();

Modified: jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/deployment/DeploymentPARTest.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/deployment/DeploymentPARTest.java	2008-12-04 07:26:45 UTC (rev 3189)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/deployment/DeploymentPARTest.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -34,6 +34,7 @@
 import org.jboss.bpm.api.model.ProcessDefinition;
 import org.jboss.bpm.api.runtime.Token;
 import org.jboss.bpm.api.service.DeploymentService;
+import org.jboss.bpm.api.service.ProcessService;
 import org.jboss.bpm.api.service.TaskService;
 import org.jboss.bpm.api.task.Task;
 import org.jboss.bpm.api.test.APITestCase;
@@ -55,32 +56,42 @@
 
     ProcessDefinition procDef = depService.deploy(dep);
     assertNotNull("ProcDef not null", procDef);
-    
+
     Process proc = procDef.newInstance();
     Token token = proc.startProcess();
+
+    assertEquals("start", token.getCurrentNode().getName());
+    assertEquals(0, token.getChildTokens().size());
+
+/*    
+    token.signal();
     
     assertEquals("fork1", token.getCurrentNode().getName());
     assertEquals(2, token.getChildTokens().size());
     
     // Get the child tokens
-    Map<String,Token> childToks = new HashMap<String, Token>();
+    Token childOne = getChildToken(token, "Review Order");
+    assertNotNull("Review Order", childOne);
+    
+    Token childTwo = getChildToken(token, "Prepare shipping");
+    assertNotNull("Review Order", childTwo);
+    
+    TaskService taskService = getProcessEngine().getService(TaskService.class);
+    assertEquals(2, taskService.getTasksByProcess(proc.getKey()).size());
+*/    
+    // Undeploy the process
+    assertTrue("Undeploy successful", depService.undeploy(dep));
+  }
+
+  private Token getChildToken(Token token, String nodeName)
+  {
+    Map<String, Token> childToks = new HashMap<String, Token>();
     Iterator<Token> itTok = token.getChildTokens().iterator();
     while (itTok.hasNext())
     {
       Token child = itTok.next();
       childToks.put(child.getCurrentNode().getName(), child);
     }
-    Token childOne = childToks.get("Prepare shipping");
-    Token childTwo = childToks.get("Review Order");
-    
-    assertNotNull("Prepare shipping", childOne);
-    assertNotNull("Review Order", childTwo);
-
-    TaskService taskService = getProcessEngine().getService(TaskService.class);
-    List<Task> tasks = taskService.getTasksByActor("sales");
-    System.out.println(tasks);
-    
-    // Undeploy the process
-    assertTrue("Undeploy successful", depService.undeploy(dep));
+    return childToks.get(nodeName);
   }
 }

Added: jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/TaskTest.java
===================================================================
--- jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/TaskTest.java	                        (rev 0)
+++ jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/TaskTest.java	2008-12-04 07:28:48 UTC (rev 3190)
@@ -0,0 +1,318 @@
+/*
+ * 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.test.integration.spec.task;
+
+// $Id$
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.jboss.bpm.api.deployment.Deployment;
+import org.jboss.bpm.api.deployment.SimpleDeployment;
+import org.jboss.bpm.api.model.Process;
+import org.jboss.bpm.api.model.ProcessDefinition;
+import org.jboss.bpm.api.service.DeploymentService;
+import org.jboss.bpm.api.test.APITestCase;
+import org.jbpm.JbpmConfiguration;
+import org.jbpm.JbpmContext;
+import org.jbpm.db.GraphSession;
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.taskmgmt.exe.TaskInstance;
+
+/**
+ * This uses the API to do the same as the EndTasksDbTest
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 03-Dec-2008
+ */
+public class TaskTest extends APITestCase
+{
+  private JbpmConfiguration jbpmConfiguration;
+  private JbpmContext jbpmContext;
+  private GraphSession graphSession;
+  
+  public void testCancelOld() 
+  {
+    org.jbpm.graph.def.ProcessDefinition processDefinition = org.jbpm.graph.def.ProcessDefinition.parseXmlString(
+      "<process-definition name='endtasksprocess'>" +
+      "  <start-state>" +
+      "    <transition to='approval' />" +
+      "  </start-state>" +
+      "  <task-node name='approval' end-tasks='true'>" +
+      "    <task name='approve' description='Review order'>" +
+      "      <assignment pooled-actors='reviewers' />" +
+      "    </task>" +
+      "    <transition name='approve' to='process'>" +
+      "      <action class='"+Buzz.class.getName()+"' />" +
+      "    </transition>" +
+      "    <transition name='cancel'  to='cancelled'/>" +
+      "  </task-node>" +
+      "  <state name='process' />" +
+      "  <state name='cancelled' />" +
+      "</process-definition>"
+    );
+    
+    jbpmContext = createJbpmContext();
+    
+    jbpmContext.deployProcessDefinition(processDefinition);
+    ProcessInstance processInstance = jbpmContext.newProcessInstance("endtasksprocess");
+    
+    processInstance = saveAndReload(processInstance);
+    
+    processInstance.signal();
+    assertEquals("approval", processInstance.getRootToken().getNode().getName());
+    
+    processInstance = saveAndReload(processInstance);
+
+    processInstance.signal("cancel");
+    assertEquals("cancelled", processInstance.getRootToken().getNode().getName());
+    
+    jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+    jbpmContext.close();
+  }
+  
+  public void testCancel() 
+  {
+    Deployment procDefDeployment = new SimpleDeployment(
+      "<process-definition name='endtasksprocess' xmlns='urn:jbpm.org:jpdl-3.2'>" +
+      "  <start-state>" +
+      "    <transition to='approval' />" +
+      "  </start-state>" +
+      "  <task-node name='approval' end-tasks='true'>" +
+      "    <task name='approve' description='Review order'>" +
+      "      <assignment pooled-actors='reviewers' />" +
+      "    </task>" +
+      "    <transition name='approve' to='process'>" +
+      "      <action class='" + Buzz.class.getName() + "' />" +
+      "    </transition>" +
+      "    <transition name='cancel'  to='cancelled'/>" +
+      "  </task-node>" +
+      "  <state name='process' />" +
+      "  <state name='cancelled' />" +
+      "</process-definition>"
+    );
+    
+    DeploymentService depService = getProcessEngine().getService(DeploymentService.class);
+    ProcessDefinition procDef = depService.deploy(procDefDeployment);
+
+    Process proc = procDef.newInstance();
+    proc.startProcess();
+
+    assertEquals("approval", proc.getRootToken().getCurrentNode().getName());
+    proc.getRootToken().signal("cancel");
+    assertEquals("cancelled", proc.getRootToken().getCurrentNode().getName());
+
+    depService.undeploy(procDefDeployment);
+  }
+
+  public void _testApprove() 
+  {
+    jbpmContext = createJbpmContext();
+    graphSession = jbpmContext.getGraphSession();
+    
+    org.jbpm.graph.def.ProcessDefinition processDefinition = org.jbpm.graph.def.ProcessDefinition.parseXmlString(
+      "<process-definition name='endtasksprocess'>" +
+      "  <start-state>" +
+      "    <transition to='approval' />" +
+      "  </start-state>" +
+      "  <task-node name='approval' end-tasks='true'>" +
+      "    <task name='approve' description='Review order'>" +
+      "      <assignment pooled-actors='reviewers' />" +
+      "    </task>" +
+      "    <transition name='approve' to='process'/>" +
+      "    <transition name='reject'  to='cancelled'/>" +
+      "    <transition name='cancel'  to='cancelled'/>" +
+      "  </task-node>" +
+      "  <state name='process' />" +
+      "  <state name='cancelled' />" +
+      "</process-definition>"
+    );
+    jbpmContext.deployProcessDefinition(processDefinition);
+    try
+    {
+      newTransaction();
+
+      ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
+      processInstance.signal();
+
+      processInstance = saveAndReload(processInstance);
+
+      assertEquals("approval", processInstance.getRootToken().getNode().getName());
+      TaskInstance taskInstance = (TaskInstance) processInstance
+          .getTaskMgmtInstance()
+          .getTaskInstances()
+          .iterator()
+          .next();
+      
+      taskInstance.end("approve");
+      assertEquals("process", processInstance.getRootToken().getNode().getName());
+    }
+    finally
+    {
+      jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+      jbpmContext.close();
+    }
+  }
+
+  public void _testReject() 
+  {
+    jbpmContext = createJbpmContext();
+    graphSession = jbpmContext.getGraphSession();
+    
+    org.jbpm.graph.def.ProcessDefinition processDefinition = org.jbpm.graph.def.ProcessDefinition.parseXmlString(
+      "<process-definition name='endtasksprocess'>" +
+      "  <start-state>" +
+      "    <transition to='approval' />" +
+      "  </start-state>" +
+      "  <task-node name='approval' end-tasks='true'>" +
+      "    <task name='approve' description='Review order'>" +
+      "      <assignment pooled-actors='reviewers' />" +
+      "    </task>" +
+      "    <transition name='approve' to='process'/>" +
+      "    <transition name='reject'  to='cancelled'/>" +
+      "    <transition name='cancel'  to='cancelled'/>" +
+      "  </task-node>" +
+      "  <state name='process' />" +
+      "  <state name='cancelled' />" +
+      "</process-definition>"
+    );
+    jbpmContext.deployProcessDefinition(processDefinition);
+    try
+    {
+      newTransaction();
+
+      ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
+      processInstance.signal();
+
+      processInstance = saveAndReload(processInstance);
+
+      assertEquals("approval", processInstance.getRootToken().getNode().getName());
+      TaskInstance taskInstance = (TaskInstance) processInstance
+          .getTaskMgmtInstance()
+          .getTaskInstances()
+          .iterator()
+          .next();
+      
+      taskInstance.end("reject");
+      assertEquals("cancelled", processInstance.getRootToken().getNode().getName());
+    }
+    finally
+    {
+      jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+      jbpmContext.close();
+    }
+  }
+
+  public void _testTaskInstancesAfterCancellation() 
+  {
+    jbpmContext = createJbpmContext();
+    graphSession = jbpmContext.getGraphSession();
+    
+    org.jbpm.graph.def.ProcessDefinition processDefinition = org.jbpm.graph.def.ProcessDefinition.parseXmlString(
+      "<process-definition name='endtasksprocess'>" +
+      "  <start-state>" +
+      "    <transition to='approval' />" +
+      "  </start-state>" +
+      "  <task-node name='approval' end-tasks='true'>" +
+      "    <task name='approve' description='Review order'>" +
+      "      <assignment pooled-actors='reviewers' />" +
+      "    </task>" +
+      "    <transition name='approve' to='process'/>" +
+      "    <transition name='reject'  to='cancelled'/>" +
+      "    <transition name='cancel'  to='cancelled'/>" +
+      "  </task-node>" +
+      "  <state name='process' />" +
+      "  <state name='cancelled' />" +
+      "</process-definition>"
+    );
+    jbpmContext.deployProcessDefinition(processDefinition);
+    try
+    {
+      newTransaction();
+
+      ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
+      processInstance.signal();
+
+      processInstance = saveAndReload(processInstance);
+      processInstance.signal("cancel");
+
+      Collection taskInstances = processInstance.getTaskMgmtInstance().getTaskInstances();
+      Iterator iter = taskInstances.iterator();
+      while(iter.hasNext()) {
+        TaskInstance taskInstance = (TaskInstance) iter.next();
+        assertTrue(taskInstance.getName()+" ended", taskInstance.hasEnded());
+        assertFalse(taskInstance.getName()+" not cancelled", taskInstance.isCancelled());
+        assertFalse(taskInstance.getName()+" not blocking", taskInstance.isBlocking());
+        assertFalse(taskInstance.getName()+" not signalling", taskInstance.isSignalling());
+      }
+    }
+    finally
+    {
+      jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+      jbpmContext.close();
+    }
+  }
+
+  public static class Buzz implements ActionHandler
+  {
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ExecutionContext executionContext) throws Exception
+    {
+      throw new RuntimeException("buzz");
+    }
+  }
+
+  private JbpmContext createJbpmContext()
+  {
+    return getJbpmConfiguration().createJbpmContext();
+  }
+  
+  private ProcessInstance saveAndReload(ProcessInstance pi)
+  {
+    if (jbpmContext == null)
+      jbpmContext = createJbpmContext();
+    
+    jbpmContext.save(pi);
+    newTransaction();
+    return graphSession.loadProcessInstance(pi.getId());
+  }
+
+  private void newTransaction()
+  {
+    if (jbpmContext != null)
+      jbpmContext.close();
+    
+    jbpmContext = createJbpmContext();
+    graphSession = jbpmContext.getGraphSession();
+  }
+  
+  private JbpmConfiguration getJbpmConfiguration()
+  {
+    if (jbpmConfiguration == null)
+      jbpmConfiguration = JbpmConfiguration.getInstance();
+    
+    return jbpmConfiguration;
+  }
+}


Property changes on: jbpm3/branches/tdiesler/modules/integration/spec/src/test/java/org/jbpm/test/integration/spec/task/TaskTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF




More information about the jbpm-commits mailing list