[jboss-svn-commits] JBL Code SVN: r16768 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: audit and 10 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Nov 23 20:26:35 EST 2007


Author: KrisVerlaenen
Date: 2007-11-23 20:26:35 -0500 (Fri, 23 Nov 2007)
New Revision: 16768

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowNodeLogEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowNodeTriggeredEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/ParameterDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/Work.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinitionExtension.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/ParameterDefinitionImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionExtensionImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItem.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemHandler.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/SystemOutWorkItemHandler.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandler.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandlerDialog.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/WorkItemImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/WorkItemNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/WorkItemNodeImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/TaskNodeInstanceImpl.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/LogEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowGroupLogEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowLogEvent.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/ProcessInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/Join.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcessValidationError.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/SubFlowNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/DroolsConsequenceAction.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidatorImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/SubFlowNodeImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/ActionNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/MilestoneNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/SubFlowNodeInstanceImpl.java
Log:
JBRULES-1342: Extend audit framework to support integrated rules and process logging
JBRULES-1343: WorkItems for communication between processes and outside world
JBRULES-1344: Discriminator join
JBRULES-1345: Subflow can specify whether this process should wait for its completion
JBRULES-1346: Extend Rules view with support for processes

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -16,9 +16,11 @@
  * limitations under the License.
  */
 
+import java.util.Collection;
 import java.util.Iterator;
 
 import org.drools.ruleflow.common.instance.ProcessInstance;
+import org.drools.ruleflow.common.instance.WorkItemManager;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.AgendaGroup;
 import org.drools.spi.AsyncExceptionHandler;
@@ -338,6 +340,21 @@
     ProcessInstance startProcess(String processId);
 
     /**
+     * Returns the list of process instances of this working memory.
+     * This list is unmodifiable.
+     * @return the list of process instances
+     */
+    public Collection getProcessInstances();
+    
+    /**
+     * Returns the process instance with the given id.
+     * @return the process instance with the given id
+     */
+    public ProcessInstance getProcessInstance(long id);
+    
+    public WorkItemManager getWorkItemManager();
+    
+    /**
      * Stops rule firing after the currect rule finishes executing
      *
      */

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryLogger.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -31,6 +31,7 @@
 import org.drools.audit.event.RuleBaseLogEvent;
 import org.drools.audit.event.RuleFlowGroupLogEvent;
 import org.drools.audit.event.RuleFlowLogEvent;
+import org.drools.audit.event.RuleFlowNodeLogEvent;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.event.ActivationCancelledEvent;
@@ -62,6 +63,7 @@
 import org.drools.event.RuleFlowEventListener;
 import org.drools.event.RuleFlowGroupActivatedEvent;
 import org.drools.event.RuleFlowGroupDeactivatedEvent;
+import org.drools.event.RuleFlowNodeTriggeredEvent;
 import org.drools.event.RuleFlowStartedEvent;
 import org.drools.event.WorkingMemoryEventListener;
 import org.drools.rule.Declaration;
@@ -319,34 +321,88 @@
         // we don't audit this yet        
     }
     
