[jboss-svn-commits] JBL Code SVN: r22597 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 18 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Sep 10 11:21:35 EDT 2008


Author: KrisVerlaenen
Date: 2008-09-10 11:21:34 -0400 (Wed, 10 Sep 2008)
New Revision: 22597

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/GetProcessInstanceCommand.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/InsertObjectCommand.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstanceInterface.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/SubProcessTest.java
   labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers1.conf
   labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers2.conf
Modified:
   labs/jbossrules/trunk/drools-compiler/.classpath
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessMarchallingTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
   labs/jbossrules/trunk/drools-core/.classpath
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.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/marshalling/InputMarshaller.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/OutputMarshaller.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/PersisterEnums.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/CompleteWorkItemCommand.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/EventListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/TimerTest.java
Log:
JBRULES-1760: Add timers in binary serialization
 - timers are now persisted as part of the session
JBRULES-1761: Add JPA persistence
 - made pluggable WorkItemManager + Factory
 - made pluggable ProcessInstanceManager + Factory
 - JPA-based command service
 - migrated SubFlowNodeInstance to use EventListener
 - WorkItemHandlers pluggable using RuleBaseConfiguration

Modified: labs/jbossrules/trunk/drools-compiler/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-compiler/.classpath	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-compiler/.classpath	2008-09-10 15:21:34 UTC (rev 22597)
@@ -1,30 +1,22 @@
-<classpath>
-  <classpathentry kind="src" path="src/main/java"/>
-  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
-  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
-  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
-  <classpathentry kind="output" path="target/classes"/>
-  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.2.2/xstream-1.2.2.jar" sourcepath="M2_REPO/com/thoughtworks/xstream/xstream/1.2.2/xstream-1.2.2-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.3.4.O/xpp3_min-1.1.3.4.O.jar"/>
-  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.10/janino-2.5.10.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.0.1/antlr-runtime-3.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/stringtemplate/3.1-b1/stringtemplate-3.1-b1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/gunit/1.0.1/gunit-1.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-project/2.0/maven-project-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-profile/2.0/maven-profile-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-model/2.0/maven-model-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-utils/1.0.4/plexus-utils-1.0.4.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-container-default/1.0-alpha-8/plexus-container-default-1.0-alpha-8.jar"/>
-  <classpathentry kind="var" path="M2_REPO/classworlds/classworlds/1.1-alpha-2/classworlds-1.1-alpha-2.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-artifact-manager/2.0/maven-artifact-manager-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-repository-metadata/2.0/maven-repository-metadata-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-artifact/2.0/maven-artifact-2.0.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/apache/maven/wagon/wagon-provider-api/1.0-alpha-5/wagon-provider-api-1.0-alpha-5.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0.1/antlr-3.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
-  <classpathentry kind="src" path="/drools-core"/>
-  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-dp4/mvel-2.0-dp4.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.2.3.v_686_R32x/core-3.2.3.v_686_R32x.jar"/>
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
+  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.10/janino-2.5.10.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.0.1/antlr-runtime-3.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/gunit/1.0.1/gunit-1.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0.1/antlr-3.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
+  <classpathentry kind="src" path="/drools-core"/>
+  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-SNAPSHOT/mvel-2.0-SNAPSHOT.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.2.3.v_686_R32x/core-3.2.3.v_686_R32x.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
 </classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessMarchallingTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessMarchallingTest.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessMarchallingTest.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -2,6 +2,8 @@
 
 import static org.drools.integrationtests.SerializationHelper.getSerialisedStatefulSession;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -15,6 +17,8 @@
 import org.drools.RuleBaseFactory;
 import org.drools.StatefulSession;
 import org.drools.compiler.PackageBuilder;
+import org.drools.marshalling.DefaultMarshaller;
+import org.drools.marshalling.Marshaller;
 import org.drools.process.core.context.variable.VariableScope;
 import org.drools.process.instance.WorkItem;
 import org.drools.process.instance.WorkItemHandler;
@@ -431,6 +435,94 @@
         assertEquals(0, session.getProcessInstances().size());
     }
     
+    public void test5() throws Exception {
+        String process = 
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+        	"<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "  xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "  xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "  type=\"RuleFlow\" name=\"ruleflow\" id=\"com.sample.ruleflow\" package-name=\"com.sample\" >\n" +
+            "\n" +
+            "    <header>\n" +
+    		"    </header>\n" +
+    		"\n" +
+    		"    <nodes>\n" +
+    		"      <start id=\"1\" name=\"Start\" />\n" +
+    		"      <timer id=\"4\" name=\"Timer\" delay=\"200\" />\n" +
+    		"      <end id=\"3\" name=\"End\" />\n" +
+    		"    </nodes>\n" +
+    		"\n" +
+    		"    <connections>\n" +
+    		"      <connection from=\"1\" to=\"4\" />\n" +
+    		"      <connection from=\"4\" to=\"3\" />\n" +
+    		"    </connections>\n" +
+            "\n" +
+            "</process>\n";
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addProcessFromXml( new StringReader( process ));
+        final Package pkg = builder.getPackage();
+        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage(pkg);
+
+        StatefulSession session = ruleBase.newStatefulSession();
+        session.startProcess("com.sample.ruleflow", null);
+
+        assertEquals(1, session.getProcessInstances().size());
+        
+        session = getSerialisedStatefulSession( session );
+        Thread.sleep(400);
+
+        assertEquals(0, session.getProcessInstances().size());
+    }
+    
+    public void test6() throws Exception {
+        String process = 
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+        	"<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "  xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "  xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "  type=\"RuleFlow\" name=\"ruleflow\" id=\"com.sample.ruleflow\" package-name=\"com.sample\" >\n" +
+            "\n" +
+            "    <header>\n" +
+    		"    </header>\n" +
+    		"\n" +
+    		"    <nodes>\n" +
+    		"      <start id=\"1\" name=\"Start\" />\n" +
+    		"      <timer id=\"4\" name=\"Timer\" delay=\"200\" />\n" +
+    		"      <end id=\"3\" name=\"End\" />\n" +
+    		"    </nodes>\n" +
+    		"\n" +
+    		"    <connections>\n" +
+    		"      <connection from=\"1\" to=\"4\" />\n" +
+    		"      <connection from=\"4\" to=\"3\" />\n" +
+    		"    </connections>\n" +
+            "\n" +
+            "</process>\n";
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addProcessFromXml( new StringReader( process ));
+        final Package pkg = builder.getPackage();
+        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage(pkg);
+
+        StatefulSession session = ruleBase.newStatefulSession();
+        session.startProcess("com.sample.ruleflow", null);
+        assertEquals(1, session.getProcessInstances().size());
+        
+        Marshaller marshaller = new DefaultMarshaller();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ruleBase.writeStatefulSession(session, baos, marshaller);
+        byte[] b1 = baos.toByteArray();
+        session.dispose();
+        Thread.sleep(400);
+        
+        ByteArrayInputStream bais = new ByteArrayInputStream( b1 );
+        session = ruleBase.readStatefulSession(bais, true, marshaller);
+        Thread.sleep(100);
+
+        assertEquals(0, session.getProcessInstances().size());
+    }
+    
     private static class TestWorkItemHandler implements WorkItemHandler {
     	private WorkItem workItem;
     	public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -1,5 +1,7 @@
 package org.drools.integrationtests;
 
+import static org.drools.integrationtests.SerializationHelper.getSerialisedStatefulSession;
+
 import java.io.Reader;
 import java.io.StringReader;
 import java.util.ArrayList;
@@ -7,16 +9,17 @@
 
 import junit.framework.TestCase;
 
+import org.drools.Message;
 import org.drools.RuleBase;
 import org.drools.RuleBaseFactory;
-import org.drools.WorkingMemory;
+import org.drools.StatefulSession;
 import org.drools.compiler.PackageBuilder;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.rule.Package;
 
 public class ProcessTimerTest extends TestCase {
 	
-	public void testSimpleProcess() {
+	public void testSimpleProcess() throws Exception {
 		PackageBuilder builder = new PackageBuilder();
 		Reader source = new StringReader(
 			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
@@ -56,18 +59,24 @@
 			"\n" +
 			"</process>");
 		builder.addRuleFlow(source);
+		
 		Package pkg = builder.getPackage();
 		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
 		ruleBase.addPackage( pkg );
-		WorkingMemory workingMemory = ruleBase.newStatefulSession();
-		List myList = new ArrayList();
-		workingMemory.setGlobal("myList", myList);
+		StatefulSession session = ruleBase.newStatefulSession();
+		List<Message> myList = new ArrayList<Message>();
+		session.setGlobal("myList", myList);
         ProcessInstance processInstance =
-    		workingMemory.startProcess("org.drools.timer");
+        	session.startProcess("org.drools.timer");
         assertEquals(0, myList.size());
         assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+        assertEquals(1, session.getTimerManager().getTimers().size());
         
+        session = getSerialisedStatefulSession( session );
+        assertEquals(1, session.getTimerManager().getTimers().size());
+
         // test that the delay works
+        System.out.println("Sleep1");
         try {
             Thread.sleep(600);
         } catch (InterruptedException e) {
@@ -76,11 +85,13 @@
         assertEquals(0, myList.size());
         
         // test that the period works
+        System.out.println("Sleep2");
         try {
         	Thread.sleep(1300);
         } catch (InterruptedException e) {
         	// do nothing
         }
+        session.fireAllRules();
         assertEquals(5, myList.size());
         assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
 	}

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -544,4 +544,9 @@
         return null;
     }
 
+	public void dispose() {
+		// TODO Auto-generated method stub
+		
+	}
+
 }

Modified: labs/jbossrules/trunk/drools-core/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-core/.classpath	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/.classpath	2008-09-10 15:21:34 UTC (rev 22597)
@@ -1,12 +1,15 @@
-<classpath>
-  <classpathentry kind="src" path="src/main/java"/>
-  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
-  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
-  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
-  <classpathentry kind="output" path="target/classes"/>
-  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.2.2/xstream-1.2.2.jar" sourcepath="M2_REPO/com/thoughtworks/xstream/xstream/1.2.2/xstream-1.2.2-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.3.4.O/xpp3_min-1.1.3.4.O.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-dp4/mvel-2.0-dp4.jar"/>
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-SNAPSHOT/mvel-2.0-SNAPSHOT.jar"/>
 </classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -40,7 +40,9 @@
 import org.drools.process.core.impl.WorkDefinitionExtensionImpl;
 import org.drools.process.instance.ProcessInstanceFactory;
 import org.drools.process.instance.ProcessInstanceFactoryRegistry;
-import org.drools.process.instance.ProcessInstanceManager;
+import org.drools.process.instance.ProcessInstanceManagerFactory;
+import org.drools.process.instance.WorkItemHandler;
+import org.drools.process.instance.WorkItemManagerFactory;
 import org.drools.process.instance.impl.ContextInstanceFactory;
 import org.drools.process.instance.impl.ContextInstanceFactoryRegistry;
 import org.drools.spi.ConflictResolver;
@@ -125,11 +127,13 @@
     private static final String            STAR             = "*";
     private ContextInstanceFactoryRegistry processContextInstanceFactoryRegistry;
     private Map<String, WorkDefinition>    workDefinitions;
+    private Map<String, WorkItemHandler>   workItemHandlers;
     private boolean                        advancedProcessRuleIntegration;
 
     private ProcessInstanceFactoryRegistry processInstanceFactoryRegistry;
     private NodeInstanceFactoryRegistry    processNodeInstanceFactoryRegistry;
-    private ProcessInstanceManager         processInstanceManager;
+    private ProcessInstanceManagerFactory  processInstanceManagerFactory;
+    private WorkItemManagerFactory         workItemManagerFactory;
 
     private transient ClassLoader          classLoader;
 
@@ -671,6 +675,47 @@
         }
     }
 