-    public void ruleFlowStarted(RuleFlowStartedEvent event,
-            					WorkingMemory workingMemory) {
-        filterLogEvent( new RuleFlowLogEvent( LogEvent.RULEFLOW_CREATED,
+    public void beforeRuleFlowStarted(RuleFlowStartedEvent event,
+            					      WorkingMemory workingMemory) {
+        filterLogEvent( new RuleFlowLogEvent( LogEvent.BEFORE_RULEFLOW_CREATED,
         		event.getRuleFlowProcessInstance().getProcess().getId(),
                 event.getRuleFlowProcessInstance().getProcess().getName() ) );
     }
 
-    public void ruleFlowCompleted(RuleFlowCompletedEvent event,
+    public void afterRuleFlowStarted(RuleFlowStartedEvent event,
+                                     WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowLogEvent(LogEvent.AFTER_RULEFLOW_CREATED,
+                event.getRuleFlowProcessInstance().getProcess().getId(),
+                event.getRuleFlowProcessInstance().getProcess().getName()));
+    }
+
+    public void beforeRuleFlowCompleted(RuleFlowCompletedEvent event,
               					  WorkingMemory workingMemory) {
-        filterLogEvent( new RuleFlowLogEvent( LogEvent.RULEFLOW_COMPLETED,
+        filterLogEvent( new RuleFlowLogEvent( LogEvent.BEFORE_RULEFLOW_COMPLETED,
         		event.getRuleFlowProcessInstance().getProcess().getId(),
                 event.getRuleFlowProcessInstance().getProcess().getName() ) );
     }
     
-    public void ruleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
-           							   WorkingMemory workingMemory) {
-        filterLogEvent( new RuleFlowGroupLogEvent( LogEvent.RULEFLOW_GROUP_ACTIVATED,
-        		event.getRuleFlowGroup().getName(),
-                event.getRuleFlowGroup().size() ) );
+    public void afterRuleFlowCompleted(RuleFlowCompletedEvent event,
+                                       WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowLogEvent(LogEvent.AFTER_RULEFLOW_COMPLETED,
+                event.getRuleFlowProcessInstance().getProcess().getId(),
+                event.getRuleFlowProcessInstance().getProcess().getName()));
     }
 
-    public void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
-                     					 WorkingMemory workingMemory) {
-        filterLogEvent( new RuleFlowGroupLogEvent( LogEvent.RULEFLOW_GROUP_DEACTIVATED,
-        		event.getRuleFlowGroup().getName(),
-                event.getRuleFlowGroup().size() ) );
+    public void beforeRuleFlowGroupActivated(
+            RuleFlowGroupActivatedEvent event,
+            WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowGroupLogEvent(
+                LogEvent.BEFORE_RULEFLOW_GROUP_ACTIVATED, event
+                        .getRuleFlowGroup().getName(), event.getRuleFlowGroup()
+                        .size()));
     }
     
+    public void afterRuleFlowGroupActivated(
+            RuleFlowGroupActivatedEvent event,
+            WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowGroupLogEvent(
+                LogEvent.AFTER_RULEFLOW_GROUP_ACTIVATED,
+                event.getRuleFlowGroup().getName(),
+                event.getRuleFlowGroup().size()));
+    }
+
+    public void beforeRuleFlowGroupDeactivated(
+            RuleFlowGroupDeactivatedEvent event, 
+            WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowGroupLogEvent(
+                LogEvent.BEFORE_RULEFLOW_GROUP_DEACTIVATED,
+                event.getRuleFlowGroup().getName(),
+                event.getRuleFlowGroup().size()));
+    }
+    
+    public void afterRuleFlowGroupDeactivated(
+            RuleFlowGroupDeactivatedEvent event,
+            WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowGroupLogEvent(
+                LogEvent.AFTER_RULEFLOW_GROUP_DEACTIVATED,
+                event.getRuleFlowGroup().getName(),
+                event.getRuleFlowGroup().size()));
+    }
+
+    public void beforeRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+                                            WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowNodeLogEvent(LogEvent.BEFORE_RULEFLOW_NODE_TRIGGERED,
+                event.getRuleFlowNodeInstance().getId() + "",
+                event.getRuleFlowNodeInstance().getProcessInstance().getRuleFlowProcess().getNode(event.getRuleFlowNodeInstance().getNodeId()).getName(),
+                event.getRuleFlowProcessInstance().getProcess().getId(), event
+                        .getRuleFlowProcessInstance().getProcess().getName()));
+    }
+
+    public void afterRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+                                           WorkingMemory workingMemory) {
+        filterLogEvent(new RuleFlowNodeLogEvent(LogEvent.AFTER_RULEFLOW_NODE_TRIGGERED,
+                event.getRuleFlowNodeInstance().getId() + "",
+                event.getRuleFlowNodeInstance().getProcessInstance().getRuleFlowProcess().getNode(event.getRuleFlowNodeInstance().getNodeId()).getName(),
+                event.getRuleFlowProcessInstance().getProcess().getId(), event
+                        .getRuleFlowProcessInstance().getProcess().getName()));
+    }
+
     public void afterPackageAdded(AfterPackageAddedEvent event) {
         filterLogEvent( new RuleBaseLogEvent( LogEvent.AFTER_PACKAGE_ADDED,
                                               event.getPackage().getName(),

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/LogEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/LogEvent.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/LogEvent.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -24,29 +24,43 @@
  */
 public class LogEvent {
 
-    public static final int INSERTED            = 1;
-    public static final int UPDATED            = 2;
-    public static final int RETRACTED           = 3;
+public static final int INSERTED                                = 1;
+    public static final int UPDATED                             = 2;
+    public static final int RETRACTED                           = 3;
 
-    public static final int ACTIVATION_CREATED         = 4;
-    public static final int ACTIVATION_CANCELLED       = 5;
-    public static final int BEFORE_ACTIVATION_FIRE     = 6;
-    public static final int AFTER_ACTIVATION_FIRE      = 7;
+    public static final int ACTIVATION_CREATED                  = 4;
+    public static final int ACTIVATION_CANCELLED                = 5;
+    public static final int BEFORE_ACTIVATION_FIRE              = 6;
+    public static final int AFTER_ACTIVATION_FIRE               = 7;
 
-    public static final int RULEFLOW_CREATED           = 8;
-    public static final int RULEFLOW_COMPLETED         = 9;
-    public static final int RULEFLOW_GROUP_ACTIVATED   = 10;
-    public static final int RULEFLOW_GROUP_DEACTIVATED = 11;
+    public static final int BEFORE_RULEFLOW_CREATED             = 8;
+    public static final int AFTER_RULEFLOW_CREATED              = 9;
+    public static final int BEFORE_RULEFLOW_COMPLETED           = 10;
+    public static final int AFTER_RULEFLOW_COMPLETED            = 11;
+    public static final int BEFORE_RULEFLOW_GROUP_ACTIVATED     = 12;
+    public static final int AFTER_RULEFLOW_GROUP_ACTIVATED      = 13;
+    public static final int BEFORE_RULEFLOW_GROUP_DEACTIVATED   = 14;
+    public static final int AFTER_RULEFLOW_GROUP_DEACTIVATED    = 15;
 
-    public static final int BEFORE_PACKAGE_ADDED       = 12;
-    public static final int AFTER_PACKAGE_ADDED        = 13;
-    public static final int BEFORE_PACKAGE_REMOVED     = 14;
-    public static final int AFTER_PACKAGE_REMOVED      = 15;
-    public static final int BEFORE_RULE_ADDED          = 16;
-    public static final int AFTER_RULE_ADDED           = 17;
-    public static final int BEFORE_RULE_REMOVED        = 18;
-    public static final int AFTER_RULE_REMOVED         = 19;
+    public static final int BEFORE_PACKAGE_ADDED                = 16;
+    public static final int AFTER_PACKAGE_ADDED                 = 17;
+    public static final int BEFORE_PACKAGE_REMOVED              = 18;
+    public static final int AFTER_PACKAGE_REMOVED               = 19;
+    public static final int BEFORE_RULE_ADDED                   = 20;
+    public static final int AFTER_RULE_ADDED                    = 21;
+    public static final int BEFORE_RULE_REMOVED                 = 22;
+    public static final int AFTER_RULE_REMOVED                  = 23;
 
+    public static final int BEFORE_RULEFLOW_NODE_TRIGGERED      = 24;
+    public static final int AFTER_RULEFLOW_NODE_TRIGGERED       = 25;
+    public static final int BEFORE_RULEFLOW_NODE_EXITED         = 26;
+    public static final int AFTER_RULEFLOW_NODE_EXITED          = 27;
+    
+    public static final int BEFORE_TASK_INSTANCE_CREATED        = 28;
+    public static final int AFTER_TASK_INSTANCE_CREATED         = 29;
+    public static final int BEFORE_TASK_INSTANCE_COMPLETED      = 30;
+    public static final int AFTER_TASK_INSTANCE_COMPLETED       = 31;
+    
     private int             type;
 
     /**

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowGroupLogEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowGroupLogEvent.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowGroupLogEvent.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -55,12 +55,18 @@
 
         String msg = null;
         switch ( this.getType() ) {
-            case RULEFLOW_GROUP_ACTIVATED :
-                msg = "RULEFLOW GROUP ACTIVATED";
+            case BEFORE_RULEFLOW_GROUP_ACTIVATED :
+                msg = "BEFORE RULEFLOW GROUP ACTIVATED";
                 break;
-            case RULEFLOW_GROUP_DEACTIVATED :
-                msg = "ACTIVATION GROUP DEACTIVATED";
+            case AFTER_RULEFLOW_GROUP_ACTIVATED :
+                msg = "AFTER RULEFLOW GROUP ACTIVATED";
                 break;
+            case BEFORE_RULEFLOW_GROUP_DEACTIVATED :
+                msg = "BEFORE RULEFLOW GROUP DEACTIVATED";
+                break;
+            case AFTER_RULEFLOW_GROUP_DEACTIVATED :
+                msg = "AFTER RULEFLOW GROUP DEACTIVATED";
+                break;
         }
         return msg + " group:" + this.groupName + "[size=" + this.size + "]";
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowLogEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowLogEvent.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowLogEvent.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -31,7 +31,8 @@
     /**
      * Create a new ruleflow log event.
      * 
-     * @param type The type of event.  This can only be RULEFLOW_CREATED or RULEFLOW_COMPLETED.
+     * @param type The type of event.  This can only be RULEFLOW_CREATED,
+     *        RULEFLOW_COMPLETED, RULEFLOW_NODE_START or RULEFLOW_NODE_END.
      * @param processId The id of the process
      * @param processName The name of the process
      */
@@ -52,15 +53,20 @@
     }
 
     public String toString() {
-
         String msg = null;
         switch ( this.getType() ) {
-            case RULEFLOW_CREATED :
-                msg = "RULEFLOW STARTED";
+            case BEFORE_RULEFLOW_CREATED :
+                msg = "BEFORE RULEFLOW STARTED";
                 break;
-            case RULEFLOW_COMPLETED :
-                msg = "ACTIVATION CREATED";
+            case AFTER_RULEFLOW_CREATED :
+                msg = "AFTER RULEFLOW STARTED";
                 break;
+            case BEFORE_RULEFLOW_COMPLETED :
+                msg = "BEFORE RULEFLOW COMPLETED";
+                break;
+            case AFTER_RULEFLOW_COMPLETED :
+                msg = "AFTER RULEFLOW COMPLETED";
+                break;
         }
         return msg + " process:" + this.processName + "[id=" + this.processId + "]";
     }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowNodeLogEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowNodeLogEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/event/RuleFlowNodeLogEvent.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,48 @@
+package org.drools.audit.event;
+
+public class RuleFlowNodeLogEvent extends RuleFlowLogEvent {
+    
+    private String nodeId;
+    private String nodeName;
+
+    /**
+     * Create a new ruleflow node log event.
+     * 
+     * @param type The type of event.  This can only be RULEFLOW_NODE_START or RULEFLOW_NODE_END.
+     * @param processId The id of the process
+     * @param processName The name of the process
+     */
+    public RuleFlowNodeLogEvent(final int type,
+                                final String nodeId,
+                                final String nodeName,
+                                final String processId,
+                                final String processName) {
+        super( type, processId, processName );
+        this.nodeId = nodeId;
+        this.nodeName = nodeName;
+    }
+    
+    public String getNodeId() {
+        return nodeId;
+    }
+    
+    public String getNodeName() {
+        return nodeName;
+    }
+    
+    public String toString() {
+        String msg = null;
+        switch ( this.getType() ) {
+            case BEFORE_RULEFLOW_NODE_TRIGGERED :
+                msg = "BEFORE RULEFLOW NODE TRIGGERED";
+                break;
+            case AFTER_RULEFLOW_NODE_TRIGGERED :
+                msg = "AFTER RULEFLOW NODE TRIGGERED";
+                break;
+            default:
+                return super.toString();
+        }
+        return msg + " node:" + nodeName + "[id=" + nodeId + "] process:" + getProcessName() + "[id=" + getProcessId() + "]";
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -22,6 +22,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -56,6 +57,7 @@
 import org.drools.rule.TimeMachine;
 import org.drools.ruleflow.common.core.Process;
 import org.drools.ruleflow.common.instance.ProcessInstance;
+import org.drools.ruleflow.common.instance.WorkItemManager;
 import org.drools.ruleflow.core.RuleFlowProcess;
 import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 import org.drools.ruleflow.instance.impl.RuleFlowProcessInstanceImpl;
@@ -150,7 +152,11 @@
 
     protected boolean                               halt;
 
-    private int                                     processCounter;
+    private Map 						   processInstances								 = new HashMap();
+    
+    private int                            processCounter;
+    
+    private WorkItemManager            taskInstanceManager;
 
     private TimeMachine 							timeMachine = new TimeMachine();
 
@@ -198,6 +204,7 @@
         } else {
             this.discardOnLogicalOverride = false;
         }
+        taskInstanceManager = new WorkItemManager(this);
     }
 
     // ------------------------------------------------------------
@@ -1413,17 +1420,35 @@
             processInstance.setWorkingMemory( this );
             processInstance.setProcess( process );
             processInstance.setId( ++processCounter );
+            processInstances.put(new Long(processInstance.getId()), processInstance);
+            getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted(
+                    processInstance, this);
             processInstance.start();
+            getRuleFlowEventSupport().fireAfterRuleFlowProcessStarted(
+                    processInstance, this);
 
-            getRuleFlowEventSupport().fireRuleFlowProcessStarted( processInstance,
-                                                                  this );
-
             return processInstance;
         } else {
             throw new IllegalArgumentException( "Unknown process type: " + process.getClass() );
         }
     }
-
+    
+    public Collection getProcessInstances() {
+    	return Collections.unmodifiableCollection(processInstances.values());
+    }
+    
+    public ProcessInstance getProcessInstance(long id) {
+        return (ProcessInstance) processInstances.get(new Long(id));
+    }
+    
+    public void removeProcessInstance(ProcessInstance processInstance) {
+    	processInstances.remove(processInstance);
+    }
+    
+    public WorkItemManager getWorkItemManager() {
+        return taskInstanceManager;
+    }
+    
     public List iterateObjectsToList() {
         List result = new ArrayList();
         Iterator iterator = iterateObjects();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -9,6 +9,7 @@
 import org.drools.reteoo.LIANodePropagation;
 import org.drools.rule.Rule;
 import org.drools.rule.TimeMachine;
+import org.drools.ruleflow.common.instance.ProcessInstance;
 import org.drools.spi.Activation;
 import org.drools.spi.FactHandleFactory;
 import org.drools.spi.PropagationContext;
@@ -67,4 +68,6 @@
 	public TimeMachine getTimeMachine();
 
 	public void setTimeMachine(TimeMachine tm);
+    
+    public void removeProcessInstance(ProcessInstance processInstance);
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -21,7 +21,6 @@
 import org.drools.spi.Activation;
 import org.drools.util.Iterator;
 import org.drools.util.LinkedList;
-import org.drools.util.LinkedList.LinkedListIterator;
 
 /**
  * Implementation of a <code>RuleFlowGroup</code> that collects activations
@@ -78,6 +77,8 @@
         }
         this.active = active;
         if ( active ) {
+            ((EventSupport) this.workingMemory).getRuleFlowEventSupport()
+                    .fireBeforeRuleFlowGroupActivated(this, this.workingMemory);
             if ( this.list.isEmpty() ) {
                 if ( this.autoDeactivate ) {
                     // if the list of activations is empty and
@@ -88,9 +89,11 @@
             } else {
                 triggerActivations();
             }
-            ((EventSupport) this.workingMemory).getRuleFlowEventSupport().fireRuleFlowGroupActivated( this,
-                                                                                                      this.workingMemory );
+            ((EventSupport) this.workingMemory).getRuleFlowEventSupport()
+                    .fireAfterRuleFlowGroupActivated(this, this.workingMemory);
         } else {
+            ((EventSupport) this.workingMemory).getRuleFlowEventSupport()
+                    .fireBeforeRuleFlowGroupDeactivated(this, this.workingMemory);
             final Iterator it = this.list.iterator();
             for ( RuleFlowGroupNode node = (RuleFlowGroupNode) it.next(); node != null; node = (RuleFlowGroupNode) it.next() ) {
                 final Activation activation = node.getActivation();
@@ -102,8 +105,8 @@
             if ( getProcessInstance() != null ) {
                 triggerCompleted();
             }
-            ((EventSupport) this.workingMemory).getRuleFlowEventSupport().fireRuleFlowGroupDeactivated( this,
-                                                                                                        this.workingMemory );
+            ((EventSupport) this.workingMemory).getRuleFlowEventSupport()
+                    .fireAfterRuleFlowGroupDeactivated(this, this.workingMemory);
         }
     }
 
@@ -191,7 +194,7 @@
         return this.name.hashCode();
     }
 
-    public void trigger(final RuleFlowNodeInstance parent) {
+    public void internalTrigger(final RuleFlowNodeInstance parent) {
         setActive( true );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DebugRuleFlowEventListener.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -6,24 +6,58 @@
     implements
     RuleFlowEventListener {
 
-    public void ruleFlowCompleted(final RuleFlowCompletedEvent event,
-                                  final WorkingMemory workingMemory) {
+    public void beforeRuleFlowCompleted(final RuleFlowCompletedEvent event,
+                                        final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+    public void afterRuleFlowCompleted(final RuleFlowCompletedEvent event,
                                        final WorkingMemory workingMemory) {
+        System.err.println(event);
+    }
+
+    public void beforeRuleFlowGroupActivated(
+            final RuleFlowGroupActivatedEvent event,
+            final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
-                                         final WorkingMemory workingMemory) {
+    public void afterRuleFlowGroupActivated(
+            final RuleFlowGroupActivatedEvent event,
+            final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
-    public void ruleFlowStarted(final RuleFlowStartedEvent event,
-                                final WorkingMemory workingMemory) {
+    public void beforeRuleFlowGroupDeactivated(
+            final RuleFlowGroupDeactivatedEvent event,
+            final WorkingMemory workingMemory) {
         System.err.println( event );
     }
 
+    public void afterRuleFlowGroupDeactivated(
+            final RuleFlowGroupDeactivatedEvent event,
+            final WorkingMemory workingMemory) {
+        System.err.println( event );
+    }
+
+    public void beforeRuleFlowStarted(final RuleFlowStartedEvent event,
+                                      final WorkingMemory workingMemory) {
+        System.err.println( event );
+    }
+
+    public void afterRuleFlowStarted(final RuleFlowStartedEvent event,
+                                     final WorkingMemory workingMemory) {
+        System.err.println(event);
+    }
+
+    public void afterRuleFlowNodeTriggered(final RuleFlowNodeTriggeredEvent event,
+                                           final WorkingMemory workingMemory) {
+        System.err.println(event);
+    }
+
+    public void beforeRuleFlowNodeTriggered(final RuleFlowNodeTriggeredEvent event,
+                                            final WorkingMemory workingMemory) {
+        System.err.println(event);
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/DefaultRuleFlowEventListener.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -6,24 +6,54 @@
     implements
     RuleFlowEventListener {
 
-    public void ruleFlowCompleted(final RuleFlowCompletedEvent event,
-                                  final WorkingMemory workingMemory) {
+    public void beforeRuleFlowCompleted(final RuleFlowCompletedEvent event,
+                                        final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+    public void afterRuleFlowCompleted(final RuleFlowCompletedEvent event,
                                        final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
-                                         final WorkingMemory workingMemory) {
+    public void beforeRuleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+                                             final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
-    public void ruleFlowStarted(final RuleFlowStartedEvent event,
-                                final WorkingMemory workingMemory) {
+    public void afterRuleFlowGroupActivated(final RuleFlowGroupActivatedEvent event,
+                                            final WorkingMemory workingMemory) {
         // intentionally left blank
     }
 
+    public void beforeRuleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
+                                               final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
+    public void afterRuleFlowGroupDeactivated(final RuleFlowGroupDeactivatedEvent event,
+                                              final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleFlowStarted(final RuleFlowStartedEvent event,
+                                      final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
+    public void afterRuleFlowStarted(final RuleFlowStartedEvent event,
+                                     final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
+    public void afterRuleFlowNodeTriggered(final RuleFlowNodeTriggeredEvent event,
+                                           final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
+    public void beforeRuleFlowNodeTriggered(final RuleFlowNodeTriggeredEvent event,
+                                            final WorkingMemory workingMemory) {
+        // intentionally left blank
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventListener.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -27,16 +27,34 @@
     extends
     EventListener {
 
-    void ruleFlowStarted(RuleFlowStartedEvent event,
-                         WorkingMemory workingMemory);
+    void beforeRuleFlowStarted(RuleFlowStartedEvent event,
+                               WorkingMemory workingMemory);
 
-    void ruleFlowCompleted(RuleFlowCompletedEvent event,
-                           WorkingMemory workingMemory);
+    void afterRuleFlowStarted(RuleFlowStartedEvent event,
+                              WorkingMemory workingMemory);
 
-    void ruleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
+    void beforeRuleFlowCompleted(RuleFlowCompletedEvent event,
+                                 WorkingMemory workingMemory);
+
+    void afterRuleFlowCompleted(RuleFlowCompletedEvent event,
                                 WorkingMemory workingMemory);
 
-    void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
-                                  WorkingMemory workingMemory);
+    void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
+                                      WorkingMemory workingMemory);
 
+    void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
+                                     WorkingMemory workingMemory);
+    
+    void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
+                                        WorkingMemory workingMemory);
+
+    void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event,
+                                       WorkingMemory workingMemory);
+
+    void beforeRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+                                     WorkingMemory workingMemory);
+
+    void afterRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+                                    WorkingMemory workingMemory);
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowEventSupport.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.drools.common.InternalWorkingMemory;
+import org.drools.ruleflow.instance.RuleFlowNodeInstance;
 import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 import org.drools.spi.RuleFlowGroup;
 
@@ -60,60 +61,162 @@
         return this.listeners.isEmpty();
     }
 
-    public void fireRuleFlowProcessStarted(final RuleFlowProcessInstance instance,
-                                           final InternalWorkingMemory workingMemory) {
-        if ( this.listeners.isEmpty() ) {
+    public void fireBeforeRuleFlowProcessStarted(
+            final RuleFlowProcessInstance instance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
             return;
         }
 
-        final RuleFlowStartedEvent event = new RuleFlowStartedEvent( instance );
+        final RuleFlowStartedEvent event = new RuleFlowStartedEvent(instance);
 
-        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowStarted( event,
-                                                                               workingMemory );
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .beforeRuleFlowStarted(event, workingMemory);
         }
     }
 
-    public void fireRuleFlowProcessCompleted(final RuleFlowProcessInstance instance,
-                                             final InternalWorkingMemory workingMemory) {
-        if ( this.listeners.isEmpty() ) {
+    public void fireAfterRuleFlowProcessStarted(
+            final RuleFlowProcessInstance instance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
             return;
         }
 
-        final RuleFlowCompletedEvent event = new RuleFlowCompletedEvent( instance );
+        final RuleFlowStartedEvent event = new RuleFlowStartedEvent(instance);
 
-        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowCompleted( event,
-                                                                                 workingMemory );
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .afterRuleFlowStarted(event, workingMemory);
         }
     }
 
-    public void fireRuleFlowGroupActivated(final RuleFlowGroup ruleFlowGroup,
-                                           final InternalWorkingMemory workingMemory) {
-        if ( this.listeners.isEmpty() ) {
+    public void fireBeforeRuleFlowProcessCompleted(
+            final RuleFlowProcessInstance instance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
             return;
         }
 
-        final RuleFlowGroupActivatedEvent event = new RuleFlowGroupActivatedEvent( ruleFlowGroup );
+        final RuleFlowCompletedEvent event = new RuleFlowCompletedEvent(
+                instance);
 
-        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowGroupActivated( event,
-                                                                                      workingMemory );
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .beforeRuleFlowCompleted(event, workingMemory);
         }
     }
 
-    public void fireRuleFlowGroupDeactivated(final RuleFlowGroup ruleFlowGroup,
-                                             final InternalWorkingMemory workingMemory) {
-        if ( this.listeners.isEmpty() ) {
+    public void fireAfterRuleFlowProcessCompleted(
+            final RuleFlowProcessInstance instance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
             return;
         }
 
-        final RuleFlowGroupDeactivatedEvent event = new RuleFlowGroupDeactivatedEvent( ruleFlowGroup );
+        final RuleFlowCompletedEvent event = new RuleFlowCompletedEvent(
+                instance);
 
-        for ( int i = 0, size = this.listeners.size(); i < size; i++ ) {
-            ((RuleFlowEventListener) this.listeners.get( i )).ruleFlowGroupDeactivated( event,
-                                                                                        workingMemory );
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .afterRuleFlowCompleted(event, workingMemory);
         }
     }
 
+    public void fireBeforeRuleFlowGroupActivated(
+            final RuleFlowGroup ruleFlowGroup,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowGroupActivatedEvent event = new RuleFlowGroupActivatedEvent(
+                ruleFlowGroup);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .beforeRuleFlowGroupActivated(event, workingMemory);
+        }
+    }
+
+    public void fireAfterRuleFlowGroupActivated(
+            final RuleFlowGroup ruleFlowGroup,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowGroupActivatedEvent event = new RuleFlowGroupActivatedEvent(
+                ruleFlowGroup);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .afterRuleFlowGroupActivated(event, workingMemory);
+        }
+    }
+
+    public void fireBeforeRuleFlowGroupDeactivated(
+            final RuleFlowGroup ruleFlowGroup,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowGroupDeactivatedEvent event = new RuleFlowGroupDeactivatedEvent(
+                ruleFlowGroup);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .beforeRuleFlowGroupDeactivated(event, workingMemory);
+        }
+    }
+
+    public void fireAfterRuleFlowGroupDeactivated(
+            final RuleFlowGroup ruleFlowGroup,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowGroupDeactivatedEvent event = new RuleFlowGroupDeactivatedEvent(
+                ruleFlowGroup);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .afterRuleFlowGroupDeactivated(event, workingMemory);
+        }
+    }
+
+    public void fireBeforeRuleFlowNodeTriggered(
+            final RuleFlowNodeInstance ruleFlowNodeInstance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowNodeTriggeredEvent event = new RuleFlowNodeTriggeredEvent(
+                ruleFlowNodeInstance);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .beforeRuleFlowNodeTriggered(event, workingMemory);
+        }
+    }
+
+    public void fireAfterRuleFlowNodeTriggered(
+            final RuleFlowNodeInstance ruleFlowNodeInstance,
+            final InternalWorkingMemory workingMemory) {
+        if (this.listeners.isEmpty()) {
+            return;
+        }
+
+        final RuleFlowNodeTriggeredEvent event = new RuleFlowNodeTriggeredEvent(
+                ruleFlowNodeInstance);
+
+        for (int i = 0, size = this.listeners.size(); i < size; i++) {
+            ((RuleFlowEventListener) this.listeners.get(i))
+                    .afterRuleFlowNodeTriggered(event, workingMemory);
+        }
+    }
+
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowNodeTriggeredEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowNodeTriggeredEvent.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/event/RuleFlowNodeTriggeredEvent.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,43 @@
+package org.drools.event;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.drools.ruleflow.instance.RuleFlowNodeInstance;
+
+/**
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowNodeTriggeredEvent extends RuleFlowEvent {
+
+    private static final long serialVersionUID = 400L;
+    
+    private RuleFlowNodeInstance nodeInstance;
+
+    public RuleFlowNodeTriggeredEvent(final RuleFlowNodeInstance nodeInstance) {
+        super( nodeInstance.getProcessInstance() );
+        this.nodeInstance = nodeInstance;
+    }
+    
+    public RuleFlowNodeInstance getRuleFlowNodeInstance() {
+        return nodeInstance;
+    }
+
+    public String toString() {
+        return "==>[RuleFlowNodeTriggered(nodeId=" + nodeInstance.getNodeId() + "; id=" + nodeInstance.getId() 
+            + "; processName=" + getRuleFlowProcessInstance().getRuleFlowProcess().getName() + "; processId=" + getRuleFlowProcessInstance().getRuleFlowProcess().getId() + ")]";
+    }
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/ParameterDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/ParameterDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/ParameterDefinition.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,13 @@
+package org.drools.ruleflow.common.core;
+
+import org.drools.ruleflow.common.datatype.DataType;
+
+public interface ParameterDefinition {
+    
+    String getName();
+    void setName(String name);
+    
+    DataType getType();
+    void setType(DataType type);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/Work.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/Work.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/Work.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,15 @@
+package org.drools.ruleflow.common.core;
+
+import java.util.Map;
+
+public interface Work {
+
+    void setName(String name);
+    String getName();
+    
+    void setParameter(String name, Object value);
+    void setParameters(Map parameters);
+    Object getParameter(String name);
+    Map getParameters();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinition.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,24 @@
+package org.drools.ruleflow.common.core;
+
+import java.util.Set;
+
+public interface WorkDefinition {
+    
+    String getName();
+//    void setName(String name);
+    
+    Set getParameters();
+//    void setParameters(Set parameters);
+//    void addParameter(ParameterDefinition parameter);
+//    void removeParameter(String name);
+    String[] getParameterNames();
+    ParameterDefinition getParameter(String name);
+    
+    Set getResults();
+//    void setResults(Set results);
+//    void addResult(ParameterDefinition result);
+//    void removeResult(String name);
+    String[] getResultNames();
+    ParameterDefinition getResult(String name);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinitionExtension.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinitionExtension.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/WorkDefinitionExtension.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,11 @@
+package org.drools.ruleflow.common.core;
+
+public interface WorkDefinitionExtension {
+    
+    String getDisplayName();
+    
+    String getExplanationText();
+    
+    String getIcon();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/ParameterDefinitionImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/ParameterDefinitionImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/ParameterDefinitionImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,45 @@
+package org.drools.ruleflow.common.core.impl;
+
+import java.io.Serializable;
+
+import org.drools.ruleflow.common.core.ParameterDefinition;
+import org.drools.ruleflow.common.datatype.DataType;
+
+public class ParameterDefinitionImpl implements ParameterDefinition, Serializable {
+   
+    private static final long serialVersionUID = 3977297720245237814L;
+   
+    private String name;
+    private DataType type;
+    
+    public ParameterDefinitionImpl(String name, DataType type) {
+        setName(name);
+        setType(type);
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Name cannot be null");
+        }
+        this.name = name;
+    }
+    
+    public DataType getType() {
+        return type;
+    }
+    
+    public void setType(DataType type) {
+        if (type == null) {
+            throw new IllegalArgumentException("Data type cannot be null");
+        }
+        this.type = type;
+    }
+    
+    public String toString() {
+        return name;
+    }
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionExtensionImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionExtensionImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionExtensionImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,35 @@
+package org.drools.ruleflow.common.core.impl;
+
+import org.drools.ruleflow.common.core.WorkDefinitionExtension;
+
+public class WorkDefinitionExtensionImpl extends WorkDefinitionImpl implements WorkDefinitionExtension {
+    
+    private String displayName;
+    private String explanationText;
+    private String icon;
+    
+    public String getDisplayName() {
+        return displayName;
+    }
+    
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getExplanationText() {
+        return explanationText;
+    }
+    
+    public void setExplanationText(String explanationText) {
+        this.explanationText = explanationText;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+    
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkDefinitionImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,87 @@
+package org.drools.ruleflow.common.core.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.ruleflow.common.core.ParameterDefinition;
+import org.drools.ruleflow.common.core.WorkDefinition;
+
+public class WorkDefinitionImpl implements WorkDefinition {
+    
+    private static final long serialVersionUID = 3977861786923710777L;
+    
+    private String name;
+    private Map parameters = new HashMap();
+    private Map results = new HashMap();
+
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public Set getParameters() {
+    	return new HashSet(parameters.values());        
+    }
+    
+    public void setParameters(Set parameters) {
+        this.parameters.clear();
+        Iterator iterator = parameters.iterator();
+        while (iterator.hasNext()) {
+        	addParameter((ParameterDefinition) iterator.next());
+        }        
+    }
+    
+    public void addParameter(ParameterDefinition parameter) {
+    	parameters.put(parameter.getName(), parameter);
+    }
+    
+    public void removeParameter(String name) {
+        parameters.remove(name);
+    }
+    
+    public String[] getParameterNames() {
+        return (String[]) parameters.keySet().toArray(new String[parameters.size()]);
+    }
+    
+    public ParameterDefinition getParameter(String name) {
+        return (ParameterDefinition) parameters.get(name);
+    }
+    
+    public Set getResults() {
+    	return new HashSet(results.values());
+    }
+    
+    public void setResults(Set results) {
+    	this.results.clear();
+        Iterator it = results.iterator();
+        while (it.hasNext()) {
+        	addResult((ParameterDefinition) it.next());
+        }   
+    }
+    
+    public void addResult(ParameterDefinition result) {
+        results.put(result.getName(), result);
+    }
+    
+    public void removeResult(String name) {
+        results.remove(name);
+    }
+    
+    public String[] getResultNames() {
+        return (String[]) results.keySet().toArray(new String[results.size()]);
+    }
+    
+    public ParameterDefinition getResult(String name) {
+        return (ParameterDefinition) results.get(name);
+    }
+    
+    public String toString() {
+        return name;
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/WorkImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,50 @@
+package org.drools.ruleflow.common.core.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.ruleflow.common.core.Work;
+
+public class WorkImpl implements Work {
+    
+    private String name;
+    private Map parameters = new HashMap();
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setParameter(String name, Object value) {
+    	if (name == null) {
+    		throw new NullPointerException("Parameter name is null");
+    	}
+		parameters.put(name, value);
+    }
+    
+    public void setParameters(Map parameters) {
+        if (parameters == null) {
+            throw new NullPointerException();
+        }
+        this.parameters = new HashMap(parameters);
+    }
+    
+    public Object getParameter(String name) {
+        if (name == null) {
+            throw new NullPointerException("Parameter name is null");
+        }
+        return parameters.get(name);
+    }
+    
+    public Map getParameters() {
+        return Collections.unmodifiableMap(parameters);
+    }
+    
+    public String toString() {
+        return "Task " + name;
+    }
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/ProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/ProcessInstance.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/ProcessInstance.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -48,5 +48,9 @@
     void setState(int state);
 
     int getState();
+    
+    void taskCompleted(WorkItem taskInstance);
+    
+    void taskAborted(WorkItem taskInstance);
 
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItem.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItem.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,33 @@
+package org.drools.ruleflow.common.instance;
+
+import java.util.Map;
+
+public interface WorkItem {
+	
+	int PENDING = 0;
+	int ACTIVE = 1;
+	int COMPLETED = 2;
+	int ABORTED = 3;
+
+    //void setId(long id);
+    long getId();
+    
+    //void setName(String name);
+    String getName();
+    
+    //void setState(int state);
+    int getState();
+    
+    //void setParameters(Map parameters);
+    Object getParameter(String name);
+    Map getParameters();
+    
+    //void setResults(Map results);
+    //void setResult(String name, Object value);
+    Object getResult(String name);
+    Map getResults();
+
+    //void setProcessInstanceId(long processInstanceId);
+    long getProcessInstanceId();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemHandler.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,9 @@
+package org.drools.ruleflow.common.instance;
+
+public interface WorkItemHandler {
+    
+    void executeWorkItem(WorkItem workItem, WorkItemManager manager);
+    
+    void abortWorkItem(WorkItem workItem, WorkItemManager manager);
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/WorkItemManager.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,74 @@
+package org.drools.ruleflow.common.instance;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.WorkingMemory;
+import org.drools.ruleflow.common.instance.impl.WorkItemImpl;
+
+public class WorkItemManager {
+
+	private long taskInstanceCounter; 
+	private Map taskInstances = new HashMap();
+	private WorkingMemory workingMemory;
+	private Map taskInstanceHandlers = new HashMap();
+	
+	public WorkItemManager(WorkingMemory workingMemory) {
+	    this.workingMemory = workingMemory;
+	}
+	
+	public void executeWorkItem(WorkItem workItem) {
+	    ((WorkItemImpl) workItem).setId(++taskInstanceCounter);
+	    taskInstances.put(new Long(workItem.getId()), workItem);
+	    WorkItemHandler handler = (WorkItemHandler) this.taskInstanceHandlers.get(workItem.getName());
+	    if (handler != null) {
+	        handler.executeWorkItem(workItem, this);
+	    } else {
+	        System.err.println("Could not find work item handler for " + workItem.getName());
+	    }
+	}
+	
+	public Set getWorkItems() {
+	    return Collections.unmodifiableSet(taskInstances.entrySet());
+	}
+	
+    public void completeWorkItem(long id, Map results) {
+        WorkItemImpl taskInstance = (WorkItemImpl) taskInstances.get(new Long(id));
+        if (taskInstance == null) {
+            throw new IllegalArgumentException(
+                "Could not find task instance with id " + id);
+        }
+        taskInstance.setResults(results);
+        ProcessInstance processInstance = workingMemory.getProcessInstance(taskInstance.getProcessInstanceId());
+        if (processInstance == null) {
+            throw new IllegalArgumentException(
+                "Could not find processInstance with id " + taskInstance.getProcessInstanceId());
+        }
+        taskInstance.setState(WorkItem.COMPLETED);
+        processInstance.taskCompleted(taskInstance);
+        taskInstances.remove(new Long(id));
+    }
+    
+    public void abortWorkItem(long id) {
+        WorkItemImpl taskInstance = (WorkItemImpl) taskInstances.get(new Long(id));
+        if (taskInstance == null) {
+            throw new IllegalArgumentException(
+                "Could not find task instance with id " + id);
+        }
+        ProcessInstance processInstance = workingMemory.getProcessInstance(taskInstance.getProcessInstanceId());
+        if (processInstance == null) {
+            throw new IllegalArgumentException(
+                "Could not find processInstance with id " + taskInstance.getProcessInstanceId());
+        }
+        taskInstance.setState(WorkItem.ABORTED);
+        processInstance.taskAborted(taskInstance);
+        taskInstances.remove(new Long(id));
+    }
+    
+    public void registerWorkItemHandler(String workItemName, WorkItemHandler handler) {
+        this.taskInstanceHandlers.put(workItemName, handler);
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -17,6 +17,7 @@
  */
 
 import org.drools.ruleflow.common.core.Process;
+import org.drools.ruleflow.common.instance.WorkItem;
 
 /**
  * Default implementation of a process instance.
@@ -54,7 +55,13 @@
     public int getState() {
         return this.state;
     }
+    
+    public void taskCompleted(WorkItem taskInstance) {
+    }
 
+    public void taskAborted(WorkItem taskInstance) {
+    }
+
     public String toString() {
         final StringBuffer b = new StringBuffer( "ProcessInstance " );
         b.append( getId() );

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/SystemOutWorkItemHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/SystemOutWorkItemHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/SystemOutWorkItemHandler.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,19 @@
+package org.drools.ruleflow.common.instance.impl;
+
+import org.drools.ruleflow.common.instance.WorkItem;
+import org.drools.ruleflow.common.instance.WorkItemHandler;
+import org.drools.ruleflow.common.instance.WorkItemManager;
+
+public class SystemOutWorkItemHandler implements WorkItemHandler {
+
+    public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+        System.out.println("Executing work item " + workItem);
+        manager.completeWorkItem(workItem.getId(), null);
+    }
+
+    public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+        System.out.println("Aborting work item " + workItem);
+        manager.abortWorkItem(workItem.getId());
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandler.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,164 @@
+package org.drools.ruleflow.common.instance.impl;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListSelectionModel;
+import javax.swing.WindowConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.drools.ruleflow.common.instance.WorkItem;
+import org.drools.ruleflow.common.instance.WorkItemHandler;
+import org.drools.ruleflow.common.instance.WorkItemManager;
+
+public class UIWorkItemHandler extends JFrame implements WorkItemHandler {
+
+    private Map taskInstances = new HashMap();
+    private JList taskInstancesList;
+    private JButton selectButton;
+    
+    public UIWorkItemHandler() {
+        setSize(new Dimension(400, 300));
+        setTitle("Work Items");
+        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        initializeComponent();
+    }
+    
+    private void initializeComponent() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new GridBagLayout());
+        getRootPane().setLayout(new BorderLayout());
+        getRootPane().add(panel, BorderLayout.CENTER);
+        
+        taskInstancesList = new JList();
+        taskInstancesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        taskInstancesList.addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() == 2) {
+                    select();
+                }
+            }
+        });
+        taskInstancesList.addListSelectionListener(new ListSelectionListener() {
+            public void valueChanged(ListSelectionEvent e) {
+                selectButton.setEnabled(getSelectedTaskInstance() != null);
+            }
+        });
+        reloadTaskInstancesList();
+        GridBagConstraints c = new GridBagConstraints();
+        c.weightx = 1;
+        c.weighty = 1;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(taskInstancesList, c);
+        
+        selectButton = new JButton("Select");
+        selectButton.setEnabled(false);
+        selectButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                select();
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.weightx = 1;
+        c.anchor = GridBagConstraints.EAST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(selectButton, c);
+    }
+    
+    private void select() {
+        WorkItem taskInstance = getSelectedTaskInstance();
+        if (taskInstance != null) {
+            UIWorkItemHandlerDialog dialog = new UIWorkItemHandlerDialog(UIWorkItemHandler.this, taskInstance);
+            dialog.setVisible(true);
+        }
+    }
+    
+    public WorkItem getSelectedTaskInstance() {
+        int index = taskInstancesList.getSelectedIndex();
+        if (index != -1) {
+            Object selected = taskInstancesList.getModel().getElementAt(index);
+            if (selected instanceof TaskInstanceWrapper) {
+                return ((TaskInstanceWrapper) selected).getTaskInstance();
+            }
+        }
+        return null;
+    }
+    
+    private void reloadTaskInstancesList() {
+        List result = new ArrayList();
+        for (Iterator iterator = taskInstances.keySet().iterator(); iterator.hasNext(); ) {
+            WorkItem taskInstance = (WorkItem) iterator.next();
+            result.add(new TaskInstanceWrapper(taskInstance));
+        }
+        taskInstancesList.setListData(result.toArray());
+    }
+    
+    public void complete(WorkItem taskInstance, Map results) {
+        WorkItemManager manager = (WorkItemManager) taskInstances.get(taskInstance);
+        if (manager != null) {
+            manager.completeWorkItem(taskInstance.getId(), results);
+            taskInstances.remove(taskInstance);
+            reloadTaskInstancesList();
+        }
+        selectButton.setEnabled(getSelectedTaskInstance() != null);
+    }
+    
+    public void abort(WorkItem taskInstance) {
+        WorkItemManager manager = (WorkItemManager) taskInstances.get(taskInstance);
+        if (manager != null) {
+            manager.abortWorkItem(taskInstance.getId());
+            taskInstances.remove(taskInstance);
+            reloadTaskInstancesList();
+        }
+        selectButton.setEnabled(getSelectedTaskInstance() != null);
+    }
+    
+    public void abortWorkItem(WorkItem taskInstance,
+            WorkItemManager manager) {
+        taskInstances.remove(taskInstance);
+        reloadTaskInstancesList();
+    }
+
+    public void executeWorkItem(WorkItem taskInstance,
+            WorkItemManager manager) {
+        taskInstances.put(taskInstance, manager);
+        reloadTaskInstancesList();
+    }
+
+    private class TaskInstanceWrapper {
+        
+        private WorkItem taskInstance;
+        
+        public TaskInstanceWrapper(WorkItem taskInstance) {
+            this.taskInstance = taskInstance;
+        }
+        
+        public WorkItem getTaskInstance() {
+            return taskInstance;
+        }
+        
+        public String toString() {
+            return taskInstance.getName() + " [" + taskInstance.getId() + "]";
+        }
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandlerDialog.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandlerDialog.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/UIWorkItemHandlerDialog.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,98 @@
+package org.drools.ruleflow.common.instance.impl;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import org.drools.ruleflow.common.instance.WorkItem;
+
+public class UIWorkItemHandlerDialog extends JDialog {
+    
+    private UIWorkItemHandler handler;
+    private WorkItem taskInstance;
+    private JButton completeButton;
+    private JButton abortButton;
+    
+    public UIWorkItemHandlerDialog(UIWorkItemHandler handler, WorkItem taskInstance) {
+        super(handler, "Execute Work Item", true);
+        this.handler = handler;
+        this.taskInstance = taskInstance;
+        setSize(new Dimension(400, 300));
+        initializeComponent();
+    }
+
+    private void initializeComponent() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new GridBagLayout());
+        getRootPane().setLayout(new BorderLayout());
+        getRootPane().add(panel, BorderLayout.CENTER);
+        
+        JTextArea params = new JTextArea();
+        params.setText(getParameters());
+        params.setEditable(false);
+        GridBagConstraints c = new GridBagConstraints();
+        c.weightx = 1;
+        c.weighty = 1;
+        c.gridwidth = 2;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(params, c);
+        
+        completeButton = new JButton("Complete");
+        completeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                complete();
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.weightx = 1;
+        c.anchor = GridBagConstraints.EAST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(completeButton, c);
+
+        abortButton = new JButton("Abort");
+        abortButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                abort();
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridx = 1;
+        c.gridy = 1;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(abortButton, c);
+    }
+    
+    private String getParameters() {
+        String result = "";
+        if (taskInstance.getParameters() != null) {
+            for (Iterator iterator = taskInstance.getParameters().entrySet().iterator(); iterator.hasNext(); ) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                result += entry.getKey() + " = " + entry.getValue() + "\n";
+            }
+        }
+        return result;
+    }
+    
+    private void complete() {
+        handler.complete(taskInstance, null);
+        dispose();
+    }
+    
+    private void abort() {
+        handler.abort(taskInstance);
+        dispose();
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/WorkItemImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/WorkItemImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/WorkItemImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,100 @@
+package org.drools.ruleflow.common.instance.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.drools.ruleflow.common.instance.WorkItem;
+
+public class WorkItemImpl implements WorkItem {
+
+	private long id;
+    private String name;
+    private int state = 0;
+    private Map parameters = new HashMap();
+    private Map results = new HashMap();
+    private long processInstanceId;
+    
+    public void setId(long id) {
+        this.id = id;
+    }
+    
+    public long getId() {
+        return id;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setState(int state) {
+        this.state = state;
+    }
+    
+    public int getState() {
+        return state;
+    }
+    
+    public void setParameters(Map parameters) {
+        this.parameters = parameters;
+    }
+    
+    public Object getParameter(String name) {
+        return parameters.get(name);
+    }
+    
+    public Map getParameters() {
+        return parameters;
+    }
+    
+    public void setResults(Map results) {
+        this.results = results;
+    }
+    
+    public void setResult(String name, Object value) {
+        results.put(name, value);
+    }
+    
+    public Object getResult(String name) {
+        return results.get(name);
+    }
+    
+    public Map getResults() {
+        return results;
+    }
+    
+    public void setProcessInstanceId(long processInstanceId) {
+        this.processInstanceId = processInstanceId;
+    }
+    
+    public long getProcessInstanceId() {
+        return processInstanceId;
+    }
+    
+    public String toString() {
+    	StringBuilder b = new StringBuilder("WorkItem ");
+    	b.append(id);
+    	b.append(" [name=");
+    	b.append(name);
+    	b.append(", state=");
+    	b.append(state);
+    	b.append(", processInstanceId=");
+    	b.append(processInstanceId);
+        b.append(", parameters{");
+    	for (Iterator iterator = parameters.entrySet().iterator(); iterator.hasNext(); ) {
+    	    Map.Entry entry = (Map.Entry) iterator.next();
+    	    b.append(entry.getKey());
+    	    b.append("=");
+    	    b.append(entry.getValue());
+    	    if (iterator.hasNext()) {
+    	        b.append(", ");
+    	    }
+    	}
+        b.append("}]");
+    	return b.toString();
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/Join.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/Join.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/Join.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -29,17 +29,24 @@
     extends
     Node {
 
-    int TYPE_UNDEFINED = 0;
+    int TYPE_UNDEFINED     = 0;
     /**
      * The outgoing connection of a join of this type is triggered
      * when all its incoming connections have been triggered.
      */
-    int TYPE_AND       = 1;
+    int TYPE_AND           = 1;
     /**
      * The outgoing connection of a join of this type is triggered
      * when one of its incoming connections has been triggered.
      */
-    int TYPE_XOR       = 2;
+    int TYPE_XOR           = 2;
+    /**
+     * The outgoing connection of a join of this type is triggered
+     * when one of its incoming connections has been triggered. It then
+     * waits until all other incoming connections have been triggered
+     * before allowing 
+     */
+    int TYPE_DISCRIMINATOR = 3;
 
     /**
      * Sets the type of the join.

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcessValidationError.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcessValidationError.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcessValidationError.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -52,6 +52,10 @@
     String ACTION_NODE_WITHOUT_OUTGOING_CONNECTIONS     = "Action node has no outgoing connection.";
     String ACTION_NODE_WITHOUT_ACTION                   = "An Action node has no action.";
     String ACTION_NODE_WITH_INVALID_ACTION              = "An Action node has an invalid action.";
+    String TASK_NODE_WITHOUT_INCOMING_CONNECTIONS       = "Task node has no incoming connection.";
+    String TASK_NODE_WITHOUT_OUTGOING_CONNECTIONS       = "Task node has no outgoing connection.";
+    String TASK_NODE_WITHOUT_TASK                       = "A Task node has no task.";
+    String TASK_NODE_WITH_INVALID_TASK                  = "A Task node has an invalid task.";
 
     String getType();
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/SubFlowNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/SubFlowNode.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/SubFlowNode.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -53,4 +53,22 @@
      * @param processId	The process id of the SubFlowNode
      */
     void setProcessId(String processId);
+    
+    /**
+     * Sets whether this node should wait until the sub-flow has been
+     * completed.
+     * 
+     * @param waitForCompletion  whether this node should wait until the sub-flow has been completed
+     */
+    void setWaitForCompletion(boolean waitForCompletion);
+
+    /**
+     * Returns whether this node should wait until the sub-flow has been
+     * completed.
+     * 
+     * @return whether this node should wait until the sub-flow has been
+     * completed.
+     */
+    boolean isWaitForCompletion();
+
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/WorkItemNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/WorkItemNode.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/WorkItemNode.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,57 @@
+package org.drools.ruleflow.core;
+
+import org.drools.ruleflow.common.core.Work;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Represents a task in a RuleFlow.
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface WorkItemNode
+    extends
+    Node {
+
+    /**
+     * Returns the incoming connection of the TaskNode.
+     * 
+     * @return the incoming connection of the TaskNode.
+     */
+    Connection getFrom();
+
+    /**
+     * Returns the outgoing connection of the TaskNode.
+     * 
+     * @return the outgoing connection of the TaskNode.
+     */
+    Connection getTo();
+
+    /**
+     * Returns the work of the WorkItemNode.
+     * 
+     * @return the work of the WorkItemNode.
+     */
+    Work getWork();
+
+    /**
+     * Sets the work of the WorkItemNode.
+     * 
+     * @param constraint	The work of the WorkItemNode
+     */
+    void setWork(Work work);
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/DroolsConsequenceAction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/DroolsConsequenceAction.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/DroolsConsequenceAction.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -4,13 +4,13 @@
 
 public class DroolsConsequenceAction implements Serializable {
 	
-	/**
-     * 
-     */
     private static final long serialVersionUID = 400L;
+    
+    private String dialect = "mvel";
     private String consequence;
 	
-	public DroolsConsequenceAction(String consequence) {
+	public DroolsConsequenceAction(String dialect, String consequence) {
+	    this.dialect = dialect;
 		this.consequence = consequence;
 	}
 	
@@ -21,6 +21,14 @@
 	public String getConsequence() {
 		return consequence;
 	}
+	
+	public void setDialect(String dialect) {
+	    this.dialect = dialect;
+	}
+	
+	public String getDialect() {
+	    return dialect;
+	}
 
 	public String toString() {
 		return consequence;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidatorImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidatorImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidatorImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -22,6 +22,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.drools.ruleflow.common.core.Work;
 import org.drools.ruleflow.core.ActionNode;
 import org.drools.ruleflow.core.Connection;
 import org.drools.ruleflow.core.EndNode;
@@ -35,6 +36,7 @@
 import org.drools.ruleflow.core.Split;
 import org.drools.ruleflow.core.StartNode;
 import org.drools.ruleflow.core.SubFlowNode;
+import org.drools.ruleflow.core.WorkItemNode;
 import org.drools.ruleflow.core.Variable;
 import org.mvel.ExpressionCompiler;
 import org.mvel.ParserContext;
@@ -201,7 +203,24 @@
                 		}
                 	}
                 }
-            }
+            } else if ( node instanceof WorkItemNode ) {
+                final WorkItemNode taskNode = (WorkItemNode) node;
+                if ( taskNode.getFrom() == null ) {
+                    errors.add( new RuleFlowProcessValidationErrorImpl( RuleFlowProcessValidationError.TASK_NODE_WITHOUT_INCOMING_CONNECTIONS, "name = " + taskNode.getName() ) );
+                }
+
+                if ( taskNode.getTo() == null ) {
+                    errors.add( new RuleFlowProcessValidationErrorImpl( RuleFlowProcessValidationError.TASK_NODE_WITHOUT_OUTGOING_CONNECTIONS, "name = " + taskNode.getName() ) );
+                }
+                if ( taskNode.getWork() == null ) {
+                   errors.add( new RuleFlowProcessValidationErrorImpl( RuleFlowProcessValidationError.TASK_NODE_WITHOUT_TASK, "name = " + taskNode.getName() ) );
+                } else {
+                    Work task = taskNode.getWork();
+                    if (task.getName() == null) {
+                        errors.add( new RuleFlowProcessValidationErrorImpl( RuleFlowProcessValidationError.TASK_NODE_WITH_INVALID_TASK, "name = " + taskNode.getName() ) );
+                    }
+                }
+            } 
         }
         if ( !startNodeFound ) {
             errors.add( new RuleFlowProcessValidationErrorImpl( RuleFlowProcessValidationError.NO_START_NODE ) );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/SubFlowNodeImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/SubFlowNodeImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/SubFlowNodeImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -34,6 +34,7 @@
 	private static final long serialVersionUID = 400L;
 	
 	private String            processId;
+	private boolean           waitForCompletion = true;
 
     public void setProcessId(final String processId) {
         this.processId = processId;
@@ -76,4 +77,12 @@
         }
     }
 
+    public boolean isWaitForCompletion() {
+        return waitForCompletion;
+    }
+
+    public void setWaitForCompletion(boolean waitForCompletion) {
+        this.waitForCompletion = waitForCompletion;
+    }
+
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/WorkItemNodeImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/WorkItemNodeImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/WorkItemNodeImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,80 @@
+package org.drools.ruleflow.core.impl;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.ruleflow.common.core.Work;
+import org.drools.ruleflow.core.Connection;
+import org.drools.ruleflow.core.WorkItemNode;
+
+/**
+ * Default implementation of a task node.
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class WorkItemNodeImpl extends NodeImpl
+    implements
+    WorkItemNode {
+
+	private static final long serialVersionUID = -2899376492708393815L;
+	
+	private Work task;
+
+	public Work getWork() {
+		return task;
+	}
+
+	public void setWork(Work task) {
+		this.task = task;
+	}
+
+    public Connection getFrom() {
+        final List list = getIncomingConnections();
+        if ( list.size() > 0 ) {
+            return (Connection) list.get( 0 );
+        }
+        return null;
+    }
+
+    public Connection getTo() {
+        final List list = getOutgoingConnections();
+        if ( list.size() > 0 ) {
+            return (Connection) list.get( 0 );
+        }
+        return null;
+    }
+
+    protected void validateAddIncomingConnection(final Connection connection) {
+        super.validateAddIncomingConnection( connection );
+        if ( getIncomingConnections().size() > 0 ) {
+            throw new IllegalArgumentException( "An ActionNode cannot have more than one incoming node" );
+        }
+    }
+
+    protected void validateAddOutgoingConnection(final Connection connection) {
+        super.validateAddOutgoingConnection( connection );
+        for ( final Iterator it = getOutgoingConnections().iterator(); it.hasNext(); ) {
+            final Connection conn = (Connection) it.next();
+            if ( conn.getType() == connection.getType() ) {
+                throw new IllegalArgumentException( "An ActionNode can have at most one outgoing node" );
+            }
+        }
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/ActionNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/ActionNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/ActionNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -48,7 +48,7 @@
         return (ActionNode) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
 		Object action = getActionNode().getAction();
 		if (action instanceof DroolsConsequenceAction) {
 			String actionString = ((DroolsConsequenceAction) action).getConsequence();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -26,7 +26,7 @@
  */
 public class EndNodeInstanceImpl extends RuleFlowNodeInstanceImpl {
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
         getProcessInstance().setState( ProcessInstance.STATE_COMPLETED );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/MilestoneNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/MilestoneNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/MilestoneNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -35,7 +35,7 @@
         return (MilestoneNode) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
     	RuleFlowGroup systemRuleFlowGroup = getProcessInstance().getAgenda().getRuleFlowGroup("DROOLS_SYSTEM");
     	String rule = "RuleFlow-Milestone-" + getProcessInstance().getProcess().getId()
     		+ "-" + getNode().getId();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -30,9 +30,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class RuleFlowJoinInstanceImpl extends RuleFlowNodeInstanceImpl
-    implements
-    RuleFlowNodeInstance {
+public class RuleFlowJoinInstanceImpl extends RuleFlowNodeInstanceImpl {
 
     private final Map triggers = new HashMap();
 
@@ -40,15 +38,15 @@
         return (Join) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
         final Join join = getJoinNode();
         switch ( join.getType() ) {
             case Join.TYPE_XOR :
                 triggerCompleted();
                 break;
             case Join.TYPE_AND :
-                final Node node = getProcessInstance().getRuleFlowProcess().getNode( from.getNodeId() );
-                final Integer count = (Integer) this.triggers.get( node );
+                Node node = getProcessInstance().getRuleFlowProcess().getNode( from.getNodeId() );
+                Integer count = (Integer) this.triggers.get( node );
                 if ( count == null ) {
                     this.triggers.put( node,
                                        new Integer( 1 ) );
@@ -56,22 +54,40 @@
                     this.triggers.put( node,
                                        new Integer( count.intValue() + 1 ) );
                 }
-                checkActivation();
+                if (checkAllActivated()) {
+                    decreaseAllTriggers();
+                    triggerCompleted();
+                }
                 break;
+            case Join.TYPE_DISCRIMINATOR :
+                boolean triggerCompleted = triggers.isEmpty();
+                node = getProcessInstance().getRuleFlowProcess().getNode( from.getNodeId() );
+                triggers.put( node, new Integer( 1 ) );
+                if (checkAllActivated()) {
+                    resetAllTriggers();
+                }
+                if (triggerCompleted) {
+                    triggerCompleted();
+                }
+                break;
             default :
                 throw new IllegalArgumentException( "Illegal join type " + join.getType() );
         }
     }
 
-    private void checkActivation() {
+    private boolean checkAllActivated() {
         // check whether all parent nodes have been triggered 
         for ( final Iterator it = getJoinNode().getIncomingConnections().iterator(); it.hasNext(); ) {
             final Connection connection = (Connection) it.next();
             if ( this.triggers.get( connection.getFrom() ) == null ) {
-                return;
+                return false;
             }
         }
-        // if true, decrease trigger count for all parents and trigger children
+        return true;
+    }
+    
+    private void decreaseAllTriggers() {
+        // decrease trigger count for all incoming connections
         for ( final Iterator it = getJoinNode().getIncomingConnections().iterator(); it.hasNext(); ) {
             final Connection connection = (Connection) it.next();
             final Integer count = (Integer) this.triggers.get( connection.getFrom() );
@@ -82,9 +98,12 @@
                                    new Integer( count.intValue() - 1 ) );
             }
         }
-        triggerCompleted();
     }
 
+    private void resetAllTriggers() {
+        triggers.clear();
+    }
+
     public void triggerCompleted() {
         getProcessInstance().getNodeInstance( getJoinNode().getTo().getTo() ).trigger( this );
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import org.drools.common.EventSupport;
+import org.drools.common.InternalWorkingMemory;
 import org.drools.ruleflow.core.Node;
 import org.drools.ruleflow.instance.RuleFlowNodeInstance;
 import org.drools.ruleflow.instance.RuleFlowProcessInstance;
@@ -64,5 +66,13 @@
     public void cancel() {
     	getProcessInstance().removeNodeInstance(this);
     }
+    
+    public final void trigger(RuleFlowNodeInstance from) {
+        ((EventSupport) getProcessInstance().getWorkingMemory()).getRuleFlowEventSupport().fireBeforeRuleFlowNodeTriggered(this, (InternalWorkingMemory) getProcessInstance().getWorkingMemory());
+        internalTrigger(from);
+        ((EventSupport) getProcessInstance().getWorkingMemory()).getRuleFlowEventSupport().fireAfterRuleFlowNodeTriggered(this, (InternalWorkingMemory) getProcessInstance().getWorkingMemory());
+    }
+    
+    public abstract void internalTrigger(RuleFlowNodeInstance from);
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -37,7 +37,9 @@
 import org.drools.event.RuleFlowEventListener;
 import org.drools.event.RuleFlowGroupActivatedEvent;
 import org.drools.event.RuleFlowGroupDeactivatedEvent;
+import org.drools.event.RuleFlowNodeTriggeredEvent;
 import org.drools.event.RuleFlowStartedEvent;
+import org.drools.ruleflow.common.instance.WorkItem;
 import org.drools.ruleflow.common.instance.impl.ProcessInstanceImpl;
 import org.drools.ruleflow.core.ActionNode;
 import org.drools.ruleflow.core.EndNode;
@@ -49,6 +51,7 @@
 import org.drools.ruleflow.core.Split;
 import org.drools.ruleflow.core.StartNode;
 import org.drools.ruleflow.core.SubFlowNode;
+import org.drools.ruleflow.core.WorkItemNode;
 import org.drools.ruleflow.instance.RuleFlowNodeInstance;
 import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 
@@ -160,6 +163,11 @@
             result.setNodeId( node.getId() );
             addNodeInstance( result );
             return result;
+        } else if ( node instanceof WorkItemNode ) {
+            final RuleFlowNodeInstance result = new TaskNodeInstanceImpl();
+            result.setNodeId( node.getId() );
+            addNodeInstance( result );
+            return result;
         }
         throw new IllegalArgumentException( "Illegal node type: " + node.getClass() );
     }