+    public Map<String, WorkItemHandler> getWorkItemHandlers() {
+        if ( this.workItemHandlers == null ) {
+            initWorkItemHandlers();
+        }
+        return this.workItemHandlers;
+
+    }
+
+    private void initWorkItemHandlers() {
+        this.workItemHandlers = new HashMap<String, WorkItemHandler>();
+
+        // split on each space
+        String locations[] = this.chainedProperties.getProperty( "drools.workItemHandlers",
+                                                                 "" ).split( "\\s" );
+
+        // load each SemanticModule
+        for ( String factoryLocation : locations ) {
+            // trim leading/trailing spaces and quotes
+            factoryLocation = factoryLocation.trim();
+            if ( factoryLocation.startsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 1 );
+            }
+            if ( factoryLocation.endsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 0,
+                                                             factoryLocation.length() - 1 );
+            }
+            if ( !factoryLocation.equals( "" ) ) {
+                loadWorkItemHandlers( factoryLocation );
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+	private void loadWorkItemHandlers(String location) {
+        String content = ConfFileUtils.URLContentsToString( ConfFileUtils.getURL( location,
+                                                                                  null,
+                                                                                  RuleBaseConfiguration.class ) );
+        Map<String, WorkItemHandler> workItemHandlers = (Map<String, WorkItemHandler>) MVEL.eval( content, new HashMap() );
+        this.workItemHandlers.putAll(workItemHandlers);
+    }
+
     public ContextInstanceFactoryRegistry getProcessContextInstanceFactoryRegistry() {
         if ( this.processContextInstanceFactoryRegistry == null ) {
             initProcessContextInstanceFactoryRegistry();
@@ -720,40 +765,80 @@
         }
     }
 
-    public ProcessInstanceManager getProcessInstanceManager() {
-        if ( this.processInstanceManager == null ) {
-            initProcessInstanceManager();
+    public ProcessInstanceManagerFactory getProcessInstanceManagerFactory() {
+        if ( this.processInstanceManagerFactory == null ) {
+            initProcessInstanceManagerFactory();
         }
-        return this.processInstanceManager;
+        return this.processInstanceManagerFactory;
     }
 
-    private void initProcessInstanceManager() {
-        String className = this.chainedProperties.getProperty( "processInstanceManager",
-                                                               "org.drools.process.instance.impl.DefaultProcessInstanceManager" );
-        Class clazz = null;
+    @SuppressWarnings("unchecked")
+	private void initProcessInstanceManagerFactory() {
+        String className = this.chainedProperties.getProperty( "processInstanceManagerFactory",
+                                                               "org.drools.process.instance.impl.DefaultProcessInstanceManagerFactory" );
+        Class<ProcessInstanceManagerFactory> clazz = null;
         try {
-            clazz = Thread.currentThread().getContextClassLoader().loadClass( className );
+            clazz = (Class<ProcessInstanceManagerFactory>)
+            	Thread.currentThread().getContextClassLoader().loadClass( className );
         } catch ( ClassNotFoundException e ) {
         }
 
         if ( clazz == null ) {
             try {
-                clazz = RuleBaseConfiguration.class.getClassLoader().loadClass( className );
+                clazz = (Class<ProcessInstanceManagerFactory>)
+                	RuleBaseConfiguration.class.getClassLoader().loadClass( className );
             } catch ( ClassNotFoundException e ) {
             }
         }
 
         if ( clazz != null ) {
             try {
-                this.processInstanceManager = (ProcessInstanceManager) clazz.newInstance();
+                this.processInstanceManagerFactory = clazz.newInstance();
             } catch ( Exception e ) {
-                throw new IllegalArgumentException( "Unable to instantiate process instance manager '" + className + "'" );
+                throw new IllegalArgumentException( "Unable to instantiate process instance manager factory '" + className + "'" );
             }
         } else {
-            throw new IllegalArgumentException( "Process instance manager '" + className + "' not found" );
+            throw new IllegalArgumentException( "Process instance manager factory '" + className + "' not found" );
         }
     }
 
+    public WorkItemManagerFactory getWorkItemManagerFactory() {
+        if ( this.workItemManagerFactory == null ) {
+            initWorkItemManagerFactory();
+        }
+        return this.workItemManagerFactory;
+    }
+
+    @SuppressWarnings("unchecked")
+	private void initWorkItemManagerFactory() {
+        String className = this.chainedProperties.getProperty( "workItemManagerFactory",
+                                                               "org.drools.process.instance.impl.DefaultWorkItemManagerFactory" );
+        Class<WorkItemManagerFactory> clazz = null;
+        try {
+            clazz = (Class<WorkItemManagerFactory>)
+            	Thread.currentThread().getContextClassLoader().loadClass( className );
+        } catch ( ClassNotFoundException e ) {
+        }
+
+        if ( clazz == null ) {
+            try {
+                clazz = (Class<WorkItemManagerFactory>)
+                	RuleBaseConfiguration.class.getClassLoader().loadClass( className );
+            } catch ( ClassNotFoundException e ) {
+            }
+        }
+
+        if ( clazz != null ) {
+            try {
+                this.workItemManagerFactory = clazz.newInstance();
+            } catch ( Exception e ) {
+                throw new IllegalArgumentException( "Unable to instantiate work item manager factory '" + className + "'", e );
+            }
+        } else {
+            throw new IllegalArgumentException( "Work item manager factory '" + className + "' not found" );
+        }
+    }
+
     public boolean isAdvancedProcessRuleIntegration() {
         return advancedProcessRuleIntegration;
     }

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	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -300,5 +300,7 @@
      * @return
      */
     public SessionClock getSessionClock();
+    
+    public void dispose();
 
 }
\ No newline at end of file

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	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -65,6 +65,7 @@
 import org.drools.process.instance.ProcessInstanceFactory;
 import org.drools.process.instance.ProcessInstanceFactoryRegistry;
 import org.drools.process.instance.ProcessInstanceManager;
+import org.drools.process.instance.WorkItemHandler;
 import org.drools.process.instance.WorkItemManager;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.process.instance.timer.TimerManager;
@@ -247,7 +248,8 @@
         this.__ruleBaseEventListeners = new LinkedList();
         this.lock = new ReentrantLock();
         this.liaPropagations = Collections.EMPTY_LIST;
-        this.processInstanceManager = conf.getProcessInstanceManager();
+        this.processInstanceManager = conf.getProcessInstanceManagerFactory()
+        	.createProcessInstanceManager(this);
         this.timeMachine = new TimeMachine();
         
         TimerService timerService = TimerServiceFactory.getTimerService( this.config.getClockType() );
@@ -1486,7 +1488,7 @@
         ProcessInstance processInstance = getProcessInstance(process);
         processInstance.setWorkingMemory( this );
         processInstance.setProcess( process );
-        addProcessInstance( processInstance );
+        processInstanceManager.addProcessInstance(processInstance);
         // set variable default values
         // TODO: should be part of processInstanceImpl?
         VariableScope variableScope = (VariableScope) process.getDefaultContext( VariableScope.VARIABLE_SCOPE );
@@ -1539,17 +1541,20 @@
         return processInstanceManager.getProcessInstance(id);
     }
 
-    public void addProcessInstance(ProcessInstance processInstance) {
-        processInstanceManager.addProcessInstance(processInstance);
-    }
-
     public void removeProcessInstance(ProcessInstance processInstance) {
         processInstanceManager.removeProcessInstance(processInstance);
     }
 
     public WorkItemManager getWorkItemManager() {
         if ( workItemManager == null ) {
-            workItemManager = new WorkItemManager( this );
+            workItemManager = ruleBase.getConfiguration().getWorkItemManagerFactory().createWorkItemManager(this);
+            Map<String, WorkItemHandler> workItemHandlers = 
+            	((InternalRuleBase) getRuleBase()).getConfiguration().getWorkItemHandlers();
+            if (workItemHandlers != null) {
+            	for (Map.Entry<String, WorkItemHandler> entry: workItemHandlers.entrySet()) {
+            		workItemManager.registerWorkItemHandler(entry.getKey(), entry.getValue());
+            	}
+            }
         }
         return workItemManager;
     }
@@ -1691,5 +1696,16 @@
     //        }
     //        
     //    }
+    
+    public void dispose() {
+        this.workingMemoryEventSupport.reset();
+        this.agendaEventSupport.reset();
+        this.workflowEventSupport.reset();
+        for ( Iterator it = this.__ruleBaseEventListeners.iterator(); it.hasNext(); ) {
+            this.ruleBase.removeEventListener( (RuleBaseEventListener) it.next() );
+        }
+        this.stopPartitionManagers();
+        this.timerManager.dispose();
+    }
 
 }

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	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -85,8 +85,6 @@
 
 	public void setTimeMachine(TimeMachine tm);
 	
-    public void addProcessInstance(ProcessInstance processInstance);
-    
     public void removeProcessInstance(ProcessInstance processInstance);
     
     public ProcessInstanceManager getProcessInstanceManager();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/InputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/InputMarshaller.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/InputMarshaller.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Queue;
@@ -25,11 +26,13 @@
 import org.drools.concurrent.ExecutorService;
 import org.drools.process.core.context.swimlane.SwimlaneContext;
 import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.timer.Timer;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItem;
 import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.process.instance.impl.WorkItemImpl;
+import org.drools.process.instance.timer.TimerManager;
 import org.drools.reteoo.BetaMemory;
 import org.drools.reteoo.BetaNode;
 import org.drools.reteoo.EntryPointNode;
@@ -63,7 +66,6 @@
 import org.drools.workflow.instance.NodeInstanceContainer;
 import org.drools.workflow.instance.impl.NodeInstanceImpl;
 import org.drools.workflow.instance.node.CompositeContextNodeInstance;
-import org.drools.workflow.instance.node.EventBasedNodeInstance;
 import org.drools.workflow.instance.node.ForEachNodeInstance;
 import org.drools.workflow.instance.node.HumanTaskNodeInstance;
 import org.drools.workflow.instance.node.JoinInstance;
@@ -114,8 +116,10 @@
 
         readProcessInstances( context );
 
-        readWorkItems( context );        
+        readWorkItems( context );
         
+        readTimers( context );
+        
         return session;
     }
     