@@ -175,6 +183,9 @@
     public void setState(final int state) {
         super.setState(state);
         if (state == ProcessInstanceImpl.STATE_COMPLETED) {
+            ((EventSupport) this.workingMemory)
+                    .getRuleFlowEventSupport()
+                    .fireBeforeRuleFlowProcessCompleted(this, this.workingMemory);
             // deactivate all node instances of this process instance
             while (!nodeInstances.isEmpty()) {
             	RuleFlowNodeInstance nodeInstance = (RuleFlowNodeInstance) nodeInstances.get(0);
@@ -182,8 +193,10 @@
             }
             workingMemory.removeEventListener((AgendaEventListener) this);
             workingMemory.removeEventListener((RuleFlowEventListener) this);
-        	((EventSupport) this.workingMemory).getRuleFlowEventSupport()
-        		.fireRuleFlowProcessCompleted(this, this.workingMemory);
+            workingMemory.removeProcessInstance(this);
+        	((EventSupport) this.workingMemory)
+                    .getRuleFlowEventSupport()
+                    .fireAfterRuleFlowProcessCompleted(this, this.workingMemory);
         }
     }
 
@@ -240,19 +253,43 @@
 		// Do nothing
 	}
 
-	public void ruleFlowGroupActivated(RuleFlowGroupActivatedEvent event, WorkingMemory workingMemory) {
+	public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event, WorkingMemory workingMemory) {
 		// Do nothing
 	}
 
-	public void ruleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
+    public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+	public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
 		// Do nothing
 	}
 
-	public void ruleFlowStarted(RuleFlowStartedEvent event, WorkingMemory workingMemory) {
+    public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+	public void beforeRuleFlowStarted(RuleFlowStartedEvent event, WorkingMemory workingMemory) {
 		// Do nothing
 	}
 
-	public void ruleFlowCompleted(RuleFlowCompletedEvent event, WorkingMemory workingMemory) {
+    public void afterRuleFlowStarted(RuleFlowStartedEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+    public void beforeRuleFlowCompleted(RuleFlowCompletedEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+    public void beforeRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+    public void afterRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event, WorkingMemory workingMemory) {
+        // Do nothing
+    }
+
+	public void afterRuleFlowCompleted(RuleFlowCompletedEvent event, WorkingMemory workingMemory) {
 		// TODO group all subflow related code in subflow instance impl?
 		for (Iterator iterator = getNodeInstances().iterator(); iterator.hasNext(); ) {
 			RuleFlowNodeInstance nodeInstance = (RuleFlowNodeInstance) iterator.next();
@@ -265,4 +302,31 @@
 			
 		}
 	}
+
+    public void taskCompleted(WorkItem taskInstance) {
+        for (Iterator iterator = getNodeInstances().iterator(); iterator.hasNext(); ) {
+            RuleFlowNodeInstance nodeInstance = (RuleFlowNodeInstance) iterator.next();
+            if (nodeInstance instanceof TaskNodeInstanceImpl) {
+                TaskNodeInstanceImpl taskNodeInstance = (TaskNodeInstanceImpl) nodeInstance;
+                WorkItem nodeTaskInstance = taskNodeInstance.getTaskInstance();
+                if (nodeTaskInstance != null && nodeTaskInstance.getId() == taskInstance.getId()) {
+                    taskNodeInstance.triggerCompleted();
+                }
+            }
+        }
+    }
+
+    public void taskAborted(WorkItem taskInstance) {
+        for (Iterator iterator = getNodeInstances().iterator(); iterator.hasNext(); ) {
+            RuleFlowNodeInstance nodeInstance = (RuleFlowNodeInstance) iterator.next();
+            if (nodeInstance instanceof TaskNodeInstanceImpl) {
+                TaskNodeInstanceImpl taskNodeInstance = (TaskNodeInstanceImpl) nodeInstance;
+                WorkItem nodeTaskInstance = taskNodeInstance.getTaskInstance();
+                if (nodeTaskInstance != null && nodeTaskInstance.getId() == taskInstance.getId()) {
+                    taskNodeInstance.triggerCompleted();
+                }
+            }
+        }
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -30,7 +30,7 @@
         return (RuleSetNode) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
         getProcessInstance().getAgenda().activateRuleFlowGroup( getRuleSetNode().getRuleFlowGroup() );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -32,15 +32,13 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class RuleFlowSplitInstanceImpl extends RuleFlowNodeInstanceImpl
-    implements
-    RuleFlowNodeInstance {
+public class RuleFlowSplitInstanceImpl extends RuleFlowNodeInstanceImpl {
 
     protected Split getSplitNode() {
         return (Split) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
         final Split split = getSplitNode();
         switch ( split.getType() ) {
             case Split.TYPE_AND :

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -26,7 +26,7 @@
  */
 public class StartNodeInstanceImpl extends RuleFlowNodeInstanceImpl {
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
         triggerCompleted();
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/SubFlowNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/SubFlowNodeInstanceImpl.java	2007-11-24 01:26:01 UTC (rev 16767)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/SubFlowNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -33,10 +33,11 @@
         return (SubFlowNode) getNode();
     }
 
-    public void trigger(final RuleFlowNodeInstance from) {
+    public void internalTrigger(final RuleFlowNodeInstance from) {
     	ProcessInstance processInstance = 
     		getProcessInstance().getWorkingMemory().startProcess(getSubFlowNode().getProcessId());
-    	if (processInstance.getState() == ProcessInstance.STATE_COMPLETED) {
+    	if (!getSubFlowNode().isWaitForCompletion()
+    	        || processInstance.getState() == ProcessInstance.STATE_COMPLETED) {
     		triggerCompleted();
     	} else {
     		this.processInstanceId = processInstance.getId();

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/TaskNodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/TaskNodeInstanceImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/TaskNodeInstanceImpl.java	2007-11-24 01:26:35 UTC (rev 16768)
@@ -0,0 +1,56 @@
+package org.drools.ruleflow.instance.impl;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.drools.ruleflow.common.core.Work;
+import org.drools.ruleflow.common.instance.WorkItem;
+import org.drools.ruleflow.common.instance.impl.WorkItemImpl;
+import org.drools.ruleflow.core.WorkItemNode;
+import org.drools.ruleflow.instance.RuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of a task node.
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class TaskNodeInstanceImpl extends RuleFlowNodeInstanceImpl {
+
+    private WorkItemImpl taskInstance;
+    
+    protected WorkItemNode getTaskNode() {
+        return (WorkItemNode) getNode();
+    }
+    
+    public WorkItem getTaskInstance() {
+        return taskInstance;
+    }
+
+    public void internalTrigger(final RuleFlowNodeInstance from) {
+		Work task = getTaskNode().getWork();
+		taskInstance = new WorkItemImpl();
+		taskInstance.setName(task.getName());
+		taskInstance.setProcessInstanceId(getProcessInstance().getId());
+		taskInstance.setParameters(task.getParameters());
+		getProcessInstance().getWorkingMemory().getWorkItemManager().executeWorkItem(taskInstance);
+    }
+
+    public void triggerCompleted() {
+        getProcessInstance().getNodeInstance( getTaskNode().getTo().getTo() ).trigger( this );
+        getProcessInstance().removeNodeInstance(this);
+    }
+
+}
\ No newline at end of file




More information about the jboss-svn-commits mailing list