@@ -173,6 +177,8 @@
         readProcessInstances( context );
 
         readWorkItems( context );
+        
+        readTimers( context );
 
         return session;
     }
@@ -653,7 +659,7 @@
 
         processInstance.internalSetNodeInstanceCounter( nodeInstanceCounter );
         if (wm != null) {
-        	wm.addProcessInstance( processInstance );
+        	processInstance.reconnect();
         }
         return processInstance;
     }
@@ -751,23 +757,21 @@
 	        default :
 	            // do nothing
 	        }
-        if ( nodeInstance instanceof EventBasedNodeInstance ) {
-            ((EventBasedNodeInstance) nodeInstance).addEventListeners();
-        }
         return nodeInstance;
     }
 
     public static void readWorkItems(MarshallerReaderContext context) throws IOException {
-        ObjectInputStream stream = context.stream;
+    	InternalWorkingMemory wm = context.wm;
+    	ObjectInputStream stream = context.stream;
         while ( stream.readShort() == PersisterEnums.WORK_ITEM ) {
-            readWorkItem( context );
+            WorkItem workItem = readWorkItem( context );
+            wm.getWorkItemManager().internalAddWorkItem( workItem );
         }
     }
 
     public static WorkItem readWorkItem(MarshallerReaderContext context) throws IOException {
         ObjectInputStream stream = context.stream;
-        InternalWorkingMemory wm = context.wm;
-
+        
         WorkItemImpl workItem = new WorkItemImpl();
         workItem.setId( stream.readLong() );
         workItem.setProcessInstanceId( stream.readLong() );
@@ -786,8 +790,35 @@
         	}
         }
 
-        wm.getWorkItemManager().internalAddWorkItem( workItem );
         return workItem;
     }
 
+    public static void readTimers(MarshallerReaderContext context) throws IOException {
+    	InternalWorkingMemory wm = context.wm;
+    	ObjectInputStream stream = context.stream;
+    	
+    	TimerManager timerManager = wm.getTimerManager();
+    	timerManager.internalSetTimerId( stream.readLong() );
+    	
+        while ( stream.readShort() == PersisterEnums.TIMER ) {
+            Timer timer = readTimer( context );
+            timerManager.internalAddTimer( timer );
+        }
+    }
+
+    public static Timer readTimer(MarshallerReaderContext context) throws IOException {
+        ObjectInputStream stream = context.stream;
+        
+        Timer timer = new Timer();
+        timer.setId( stream.readLong() );
+        timer.setDelay( stream.readLong() );
+        timer.setPeriod( stream.readLong() );
+        timer.setProcessInstanceId( stream.readLong() );
+        timer.setActivated( new Date(stream.readLong()) );
+        if (stream.readBoolean()) {
+        	timer.setLastTriggered( new Date(stream.readLong()) );
+        }
+        return timer;
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/OutputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/OutputMarshaller.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/OutputMarshaller.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -8,6 +8,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -29,10 +30,12 @@
 import org.drools.common.WorkingMemoryAction;
 import org.drools.process.core.context.swimlane.SwimlaneContext;
 import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.timer.Timer;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItem;
 import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.timer.TimerManager;
 import org.drools.reteoo.LeftTuple;
 import org.drools.reteoo.LeftTupleSink;
 import org.drools.reteoo.NodeTypeEnums;
@@ -94,6 +97,8 @@
         writeProcessInstances( context );
 
         writeWorkItems( context );
+        
+        writeTimers( context );
     }
 
     public static void writeAgenda(MarshallerWriteContext context) throws IOException {
@@ -791,4 +796,39 @@
         }
     }
 
+    public static void writeTimers(MarshallerWriteContext context) throws IOException {
+        ObjectOutputStream stream = context.stream;
+
+        TimerManager timerManager = context.wm.getTimerManager();
+        stream.writeLong( timerManager.internalGetTimerId() );
+
+        List<Timer> timers = new ArrayList<Timer>(timerManager.getTimers());
+        Collections.sort(timers, new Comparator<Timer>() {
+			public int compare(Timer o1, Timer o2) {
+				return (int) (o2.getId() - o1.getId());
+			}
+        });
+        for ( Timer timer: timers ) {
+            stream.writeShort( PersisterEnums.TIMER );
+            writeTimer( context, timer );
+        }
+        stream.writeShort( PersisterEnums.END );
+    }
+
+    public static void writeTimer(MarshallerWriteContext context, Timer timer) throws IOException {
+    	ObjectOutputStream stream = context.stream;
+    	stream.writeLong( timer.getId() );
+    	stream.writeLong( timer.getDelay() );
+    	stream.writeLong( timer.getPeriod() );
+    	stream.writeLong( timer.getProcessInstanceId() );
+    	stream.writeLong( timer.getActivated().getTime() );
+    	Date lastTriggered = timer.getLastTriggered();
+    	if (lastTriggered != null) {
+    		stream.writeBoolean(true);
+    		stream.writeLong( timer.getLastTriggered().getTime() );
+    	} else {
+    		stream.writeBoolean(false);
+    	}
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/PersisterEnums.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/PersisterEnums.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/PersisterEnums.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -38,5 +38,6 @@
     public static final short COMPOSITE_NODE_INSTANCE   = 26;
     public static final short HUMAN_TASK_NODE_INSTANCE  = 27;
     public static final short FOR_EACH_NODE_INSTANCE    = 28;
+    public static final short TIMER                     = 29;
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/CompleteWorkItemCommand.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/CompleteWorkItemCommand.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/CompleteWorkItemCommand.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -8,7 +8,6 @@
 public class CompleteWorkItemCommand implements Command {
 	
 	private long workItemId;
-	private long processInstanceId;
 	private Map<String, Object> results = new HashMap<String, Object>();
 	
 	public long getWorkItemId() {
@@ -19,14 +18,6 @@
 		this.workItemId = workItemId;
 	}
 
-	public long getProcessInstanceId() {
-		return processInstanceId;
-	}
-
-	public void setProcessInstanceId(long processInstanceId) {
-		this.processInstanceId = processInstanceId;
-	}
-
 	public Map<String, Object> getResults() {
 		return results;
 	}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/GetProcessInstanceCommand.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/GetProcessInstanceCommand.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/GetProcessInstanceCommand.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,24 @@
+package org.drools.process.command;
+
+import org.drools.WorkingMemory;
+
+public class GetProcessInstanceCommand implements Command {
+	
+	private Long processInstanceId;
+	
+	public Long getProcessInstanceId() {
+		return processInstanceId;
+	}
+	
+	public void setProcessInstanceId(Long processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+	
+	public Object execute(WorkingMemory workingMemory) {
+		if (processInstanceId == null) {
+			return null;
+		}
+		return workingMemory.getProcessInstance(processInstanceId);
+	}
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/InsertObjectCommand.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/InsertObjectCommand.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/command/InsertObjectCommand.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,28 @@
+package org.drools.process.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.WorkingMemory;
+
+public class InsertObjectCommand implements Command {
+	
+	private List<Object> objects;
+	
+	public InsertObjectCommand(Object object) {
+		objects = new ArrayList<Object>();
+		objects.add(object);
+	}
+	
+	public InsertObjectCommand(List<Object> objects) {
+		this.objects = objects;
+	}
+	
+	public Object execute(WorkingMemory workingMemory) {
+		for (Object object: objects) {
+			workingMemory.insert(object);
+		}
+		return null;
+	}
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -1,5 +1,7 @@
 package org.drools.process.core.timer;
 
+import java.util.Date;
+
 import org.drools.time.JobHandle;
 
 public class Timer {
@@ -7,7 +9,11 @@
     private long id;
     private long delay;
     private long period;
+    // TODO separate in Timer and TimerInstance
     private JobHandle jobHandle;
+    private Date activated;
+    private Date lastTriggered;
+    private long processInstanceId;
     
     public long getId() {
         return id;
@@ -41,6 +47,28 @@
         this.jobHandle = jobHandle;
     }
     
+    public Date getActivated() {
+		return activated;
+	}
+
+	public void setActivated(Date activated) {
+		this.activated = activated;
+	}
+
+	public void setLastTriggered(Date lastTriggered) {
+    	this.lastTriggered = lastTriggered;
+    }
     
+    public Date getLastTriggered() {
+    	return lastTriggered;
+    }
+
+	public long getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(long processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
     
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/EventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/EventListener.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/EventListener.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -3,5 +3,11 @@
 public interface EventListener {
 	
 	void signalEvent(String type, Object event);
+	
+	/**
+	 * Returns the event types this event listener is interested in.
+	 * May return null if the event types are unknown.
+	 */
+	String[] getEventTypes();
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManager.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManager.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -9,7 +9,11 @@
     Collection<ProcessInstance> getProcessInstances();
 
     void addProcessInstance(ProcessInstance processInstance);
+    
+    void internalAddProcessInstance(ProcessInstance processInstance);
 
     void removeProcessInstance(ProcessInstance processInstance);
 
+    void internalRemoveProcessInstance(ProcessInstance processInstance);
+
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstanceManagerFactory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,9 @@
+package org.drools.process.instance;
+
+import org.drools.WorkingMemory;
+
+public interface ProcessInstanceManagerFactory {
+	
+	ProcessInstanceManager createProcessInstanceManager(WorkingMemory workingMemory);
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -1,120 +1,28 @@
 package org.drools.process.instance;
 
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import org.drools.WorkingMemory;
-import org.drools.process.instance.impl.WorkItemImpl;
-
 /**
  *
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class WorkItemManager implements Externalizable {
+public interface WorkItemManager {
 
-    private static final long serialVersionUID = 400L;
-
-    private long workItemCounter;
-	private Map<Long, WorkItem> workItems = new HashMap<Long, WorkItem>();
-	private WorkingMemory workingMemory;
-	private Map<String, WorkItemHandler> workItemHandlers = new HashMap<String, WorkItemHandler>();
-
-    public WorkItemManager() {
-
-    }
-    public WorkItemManager(WorkingMemory workingMemory) {
-	    this.workingMemory = workingMemory;
-	}
-
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        workItemCounter = in.readLong();
-        workItems   = (Map<Long, WorkItem>)in.readObject();
-        workingMemory   = (WorkingMemory)in.readObject();
-        workItemHandlers   = (Map<String, WorkItemHandler>)in.readObject();
-    }
-
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeLong(workItemCounter);
-        out.writeObject(workItems);
-        out.writeObject(workingMemory);
-        out.writeObject(workItemHandlers);
-    }
-
-	public void internalExecuteWorkItem(WorkItem workItem) {
-	    ((WorkItemImpl) workItem).setId(++workItemCounter);
-	    internalAddWorkItem(workItem);
-	    WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
-	    if (handler != null) {
-	        handler.executeWorkItem(workItem, this);
-	    } else {
-	        System.err.println("Could not find work item handler for " + workItem.getName());
-	    }
-	}
+	void internalExecuteWorkItem(WorkItem workItem);
 	
-	public void internalAddWorkItem(WorkItem workItem) {
-	    workItems.put(new Long(workItem.getId()), workItem);
-	}
-
-    public void internalAbortWorkItem(long id) {
-        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
-        // work item may have been aborted
-        if (workItem != null) {
-            WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
-            if (handler != null) {
-                handler.abortWorkItem(workItem, this);
-            } else {
-                System.err.println("Could not find work item handler for " + workItem.getName());
-            }
-        }
-    }
+	void internalAddWorkItem(WorkItem workItem);
+	
+    void internalAbortWorkItem(long id);
     
-	public Set<WorkItem> getWorkItems() {
-	    return new HashSet<WorkItem>(workItems.values());
-	}
+	Set<WorkItem> getWorkItems();
 	
-	public WorkItem getWorkItem(long id) {
-		return workItems.get(id);
-	}
+	WorkItem getWorkItem(long id);
 
-    public void completeWorkItem(long id, Map<String, Object> results) {
-        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
-        // work item may have been aborted
-        if (workItem != null) {
-            workItem.setResults(results);
-            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
-            workItem.setState(WorkItem.COMPLETED);
-            // process instance may have finished already
-            if (processInstance != null) {
-                processInstance.signalEvent("workItemCompleted", workItem);
-            }
-            workItems.remove(new Long(id));
-            workingMemory.fireAllRules();
-        }
-    }
+    void completeWorkItem(long id, Map<String, Object> results);
 
-    public void abortWorkItem(long id) {
-        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
-        // work item may have been aborted
-        if (workItem != null) {
-            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
-            workItem.setState(WorkItem.ABORTED);
-            // process instance may have finished already
-            if (processInstance != null) {
-                processInstance.signalEvent("workItemAborted", workItem);
-            }
-            workItems.remove(new Long(id));
-            workingMemory.fireAllRules();
-        }
-    }
+    void abortWorkItem(long id);
 
-    public void registerWorkItemHandler(String workItemName, WorkItemHandler handler) {
-        this.workItemHandlers.put(workItemName, handler);
-    }
+    void registerWorkItemHandler(String workItemName, WorkItemHandler handler);
 
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManagerFactory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,9 @@
+package org.drools.process.instance;
+
+import org.drools.WorkingMemory;
+
+public interface WorkItemManagerFactory {
+	
+	WorkItemManager createWorkItemManager(WorkingMemory workingMemory);
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManager.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManager.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -14,11 +14,13 @@
     private int processCounter = 0;
 
     public void addProcessInstance(ProcessInstance processInstance) {
-        if (processInstance.getId() == 0) {
-            processInstance.setId(++processCounter);
-        }
-        processInstances.put(processInstance.getId(), processInstance);
+        processInstance.setId(++processCounter);
+        internalAddProcessInstance(processInstance);
     }
+    
+    public void internalAddProcessInstance(ProcessInstance processInstance) {
+    	processInstances.put(processInstance.getId(), processInstance);
+    }
 
     public Collection<ProcessInstance> getProcessInstances() {
         return Collections.unmodifiableCollection(processInstances.values());
@@ -29,6 +31,10 @@
     }
 
     public void removeProcessInstance(ProcessInstance processInstance) {
+        internalRemoveProcessInstance(processInstance);
+    }
+
+    public void internalRemoveProcessInstance(ProcessInstance processInstance) {
         processInstances.remove(processInstance.getId());
     }
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultProcessInstanceManagerFactory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,13 @@
+package org.drools.process.instance.impl;
+
+import org.drools.WorkingMemory;
+import org.drools.process.instance.ProcessInstanceManager;
+import org.drools.process.instance.ProcessInstanceManagerFactory;
+
+public class DefaultProcessInstanceManagerFactory implements ProcessInstanceManagerFactory {
+
+	public ProcessInstanceManager createProcessInstanceManager(WorkingMemory workingMemory) {
+		return new DefaultProcessInstanceManager();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManager.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,121 @@
+package org.drools.process.instance.impl;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.WorkingMemory;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.WorkItemHandler;
+import org.drools.process.instance.WorkItemManager;
+
+/**
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class DefaultWorkItemManager implements WorkItemManager, Externalizable {
+
+    private static final long serialVersionUID = 400L;
+
+    private long workItemCounter;
+	private Map<Long, WorkItem> workItems = new HashMap<Long, WorkItem>();
+	private WorkingMemory workingMemory;
+	private Map<String, WorkItemHandler> workItemHandlers = new HashMap<String, WorkItemHandler>();
+
+    public DefaultWorkItemManager(WorkingMemory workingMemory) {
+	    this.workingMemory = workingMemory;
+	}
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        workItemCounter = in.readLong();
+        workItems   = (Map<Long, WorkItem>)in.readObject();
+        workingMemory   = (WorkingMemory)in.readObject();
+        workItemHandlers   = (Map<String, WorkItemHandler>)in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeLong(workItemCounter);
+        out.writeObject(workItems);
+        out.writeObject(workingMemory);
+        out.writeObject(workItemHandlers);
+    }
+
+	public void internalExecuteWorkItem(WorkItem workItem) {
+	    ((WorkItemImpl) workItem).setId(++workItemCounter);
+	    internalAddWorkItem(workItem);
+	    WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
+	    if (handler != null) {
+	        handler.executeWorkItem(workItem, this);
+	    } else {
+	        System.err.println("Could not find work item handler for " + workItem.getName());
+	    }
+	}
+	
+	public void internalAddWorkItem(WorkItem workItem) {
+	    workItems.put(new Long(workItem.getId()), workItem);
+	}
+
+    public void internalAbortWorkItem(long id) {
+        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
+        // work item may have been aborted
+        if (workItem != null) {
+            WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
+            if (handler != null) {
+                handler.abortWorkItem(workItem, this);
+            } else {
+                System.err.println("Could not find work item handler for " + workItem.getName());
+            }
+            workItems.remove(workItem.getId());
+        }
+    }
+    
+	public Set<WorkItem> getWorkItems() {
+	    return new HashSet<WorkItem>(workItems.values());
+	}
+	
+	public WorkItem getWorkItem(long id) {
+		return workItems.get(id);
+	}
+
+    public void completeWorkItem(long id, Map<String, Object> results) {
+        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
+        // work item may have been aborted
+        if (workItem != null) {
+            workItem.setResults(results);
+            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
+            workItem.setState(WorkItem.COMPLETED);
+            // process instance may have finished already
+            if (processInstance != null) {
+                processInstance.signalEvent("workItemCompleted", workItem);
+            }
+            workItems.remove(new Long(id));
+            workingMemory.fireAllRules();
+        }
+    }
+
+    public void abortWorkItem(long id) {
+        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
+        // work item may have been aborted
+        if (workItem != null) {
+            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
+            workItem.setState(WorkItem.ABORTED);
+            // process instance may have finished already
+            if (processInstance != null) {
+                processInstance.signalEvent("workItemAborted", workItem);
+            }
+            workItems.remove(new Long(id));
+            workingMemory.fireAllRules();
+        }
+    }
+
+    public void registerWorkItemHandler(String workItemName, WorkItemHandler handler) {
+        this.workItemHandlers.put(workItemName, handler);
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/DefaultWorkItemManagerFactory.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,24 @@
+package org.drools.process.instance.impl;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.WorkingMemory;
+import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.WorkItemManagerFactory;
+
+public class DefaultWorkItemManagerFactory implements WorkItemManagerFactory, Externalizable {
+
+	public WorkItemManager createWorkItemManager(WorkingMemory workingMemory) {
+		return new DefaultWorkItemManager(workingMemory);
+	}
+
+	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+	}
+
+	public void writeExternal(ObjectOutput out) throws IOException {
+	}
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -169,15 +169,19 @@
     protected abstract void internalStart();
     
     public void disconnect() {
-        workingMemory.removeProcessInstance(this);
+        workingMemory.getProcessInstanceManager().internalRemoveProcessInstance(this);
         process = null;
         workingMemory = null;
     }
     
     public void reconnect() {
-        workingMemory.addProcessInstance(this);
+        workingMemory.getProcessInstanceManager().internalAddProcessInstance(this);
     }
 
+    public String[] getEventTypes() {
+    	return null;
+    }
+    
     public String toString() {
         final StringBuffer b = new StringBuffer( "ProcessInstance " );
         b.append( getId() );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -3,6 +3,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
@@ -31,7 +32,9 @@
     public void registerTimer(final Timer timer,
                               ProcessInstance processInstance) {
         timer.setId( ++timerId );
-
+        timer.setProcessInstanceId(processInstance.getId());
+        timer.setActivated(new Date());
+        
         ProcessJobContext ctx = new ProcessJobContext( timer,
                                                        processInstance.getId(),
                                                        this.workingMemory );
@@ -44,6 +47,34 @@
         timers.put(timerId, timer);
     }
 
+    public void internalAddTimer(final Timer timer) {
+		ProcessJobContext ctx = new ProcessJobContext(
+			timer, timer.getProcessInstanceId(), this.workingMemory);
+
+		long delay;
+		Date lastTriggered = timer.getLastTriggered();
+		if (lastTriggered == null) {
+			Date activated = timer.getActivated();
+			Date now = new Date();
+			long timespan = now.getTime() - activated.getTime();
+			delay = timer.getDelay() - timespan;
+			if (delay < 0) {
+				delay = 0;
+			}
+		} else {
+			Date now = new Date();
+			long timespan = now.getTime() - lastTriggered.getTime();
+			delay = timespan - timer.getPeriod();
+			if (delay < 0) {
+				delay = 0;
+			}
+		}
+		JobHandle jobHandle = this.timerService.scheduleJob(
+			ProcessJob.instance, ctx, new TimerTrigger(delay, timer.getPeriod()));
+		timer.setJobHandle(jobHandle);
+		timers.put(timerId, timer);
+	}
+
     public void cancelTimer(long timerId) {
     	Timer timer = timers.get(timerId);
     	if (timer != null) {
@@ -51,9 +82,27 @@
     	}
     }
     
+    public void dispose() {
+    	for (Timer timer: timers.values()) {
+    		timerService.removeJob( timer.getJobHandle() );
+    	}
+    }
+    
     public TimerService getTimerService() {
         return this.timerService;
     }
+    
+    public Collection<Timer> getTimers() {
+    	return timers.values();
+    }
+    
+    public long internalGetTimerId() {
+    	return timerId;
+    }
+    
+    public void internalSetTimerId(long timerId) {
+    	this.timerId = timerId;
+    }
 
     public static class ProcessJob
         implements
@@ -69,6 +118,8 @@
             if ( processInstanceId == null ) {
                 throw new IllegalArgumentException( "Could not find process instance for timer " );
             }
+            
+            ctx.getTimer().setLastTriggered(new Date());
 
             ProcessInstance processInstance = workingMemory.getProcessInstance( processInstanceId );
             // process instance may have finished already

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooStatefulSession.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -111,13 +111,7 @@
 
     public void dispose() {
         this.ruleBase.disposeStatefulSession( this );
-        this.workingMemoryEventSupport.reset();
-        this.agendaEventSupport.reset();
-        this.workflowEventSupport.reset();
-        for ( Iterator it = this.__ruleBaseEventListeners.iterator(); it.hasNext(); ) {
-            this.ruleBase.removeEventListener( (RuleBaseEventListener) it.next() );
-        }
-        this.stopPartitionManagers();
+    	super.dispose();
         this.executor.shutDown();
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -371,7 +371,7 @@
 
     private void processNode(final Node node, final Map<Node, Boolean> nodes) {
         if (!nodes.containsKey(node) ) {
-            throw new IllegalStateException("A process node is connected with a node that does not belong to the process.");
+            throw new IllegalStateException("A process node is connected with a node that does not belong to the process: " + node.getName());
         }
         final Boolean prevValue = (Boolean) nodes.put(node, Boolean.TRUE);
         if (prevValue == Boolean.FALSE) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -26,9 +26,13 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.drools.Agenda;
+import org.drools.WorkingMemory;
 import org.drools.common.EventSupport;
 import org.drools.common.InternalRuleBase;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.event.DefaultRuleFlowEventListener;
+import org.drools.event.RuleFlowCompletedEvent;
+import org.drools.event.RuleFlowEventListener;
 import org.drools.process.instance.EventListener;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.impl.ProcessInstanceImpl;
@@ -40,6 +44,7 @@
 import org.drools.workflow.instance.NodeInstanceContainer;
 import org.drools.workflow.instance.WorkflowProcessInstance;
 import org.drools.workflow.instance.node.EventBasedNodeInstance;
+import org.drools.workflow.instance.node.EventBasedNodeInstanceInterface;
 import org.drools.workflow.instance.node.EventNodeInstanceInterface;
 
 /**
@@ -55,6 +60,7 @@
     private final List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();;
     private long nodeInstanceCounter = 0;
     private Map<String, List<EventListener>> eventListeners = new HashMap<String, List<EventListener>>();
+    private transient RuleFlowEventListener processInstanceEventListener;
 
     public NodeContainer getNodeContainer() {
         return getWorkflowProcess();
@@ -136,6 +142,11 @@
     public WorkflowProcess getWorkflowProcess() {
         return (WorkflowProcess) getProcess();
     }
+    
+    public void start() {
+    	addEventListeners();
+    	super.start();
+    }
 
     public void setState(final int state) {
         super.setState( state );
@@ -150,6 +161,7 @@
                 NodeInstance nodeInstance = (NodeInstance) nodeInstances.get( 0 );
                 nodeInstance.cancel();
             }
+            removeEventListeners();
             workingMemory.removeProcessInstance( this );
             ((EventSupport) workingMemory).getRuleFlowEventSupport()
                 .fireAfterRuleFlowProcessCompleted( this, workingMemory );
@@ -157,6 +169,7 @@
     }
 
     public void disconnect() {
+        removeEventListeners();
         for (NodeInstance nodeInstance: nodeInstances) {
             if (nodeInstance instanceof EventBasedNodeInstance) {
                 ((EventBasedNodeInstance) nodeInstance).removeEventListeners();
@@ -168,10 +181,11 @@
     public void reconnect() {
         super.reconnect();
         for (NodeInstance nodeInstance: nodeInstances) {
-            if (nodeInstance instanceof EventBasedNodeInstance) {
-                ((EventBasedNodeInstance) nodeInstance).addEventListeners();
+            if (nodeInstance instanceof EventBasedNodeInstanceInterface) {
+                ((EventBasedNodeInstanceInterface) nodeInstance).addEventListeners();
             }
         }
+        addEventListeners();
     }
     
     public String toString() {
@@ -219,4 +233,30 @@
     	}
     }
     
+	private void addEventListeners() {
+		// TODO enable ruleflow event listener only when there is a sub-process node instance
+		// actively waiting for the completion of a process instance ?
+    	processInstanceEventListener = new DefaultRuleFlowEventListener() {
+    		public void afterRuleFlowCompleted(RuleFlowCompletedEvent event, WorkingMemory workingMemory) {
+    			ProcessInstance processInstance = event.getProcessInstance();
+    			String type = "processInstanceCompleted:" + processInstance.getId();
+    			List<EventListener> listeners = eventListeners.get(type);
+    	    	if (listeners != null) {
+    	    		for (EventListener listener: listeners) {
+    	    			listener.signalEvent(type, processInstance);
+    	    		}
+    	    	}
+    		}
+    	};
+        getWorkingMemory().addEventListener(processInstanceEventListener);
+    }
+    
+    private void removeEventListeners() {
+    	getWorkingMemory().removeEventListener(processInstanceEventListener);
+    }
+    
+    public String[] getEventTypes() {
+    	return eventListeners.keySet().toArray(new String[eventListeners.size()]);
+    }
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -39,7 +39,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class CompositeNodeInstance extends NodeInstanceImpl implements NodeInstanceContainer, EventNodeInstanceInterface {
+public class CompositeNodeInstance extends NodeInstanceImpl implements NodeInstanceContainer, EventNodeInstanceInterface, EventBasedNodeInstanceInterface {
 
     private static final long serialVersionUID = 400L;
     
@@ -202,4 +202,20 @@
         
     }
 
+	public void addEventListeners() {
+		for (NodeInstance nodeInstance: nodeInstances) {
+            if (nodeInstance instanceof EventBasedNodeInstanceInterface) {
+                ((EventBasedNodeInstanceInterface) nodeInstance).addEventListeners();
+            }
+        }
+	}
+
+	public void removeEventListeners() {
+		for (NodeInstance nodeInstance: nodeInstances) {
+            if (nodeInstance instanceof EventBasedNodeInstanceInterface) {
+                ((EventBasedNodeInstanceInterface) nodeInstance).removeEventListeners();
+            }
+        }
+	}
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -4,7 +4,7 @@
 import org.drools.workflow.core.node.EventBasedNode;
 import org.drools.workflow.instance.impl.ExtendedNodeInstanceImpl;
 
-public abstract class EventBasedNodeInstance extends ExtendedNodeInstanceImpl {
+public abstract class EventBasedNodeInstance extends ExtendedNodeInstanceImpl implements EventBasedNodeInstanceInterface {
 
     public EventBasedNode getEventNode() {
         return (EventBasedNode) getNode();

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstanceInterface.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstanceInterface.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstanceInterface.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,9 @@
+package org.drools.workflow.instance.node;
+
+public interface EventBasedNodeInstanceInterface {
+
+    void addEventListeners();
+    
+    void removeEventListeners();
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -19,14 +19,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.drools.WorkingMemory;
-import org.drools.event.RuleFlowCompletedEvent;
-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.process.core.context.variable.VariableScope;
+import org.drools.process.instance.EventListener;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.workflow.core.Node;
@@ -38,7 +32,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class SubProcessNodeInstance extends EventBasedNodeInstance implements RuleFlowEventListener {
+public class SubProcessNodeInstance extends EventBasedNodeInstance implements EventListener {
 
     private static final long serialVersionUID = 400L;
     
@@ -71,8 +65,8 @@
     	        || processInstance.getState() == ProcessInstance.STATE_COMPLETED) {
     		triggerCompleted();
     	} else {
-    	    addEventListeners();
     		this.processInstanceId = processInstance.getId();
+    	    addEventListeners();
     	}
     }
     
@@ -96,89 +90,38 @@
 
     public void addEventListeners() {
         super.addEventListeners();
-        getProcessInstance().getWorkingMemory().addEventListener(this);
+        getProcessInstance().addEventListener("processInstanceCompleted:" + processInstanceId, this);
     }
 
     public void removeEventListeners() {
         super.removeEventListeners();
-        getProcessInstance().getWorkingMemory().removeEventListener(this);
+        getProcessInstance().removeEventListener("processInstanceCompleted:" + processInstanceId, this);
     }
 
-    public void afterRuleFlowCompleted(RuleFlowCompletedEvent event,
-            WorkingMemory workingMemory) {
-        ProcessInstance processInstance = event.getProcessInstance();
-        if ( processInstance.getId() == processInstanceId ) {
-            removeEventListeners();
-            VariableScopeInstance subProcessVariableScopeInstance = (VariableScopeInstance)
-                processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE);
-            for (Map.Entry<String, String> mapping: getSubProcessNode().getOutMappings().entrySet()) {
-                VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
-                    resolveContextInstance(VariableScope.VARIABLE_SCOPE, mapping.getValue());
-                if (variableScopeInstance != null) {
-                    variableScopeInstance.setVariable(mapping.getValue(), subProcessVariableScopeInstance.getVariable(mapping.getKey()));
-                } else {
-                    System.err.println("Could not find variable scope for variable " + mapping.getValue());
-                    System.err.println("when trying to complete SubProcess node " + getSubProcessNode().getName());
-                    System.err.println("Continuing without setting variable.");
-                }
+	public void signalEvent(String type, Object event) {
+		processInstanceCompleted((ProcessInstance) event);
+	}
+    
+    public String[] getEventTypes() {
+    	return new String[] { "processInstanceCompleted:" + processInstanceId };
+    }
+    
+    public void processInstanceCompleted(ProcessInstance processInstance) {
+        removeEventListeners();
+        VariableScopeInstance subProcessVariableScopeInstance = (VariableScopeInstance)
+            processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE);
+        for (Map.Entry<String, String> mapping: getSubProcessNode().getOutMappings().entrySet()) {
+            VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+                resolveContextInstance(VariableScope.VARIABLE_SCOPE, mapping.getValue());
+            if (variableScopeInstance != null) {
+                variableScopeInstance.setVariable(mapping.getValue(), subProcessVariableScopeInstance.getVariable(mapping.getKey()));
+            } else {
+                System.err.println("Could not find variable scope for variable " + mapping.getValue());
+                System.err.println("when trying to complete SubProcess node " + getSubProcessNode().getName());
+                System.err.println("Continuing without setting variable.");
             }
-            triggerCompleted();
         }
+        triggerCompleted();
     }
 
-    public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void afterRuleFlowGroupDeactivated(
-            RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void afterRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void afterRuleFlowStarted(RuleFlowStartedEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void beforeRuleFlowCompleted(RuleFlowCompletedEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void beforeRuleFlowGroupDeactivated(
-            RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void beforeRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-    public void beforeRuleFlowStarted(RuleFlowStartedEvent event,
-            WorkingMemory workingMemory) {
-        // Do nothing
-    }
-
-	public void afterRuleFlowNodeLeft(RuleFlowNodeTriggeredEvent event,
-			WorkingMemory workingMemory) {
-        // Do nothing
-	}
-
-	public void beforeRuleFlowNodeLeft(RuleFlowNodeTriggeredEvent event,
-			WorkingMemory workingMemory) {
-        // Do nothing
-	}
-
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -53,6 +53,10 @@
     	}
     }
     
+    public String[] getEventTypes() {
+    	return new String[] { "timerTriggered" };
+    }
+    
     public void triggerCompleted(boolean remove) {
         triggerCompleted(Node.CONNECTION_DEFAULT_TYPE, remove);
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -190,6 +190,10 @@
     	} 
     }
 
+    public String[] getEventTypes() {
+    	return new String[] { "workItemCompleted" };
+    }
+    
     public void workItemAborted(WorkItem workItem) {
         if ( getWorkItem().getId() == workItem.getId() ) {
             removeEventListeners();

Modified: labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	2008-09-10 15:21:34 UTC (rev 22597)
@@ -18,4 +18,5 @@
 drools.consequenceExceptionHandler = org.drools.base.DefaultConsequenceExceptionHandler
 drools.ruleBaseUpdateHandler = org.drools.base.FireAllRulesRuleBaseUpdateListener
 drools.workDefinitions = WorkDefinitions.conf
-drools.processInstanceManager = org.drools.process.instance.impl.DefaultProcessInstanceManager
+drools.processInstanceManagerFactory = org.drools.process.instance.impl.DefaultProcessInstanceManagerFactory
+drools.workItemManagerFactory = org.drools.process.instance.impl.DefaultWorkItemManagerFactory

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/RuleBaseConfigurationTest.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -2,14 +2,16 @@
 
 import java.util.Properties;
 
+import junit.framework.TestCase;
+
 import org.drools.RuleBaseConfiguration.AssertBehaviour;
 import org.drools.RuleBaseConfiguration.LogicalOverride;
 import org.drools.RuleBaseConfiguration.SequentialAgenda;
 import org.drools.common.ArrayAgendaGroupFactory;
 import org.drools.common.PriorityQueueAgendaGroupFactory;
+import org.drools.process.instance.impl.demo.SystemOutWorkItemHandler;
+import org.drools.process.instance.impl.demo.UIWorkItemHandler;
 
-import junit.framework.TestCase;
-
 public class RuleBaseConfigurationTest extends TestCase {
 
     public void testSystemProperties() {
@@ -95,6 +97,15 @@
         assertTrue( cfg.isSequential() );
         assertEquals( SequentialAgenda.DYNAMIC, cfg.getSequentialAgenda() );
         assertTrue( cfg.getAgendaGroupFactory() instanceof PriorityQueueAgendaGroupFactory );
-    }    
+    }
+    
+    public void testWorkItemHandlers() {
+    	Properties properties = new Properties();
+        properties.setProperty( "drools.workItemHandlers", "WorkItemHandlers1.conf WorkItemHandlers2.conf" );
+        RuleBaseConfiguration cfg = new RuleBaseConfiguration(properties);
+        assertEquals(cfg.getWorkItemHandlers().size(), 3);
+        assertEquals(cfg.getWorkItemHandlers().get("MyWork").getClass(), SystemOutWorkItemHandler.class);
+        assertEquals(cfg.getWorkItemHandlers().get("UIWork").getClass(), UIWorkItemHandler.class);
+    }
 
 }

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/SubProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/SubProcessTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/SubProcessTest.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,185 @@
+package org.drools.process;
+
+import junit.framework.TestCase;
+
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.common.AbstractRuleBase;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.process.core.Work;
+import org.drools.process.core.impl.WorkImpl;
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.WorkItemHandler;
+import org.drools.process.instance.WorkItemManager;
+import org.drools.reteoo.ReteooWorkingMemory;
+import org.drools.ruleflow.core.RuleFlowProcess;
+import org.drools.spi.Action;
+import org.drools.spi.KnowledgeHelper;
+import org.drools.spi.ProcessContext;
+import org.drools.workflow.core.DroolsAction;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.ConnectionImpl;
+import org.drools.workflow.core.impl.DroolsConsequenceAction;
+import org.drools.workflow.core.node.ActionNode;
+import org.drools.workflow.core.node.EndNode;
+import org.drools.workflow.core.node.StartNode;
+import org.drools.workflow.core.node.SubProcessNode;
+import org.drools.workflow.core.node.WorkItemNode;
+
+public class SubProcessTest extends TestCase {
+
+	private boolean executed = false;
+	private WorkItem workItem;
+	
+	public void setUp() {
+		executed = false;
+		workItem = null;
+	}
+    
+    public void testSynchronousSubProcess() {
+        RuleFlowProcess process = new RuleFlowProcess();
+        process.setId("org.drools.process.process");
+        process.setName("Process");
+        
+        StartNode startNode = new StartNode();
+        startNode.setName("Start");
+        startNode.setId(1);
+        process.addNode(startNode);
+        EndNode endNode = new EndNode();
+        endNode.setName("EndNode");
+        endNode.setId(2);
+        process.addNode(endNode);
+        SubProcessNode subProcessNode = new SubProcessNode();
+        subProcessNode.setName("SubProcessNode");
+        subProcessNode.setId(3);
+        subProcessNode.setProcessId("org.drools.process.subprocess");
+        process.addNode(subProcessNode);
+        new ConnectionImpl(
+            startNode, Node.CONNECTION_DEFAULT_TYPE,
+            subProcessNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        new ConnectionImpl(
+            subProcessNode, Node.CONNECTION_DEFAULT_TYPE,
+            endNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        
+        AbstractRuleBase ruleBase = (AbstractRuleBase) RuleBaseFactory.newRuleBase();
+        ruleBase.addProcess(process);
+        
+        process = new RuleFlowProcess();
+        process.setId("org.drools.process.subprocess");
+        process.setName("SubProcess");
+        
+        startNode = new StartNode();
+        startNode.setName("Start");
+        startNode.setId(1);
+        process.addNode(startNode);
+        endNode = new EndNode();
+        endNode.setName("EndNode");
+        endNode.setId(2);
+        process.addNode(endNode);
+        ActionNode actionNode = new ActionNode();
+        actionNode.setName("Action");
+        DroolsAction action = new DroolsConsequenceAction("java", null);
+        action.setMetaData("Action", new Action() {
+            public void execute(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory, ProcessContext context) throws Exception {
+            	System.out.println("Executed action");
+            	executed = true;
+            }
+        });
+        actionNode.setAction(action);
+        process.addNode(actionNode);
+        new ConnectionImpl(
+            startNode, Node.CONNECTION_DEFAULT_TYPE,
+            actionNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        new ConnectionImpl(
+    		actionNode, Node.CONNECTION_DEFAULT_TYPE,
+            endNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        
+        ruleBase.addProcess(process);
+        
+        InternalWorkingMemory workingMemory = new ReteooWorkingMemory(1, ruleBase);
+        workingMemory.startProcess("org.drools.process.process");
+        assertTrue(executed);
+        assertEquals(0, workingMemory.getProcessInstances().size());
+    }
+
+    public void testAsynchronousSubProcess() {
+        RuleFlowProcess process = new RuleFlowProcess();
+        process.setId("org.drools.process.process");
+        process.setName("Process");
+        
+        StartNode startNode = new StartNode();
+        startNode.setName("Start");
+        startNode.setId(1);
+        process.addNode(startNode);
+        EndNode endNode = new EndNode();
+        endNode.setName("EndNode");
+        endNode.setId(2);
+        process.addNode(endNode);
+        SubProcessNode subProcessNode = new SubProcessNode();
+        subProcessNode.setName("SubProcessNode");
+        subProcessNode.setId(3);
+        subProcessNode.setProcessId("org.drools.process.subprocess");
+        process.addNode(subProcessNode);
+        new ConnectionImpl(
+            startNode, Node.CONNECTION_DEFAULT_TYPE,
+            subProcessNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        new ConnectionImpl(
+            subProcessNode, Node.CONNECTION_DEFAULT_TYPE,
+            endNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        
+        AbstractRuleBase ruleBase = (AbstractRuleBase) RuleBaseFactory.newRuleBase();
+        ruleBase.addProcess(process);
+        
+        process = new RuleFlowProcess();
+        process.setId("org.drools.process.subprocess");
+        process.setName("SubProcess");
+        
+        startNode = new StartNode();
+        startNode.setName("Start");
+        startNode.setId(1);
+        process.addNode(startNode);
+        endNode = new EndNode();
+        endNode.setName("EndNode");
+        endNode.setId(2);
+        process.addNode(endNode);
+        WorkItemNode workItemNode = new WorkItemNode();
+        workItemNode.setName("WorkItem");
+        Work work = new WorkImpl();
+        work.setName("MyWork");
+        workItemNode.setWork(work);
+        process.addNode(workItemNode);
+        new ConnectionImpl(
+            startNode, Node.CONNECTION_DEFAULT_TYPE,
+            workItemNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        new ConnectionImpl(
+    		workItemNode, Node.CONNECTION_DEFAULT_TYPE,
+            endNode, Node.CONNECTION_DEFAULT_TYPE
+        );
+        
+        ruleBase.addProcess(process);
+        
+        InternalWorkingMemory workingMemory = new ReteooWorkingMemory(1, ruleBase);
+        workingMemory.getWorkItemManager().registerWorkItemHandler("MyWork", new WorkItemHandler() {
+			public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+				System.out.println("Executing work item");
+				SubProcessTest.this.workItem = workItem;
+			}
+			public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+			}
+        });
+        workingMemory.startProcess("org.drools.process.process");
+        assertNotNull(workItem);
+        assertEquals(2, workingMemory.getProcessInstances().size());
+        
+        workingMemory.getWorkItemManager().completeWorkItem(workItem.getId(), null);
+        assertEquals(0, workingMemory.getProcessInstances().size());
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/TimerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/TimerTest.java	2008-09-10 15:18:07 UTC (rev 22596)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/TimerTest.java	2008-09-10 15:21:34 UTC (rev 22597)
@@ -27,7 +27,7 @@
         	}
         };
         processInstance.setId(1234);
-        workingMemory.addProcessInstance(processInstance);
+        workingMemory.getProcessInstanceManager().internalAddProcessInstance(processInstance);
         TimerManager timerManager = workingMemory.getTimerManager();
         Timer timer = new Timer();
         timerManager.registerTimer(timer, processInstance);

Added: labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers1.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers1.conf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers1.conf	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,11 @@
+// We use MVEL to return a List of work definitions
+// The properties of the work definitions are specified as a Map<String, Object>
+// The allowed properties are name, parameters, displayName, icon and customEditor
+// The returned result should thus be of type List<Map<String, Object>>
+import org.drools.process.instance.impl.demo.SystemOutWorkItemHandler;
+
+[
+
+  "MyWork" : new SystemOutWorkItemHandler()
+      
+]
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers2.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers2.conf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/resources/META-INF/WorkItemHandlers2.conf	2008-09-10 15:21:34 UTC (rev 22597)
@@ -0,0 +1,13 @@
+// We use MVEL to return a List of work definitions
+// The properties of the work definitions are specified as a Map<String, Object>
+// The allowed properties are name, parameters, displayName, icon and customEditor
+// The returned result should thus be of type List<Map<String, Object>>
+import org.drools.process.instance.impl.demo.DoNothingWorkItemHandler;
+import org.drools.process.instance.impl.demo.UIWorkItemHandler;
+
+[
+
+  "Log" : new DoNothingWorkItemHandler(),
+  "UIWork" : new UIWorkItemHandler()
+    
+]
\ No newline at end of file




More information about the jboss-svn-commits mailing list