[jboss-svn-commits] JBL Code SVN: r29305 - in labs/jbossrules/trunk: drools-persistence-jpa and 6 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Sep 10 17:30:28 EDT 2009


Author: salaboy21
Date: 2009-09-10 17:30:27 -0400 (Thu, 10 Sep 2009)
New Revision: 29305

Added:
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategy.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategyFactory.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/JPAVariablePersister.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/SerializableVariablePersister.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/VariablePersister.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/JPAPersistedVariable.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/SerializablePersistedVariable.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/VariableInstanceInfo.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyEntity.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyVariableSerializable.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariableCheckerTestWorkItemHandler.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariablePersistenceStrategyTest.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcess.rf
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcessTypeChange.rf
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategySubProcess.rf
   labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/testVariables.rf
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/AbstractProcessInstanceMarshaller.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/ProcessInstanceMarshaller.java
   labs/jbossrules/trunk/drools-persistence-jpa/pom.xml
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/JPAProcessInstanceManager.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java
   labs/jbossrules/trunk/drools-persistence-jpa/src/main/resources/META-INF/persistence.xml
Log:
Variable Persistence Strategies for Drools Flow

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/AbstractProcessInstanceMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/AbstractProcessInstanceMarshaller.java	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/AbstractProcessInstanceMarshaller.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -18,6 +18,7 @@
 import org.drools.process.core.context.variable.VariableScope;
 import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 import org.drools.runtime.process.NodeInstance;
 import org.drools.runtime.process.NodeInstanceContainer;
 import org.drools.runtime.process.ProcessInstance;
@@ -43,390 +44,399 @@
  * @author salaboy
  */
 public abstract class AbstractProcessInstanceMarshaller implements
-		ProcessInstanceMarshaller {
+        ProcessInstanceMarshaller {
 
-	// Output methods
+    // Output methods
+    public void writeProcessInstance(MarshallerWriteContext context,
+            ProcessInstance processInstance) throws IOException {
+        writeProcessInstance(context, processInstance, true);
+    }
 
-	public void writeProcessInstance(MarshallerWriteContext context,
-			ProcessInstance processInstance) throws IOException {
+    public void writeProcessInstance(MarshallerWriteContext context,
+            ProcessInstance processInstance, boolean includeVariables) throws IOException {
 
-		WorkflowProcessInstanceImpl workFlow = (WorkflowProcessInstanceImpl) processInstance;
-		ObjectOutputStream stream = context.stream;
-		stream.writeLong(workFlow.getId());
-		stream.writeUTF(workFlow.getProcessId());
-		stream.writeInt(workFlow.getState());
-		stream.writeLong(workFlow.getNodeInstanceCounter());
-		
-		VariableScopeInstance variableScopeInstance = (VariableScopeInstance) workFlow.getContextInstance( VariableScope.VARIABLE_SCOPE );
-        Map<String, Object> variables = variableScopeInstance.getVariables();
-        List<String> keys = new ArrayList<String>( variables.keySet() );
-        Collections.sort( keys,
-                          new Comparator<String>() {
-                              public int compare(String o1,
-                                                 String o2) {
-                                  return o1.compareTo( o2 );
-                              }
-                          } );
-        stream.writeInt( keys.size() );
-        for ( String key : keys ) {
-            stream.writeUTF( key );
-            stream.writeObject( variables.get( key ) );
+        WorkflowProcessInstanceImpl workFlow = (WorkflowProcessInstanceImpl) processInstance;
+        ObjectOutputStream stream = context.stream;
+        stream.writeLong(workFlow.getId());
+        stream.writeUTF(workFlow.getProcessId());
+        stream.writeInt(workFlow.getState());
+        stream.writeLong(workFlow.getNodeInstanceCounter());
+        if (includeVariables) {
+            VariableScopeInstance variableScopeInstance = (VariableScopeInstance) workFlow.getContextInstance(VariableScope.VARIABLE_SCOPE);
+            Map<String, Object> variables = variableScopeInstance.getVariables();
+            List<String> keys = new ArrayList<String>(variables.keySet());
+            Collections.sort(keys,
+                    new Comparator<String>() {
+
+                        public int compare(String o1,
+                                String o2) {
+                            return o1.compareTo(o2);
+                        }
+                    });
+            stream.writeInt(keys.size());
+            for (String key : keys) {
+                stream.writeUTF(key);
+                stream.writeObject(variables.get(key));
+            }
         }
 
-        SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) workFlow.getContextInstance( SwimlaneContext.SWIMLANE_SCOPE );
-        
-        if (swimlaneContextInstance!=null) {
-			Map<String, String> swimlaneActors = swimlaneContextInstance
-					.getSwimlaneActors();
-			stream.writeInt(swimlaneActors.size());
-			for (Map.Entry<String, String> entry : swimlaneActors.entrySet()) {
-				stream.writeUTF(entry.getKey());
-				stream.writeUTF(entry.getValue());
-			}
-		}else{
+        SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) workFlow.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);
+
+        if (swimlaneContextInstance != null) {
+            Map<String, String> swimlaneActors = swimlaneContextInstance.getSwimlaneActors();
+            stream.writeInt(swimlaneActors.size());
+            for (Map.Entry<String, String> entry : swimlaneActors.entrySet()) {
+                stream.writeUTF(entry.getKey());
+                stream.writeUTF(entry.getValue());
+            }
+        } else {
             stream.writeInt(0);
         }
-		List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>( workFlow.getNodeInstances() );
-        Collections.sort( nodeInstances,
-                          new Comparator<NodeInstance>() {
-                              public int compare(NodeInstance o1,
-                                                 NodeInstance o2) {
-                                  return (int) (o1.getId() - o2.getId());
-                              }
-                          } );
-        for ( NodeInstance nodeInstance : nodeInstances ) {
-            stream.writeShort( PersisterEnums.NODE_INSTANCE );
-            writeNodeInstance( context,
-                               nodeInstance );
+        List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>(workFlow.getNodeInstances());
+        Collections.sort(nodeInstances,
+                new Comparator<NodeInstance>() {
+
+                    public int compare(NodeInstance o1,
+                            NodeInstance o2) {
+                        return (int) (o1.getId() - o2.getId());
+                    }
+                });
+        for (NodeInstance nodeInstance : nodeInstances) {
+            stream.writeShort(PersisterEnums.NODE_INSTANCE);
+            writeNodeInstance(context,
+                    nodeInstance);
         }
-        stream.writeShort( PersisterEnums.END );
-	}
+        stream.writeShort(PersisterEnums.END);
+    }
 
-	public void writeNodeInstance(MarshallerWriteContext context,
-			NodeInstance nodeInstance) throws IOException {
-		ObjectOutputStream stream = context.stream;
-		stream.writeLong(nodeInstance.getId());
-		stream.writeLong(nodeInstance.getNodeId());
-		writeNodeInstanceContent(stream, nodeInstance, context);
-	}
+    public void writeNodeInstance(MarshallerWriteContext context,
+            NodeInstance nodeInstance) throws IOException {
+        ObjectOutputStream stream = context.stream;
+        stream.writeLong(nodeInstance.getId());
+        stream.writeLong(nodeInstance.getNodeId());
+        writeNodeInstanceContent(stream, nodeInstance, context);
+    }
 
-	protected void writeNodeInstanceContent(ObjectOutputStream stream,
-			NodeInstance nodeInstance, MarshallerWriteContext context)
-			throws IOException {
-		 if ( nodeInstance instanceof RuleSetNodeInstance ) {
-	            stream.writeShort( PersisterEnums.RULE_SET_NODE_INSTANCE );
-	        } else if ( nodeInstance instanceof HumanTaskNodeInstance ) {
-	            stream.writeShort( PersisterEnums.HUMAN_TASK_NODE_INSTANCE );
-	            stream.writeLong( ((HumanTaskNodeInstance) nodeInstance).getWorkItemId() );
-	        } else if ( nodeInstance instanceof WorkItemNodeInstance ) {
-	            stream.writeShort( PersisterEnums.WORK_ITEM_NODE_INSTANCE );
-	            stream.writeLong( ((WorkItemNodeInstance) nodeInstance).getWorkItemId() );
-	        } else if ( nodeInstance instanceof SubProcessNodeInstance ) {
-	            stream.writeShort( PersisterEnums.SUB_PROCESS_NODE_INSTANCE );
-	            stream.writeLong( ((SubProcessNodeInstance) nodeInstance).getProcessInstanceId() );
-	        } else if ( nodeInstance instanceof MilestoneNodeInstance ) {
-	            stream.writeShort( PersisterEnums.MILESTONE_NODE_INSTANCE );
-	            List<Long> timerInstances = 
-	            	((MilestoneNodeInstance) nodeInstance).getTimerInstances();
-	            if (timerInstances != null) {
-	            	stream.writeInt(timerInstances.size());
-	            	for (Long id: timerInstances) {
-	            		stream.writeLong(id);
-	            	}
-	            } else {
-	            	stream.writeInt(0);
-	            }
-	        } else if ( nodeInstance instanceof TimerNodeInstance ) {
-	            stream.writeShort( PersisterEnums.TIMER_NODE_INSTANCE );
-	            stream.writeLong( ((TimerNodeInstance) nodeInstance).getTimerId() );
-	        } else if ( nodeInstance instanceof JoinInstance ) {
-	            stream.writeShort( PersisterEnums.JOIN_NODE_INSTANCE );
-	            Map<Long, Integer> triggers = ((JoinInstance) nodeInstance).getTriggers();
-	            stream.writeInt( triggers.size() );
-	            List<Long> keys = new ArrayList<Long>( triggers.keySet() );
-	            Collections.sort( keys,
-	                              new Comparator<Long>() {
-	                                  public int compare(Long o1,
-	                                                     Long o2) {
-	                                      return o1.compareTo( o2 );
-	                                  }
-	                              } );
-	            for ( Long key : keys ) {
-	                stream.writeLong( key );
-	                stream.writeInt( triggers.get( key ) );
-	            }
-	        } else if ( nodeInstance instanceof CompositeContextNodeInstance ) {
-	            stream.writeShort( PersisterEnums.COMPOSITE_NODE_INSTANCE );
-	            CompositeContextNodeInstance compositeNodeInstance = (CompositeContextNodeInstance) nodeInstance;
-	            List<Long> timerInstances = 
-	            	((CompositeContextNodeInstance) nodeInstance).getTimerInstances();
-	            if (timerInstances != null) {
-	            	stream.writeInt(timerInstances.size());
-	            	for (Long id: timerInstances) {
-	            		stream.writeLong(id);
-	            	}
-	            } else {
-	            	stream.writeInt(0);
-	            }
-	            VariableScopeInstance variableScopeInstance = (VariableScopeInstance) compositeNodeInstance.getContextInstance( VariableScope.VARIABLE_SCOPE );
-	            Map<String, Object> variables = variableScopeInstance.getVariables();
-	            List<String> keys = new ArrayList<String>( variables.keySet() );
-	            Collections.sort( keys,
-	                              new Comparator<String>() {
-	                                  public int compare(String o1,
-	                                                     String o2) {
-	                                      return o1.compareTo( o2 );
-	                                  }
-	                              } );
-	            stream.writeInt( keys.size() );
-	            for ( String key : keys ) {
-	                stream.writeUTF( key );
-	                stream.writeObject( variables.get( key ) );
-	            }
-	            List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>( compositeNodeInstance.getNodeInstances() );
-	            Collections.sort( nodeInstances,
-	                              new Comparator<NodeInstance>() {
-	                                  public int compare(NodeInstance o1,
-	                                                     NodeInstance o2) {
-	                                      return (int) (o1.getId() - o2.getId());
-	                                  }
-	                              } );
-	            for ( NodeInstance subNodeInstance : nodeInstances ) {
-	                stream.writeShort( PersisterEnums.NODE_INSTANCE );
-	                writeNodeInstance( context,
-	                                   subNodeInstance );
-	            }
-	            stream.writeShort( PersisterEnums.END );
-	        } else if ( nodeInstance instanceof ForEachNodeInstance ) {
-	            stream.writeShort( PersisterEnums.FOR_EACH_NODE_INSTANCE );
-	            ForEachNodeInstance forEachNodeInstance = (ForEachNodeInstance) nodeInstance;
-	            List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>( forEachNodeInstance.getNodeInstances() );
-	            Collections.sort( nodeInstances,
-	                              new Comparator<NodeInstance>() {
-	                                  public int compare(NodeInstance o1,
-	                                                     NodeInstance o2) {
-	                                      return (int) (o1.getId() - o2.getId());
-	                                  }
-	                              } );
-	            for ( NodeInstance subNodeInstance : nodeInstances ) {
-	                if ( subNodeInstance instanceof CompositeContextNodeInstance ) {
-	                    stream.writeShort( PersisterEnums.NODE_INSTANCE );
-	                    writeNodeInstance( context,
-	                                       subNodeInstance );
-	                }
-	            }
-	            stream.writeShort( PersisterEnums.END );
-	        } else if ( nodeInstance instanceof StateNodeInstance ) {
-	            stream.writeShort( PersisterEnums.STATE_NODE_INSTANCE );
-	            List<Long> timerInstances = 
-	            	((StateNodeInstance) nodeInstance).getTimerInstances();
-	            if (timerInstances != null) {
-	            	stream.writeInt(timerInstances.size());
-	            	for (Long id: timerInstances) {
-	            		stream.writeLong(id);
-	            	}
-	            } else {
-	            	stream.writeInt(0);
-	            }
-	        } else {
-	            throw new IllegalArgumentException( "Unknown node instance type: " + nodeInstance );
-	        }
-	}
+    protected void writeNodeInstanceContent(ObjectOutputStream stream,
+            NodeInstance nodeInstance, MarshallerWriteContext context)
+            throws IOException {
+        if (nodeInstance instanceof RuleSetNodeInstance) {
+            stream.writeShort(PersisterEnums.RULE_SET_NODE_INSTANCE);
+        } else if (nodeInstance instanceof HumanTaskNodeInstance) {
+            stream.writeShort(PersisterEnums.HUMAN_TASK_NODE_INSTANCE);
+            stream.writeLong(((HumanTaskNodeInstance) nodeInstance).getWorkItemId());
+        } else if (nodeInstance instanceof WorkItemNodeInstance) {
+            stream.writeShort(PersisterEnums.WORK_ITEM_NODE_INSTANCE);
+            stream.writeLong(((WorkItemNodeInstance) nodeInstance).getWorkItemId());
+        } else if (nodeInstance instanceof SubProcessNodeInstance) {
+            stream.writeShort(PersisterEnums.SUB_PROCESS_NODE_INSTANCE);
+            stream.writeLong(((SubProcessNodeInstance) nodeInstance).getProcessInstanceId());
+        } else if (nodeInstance instanceof MilestoneNodeInstance) {
+            stream.writeShort(PersisterEnums.MILESTONE_NODE_INSTANCE);
+            List<Long> timerInstances =
+                    ((MilestoneNodeInstance) nodeInstance).getTimerInstances();
+            if (timerInstances != null) {
+                stream.writeInt(timerInstances.size());
+                for (Long id : timerInstances) {
+                    stream.writeLong(id);
+                }
+            } else {
+                stream.writeInt(0);
+            }
+        } else if (nodeInstance instanceof TimerNodeInstance) {
+            stream.writeShort(PersisterEnums.TIMER_NODE_INSTANCE);
+            stream.writeLong(((TimerNodeInstance) nodeInstance).getTimerId());
+        } else if (nodeInstance instanceof JoinInstance) {
+            stream.writeShort(PersisterEnums.JOIN_NODE_INSTANCE);
+            Map<Long, Integer> triggers = ((JoinInstance) nodeInstance).getTriggers();
+            stream.writeInt(triggers.size());
+            List<Long> keys = new ArrayList<Long>(triggers.keySet());
+            Collections.sort(keys,
+                    new Comparator<Long>() {
 
-	// Input methods
+                        public int compare(Long o1,
+                                Long o2) {
+                            return o1.compareTo(o2);
+                        }
+                    });
+            for (Long key : keys) {
+                stream.writeLong(key);
+                stream.writeInt(triggers.get(key));
+            }
+        } else if (nodeInstance instanceof CompositeContextNodeInstance) {
+            stream.writeShort(PersisterEnums.COMPOSITE_NODE_INSTANCE);
+            CompositeContextNodeInstance compositeNodeInstance = (CompositeContextNodeInstance) nodeInstance;
+            List<Long> timerInstances =
+                    ((CompositeContextNodeInstance) nodeInstance).getTimerInstances();
+            if (timerInstances != null) {
+                stream.writeInt(timerInstances.size());
+                for (Long id : timerInstances) {
+                    stream.writeLong(id);
+                }
+            } else {
+                stream.writeInt(0);
+            }
+            VariableScopeInstance variableScopeInstance = (VariableScopeInstance) compositeNodeInstance.getContextInstance(VariableScope.VARIABLE_SCOPE);
+            Map<String, Object> variables = variableScopeInstance.getVariables();
+            List<String> keys = new ArrayList<String>(variables.keySet());
+            Collections.sort(keys,
+                    new Comparator<String>() {
 
-	public ProcessInstance readProcessInstance(MarshallerReaderContext context)	throws IOException {
-		ObjectInputStream stream = context.stream;
-		InternalRuleBase ruleBase = context.ruleBase;
-		InternalWorkingMemory wm = context.wm;
+                        public int compare(String o1,
+                                String o2) {
+                            return o1.compareTo(o2);
+                        }
+                    });
+            stream.writeInt(keys.size());
+            for (String key : keys) {
+                stream.writeUTF(key);
+                stream.writeObject(variables.get(key));
+            }
+            List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>(compositeNodeInstance.getNodeInstances());
+            Collections.sort(nodeInstances,
+                    new Comparator<NodeInstance>() {
 
-		WorkflowProcessInstanceImpl processInstance = createProcessInstance();
-		processInstance.setId(stream.readLong());
-		String processId = stream.readUTF();
-		processInstance.setProcessId(processId);
-		Process process = ruleBase.getProcess(processId);
-		if (ruleBase != null) {
-			processInstance.setProcess(process);
-		}
-		processInstance.setState(stream.readInt());
-		long nodeInstanceCounter = stream.readLong();
-		processInstance.setWorkingMemory(wm);
+                        public int compare(NodeInstance o1,
+                                NodeInstance o2) {
+                            return (int) (o1.getId() - o2.getId());
+                        }
+                    });
+            for (NodeInstance subNodeInstance : nodeInstances) {
+                stream.writeShort(PersisterEnums.NODE_INSTANCE);
+                writeNodeInstance(context,
+                        subNodeInstance);
+            }
+            stream.writeShort(PersisterEnums.END);
+        } else if (nodeInstance instanceof ForEachNodeInstance) {
+            stream.writeShort(PersisterEnums.FOR_EACH_NODE_INSTANCE);
+            ForEachNodeInstance forEachNodeInstance = (ForEachNodeInstance) nodeInstance;
+            List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>(forEachNodeInstance.getNodeInstances());
+            Collections.sort(nodeInstances,
+                    new Comparator<NodeInstance>() {
 
-		int nbVariables = stream.readInt();
-		if (nbVariables > 0) {
-			Context variableScope = process
-					.getDefaultContext(VariableScope.VARIABLE_SCOPE);
-			VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
-				processInstance.getContextInstance(variableScope);
-			for (int i = 0; i < nbVariables; i++) {
-				String name = stream.readUTF();
-				try {
-					Object value = stream.readObject();
-					variableScopeInstance.setVariable(name, value);
-				} catch (ClassNotFoundException e) {
-					throw new IllegalArgumentException(
-						"Could not reload variable " + name);
-				}
-			}
-		}
+                        public int compare(NodeInstance o1,
+                                NodeInstance o2) {
+                            return (int) (o1.getId() - o2.getId());
+                        }
+                    });
+            for (NodeInstance subNodeInstance : nodeInstances) {
+                if (subNodeInstance instanceof CompositeContextNodeInstance) {
+                    stream.writeShort(PersisterEnums.NODE_INSTANCE);
+                    writeNodeInstance(context,
+                            subNodeInstance);
+                }
+            }
+            stream.writeShort(PersisterEnums.END);
+        } else if (nodeInstance instanceof StateNodeInstance) {
+            stream.writeShort(PersisterEnums.STATE_NODE_INSTANCE);
+            List<Long> timerInstances =
+                    ((StateNodeInstance) nodeInstance).getTimerInstances();
+            if (timerInstances != null) {
+                stream.writeInt(timerInstances.size());
+                for (Long id : timerInstances) {
+                    stream.writeLong(id);
+                }
+            } else {
+                stream.writeInt(0);
+            }
+        } else {
+            throw new IllegalArgumentException("Unknown node instance type: " + nodeInstance);
+        }
+    }
 
-		int nbSwimlanes = stream.readInt();
-		if (nbSwimlanes > 0) {
-			Context swimlaneContext = process.getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE);
-			SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance)
-				processInstance.getContextInstance(swimlaneContext);
-			for (int i = 0; i < nbSwimlanes; i++) {
-				String name = stream.readUTF();
-				String value = stream.readUTF();
-				swimlaneContextInstance.setActorId(name, value);
-			}
-		}
+    // Input methods
+    public ProcessInstance readProcessInstance(MarshallerReaderContext context) throws IOException {
+        return readProcessInstance(context, true);
+    }
 
-		while (stream.readShort() == PersisterEnums.NODE_INSTANCE) {
-			readNodeInstance(context, processInstance, processInstance);
-		}
+    public ProcessInstance readProcessInstance(MarshallerReaderContext context, boolean includeVariables) throws IOException {
+        ObjectInputStream stream = context.stream;
+        InternalRuleBase ruleBase = context.ruleBase;
+        InternalWorkingMemory wm = context.wm;
 
-		processInstance.internalSetNodeInstanceCounter(nodeInstanceCounter);
-		if (wm != null) {
-			processInstance.reconnect();
-		}
-		return processInstance;
-	}
-	
-	protected abstract WorkflowProcessInstanceImpl createProcessInstance();
-	
-	public NodeInstance readNodeInstance(MarshallerReaderContext context,
-			NodeInstanceContainer nodeInstanceContainer,
-			WorkflowProcessInstance processInstance) throws IOException {
-		ObjectInputStream stream = context.stream;
-		long id = stream.readLong();
-		long nodeId = stream.readLong();
-		int nodeType = stream.readShort();
-		NodeInstanceImpl nodeInstance = readNodeInstanceContent(nodeType,
-				stream, context, processInstance);
+        WorkflowProcessInstanceImpl processInstance = createProcessInstance();
+        processInstance.setId(stream.readLong());
+        String processId = stream.readUTF();
+        processInstance.setProcessId(processId);
+        Process process = ruleBase.getProcess(processId);
+        if (ruleBase != null) {
+            processInstance.setProcess(process);
+        }
+        processInstance.setState(stream.readInt());
+        long nodeInstanceCounter = stream.readLong();
+        processInstance.setWorkingMemory(wm);
+        if (includeVariables) {
+            int nbVariables = stream.readInt();
+            if (nbVariables > 0) {
+                Context variableScope = process.getDefaultContext(VariableScope.VARIABLE_SCOPE);
+                VariableScopeInstance variableScopeInstance = (VariableScopeInstance) processInstance.getContextInstance(variableScope);
+                for (int i = 0; i < nbVariables; i++) {
+                    String name = stream.readUTF();
+                    try {
+                        Object value = stream.readObject();
+                        variableScopeInstance.setVariable(name, value);
+                    } catch (ClassNotFoundException e) {
+                        throw new IllegalArgumentException(
+                                "Could not reload variable " + name);
+                    }
+                }
+            }
+        }
 
-		nodeInstance.setNodeId(nodeId);
-		nodeInstance.setNodeInstanceContainer(nodeInstanceContainer);
-		nodeInstance.setProcessInstance(processInstance);
-		nodeInstance.setId(id);
+        int nbSwimlanes = stream.readInt();
+        if (nbSwimlanes > 0) {
+            Context swimlaneContext = process.getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE);
+            SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) processInstance.getContextInstance(swimlaneContext);
+            for (int i = 0; i < nbSwimlanes; i++) {
+                String name = stream.readUTF();
+                String value = stream.readUTF();
+                swimlaneContextInstance.setActorId(name, value);
+            }
+        }
 
-		switch ( nodeType ) {
-	        case PersisterEnums.COMPOSITE_NODE_INSTANCE :
-	            int nbVariables = stream.readInt();
-	            if ( nbVariables > 0 ) {
-	            	Context variableScope = ((org.drools.process.core.Process)
-            			processInstance.getProcess()).getDefaultContext(VariableScope.VARIABLE_SCOPE);
-	    			VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
-	    				((CompositeContextNodeInstance) nodeInstance).getContextInstance(variableScope);
-	                for ( int i = 0; i < nbVariables; i++ ) {
-	                    String name = stream.readUTF();
-	                    try {
-	                        Object value = stream.readObject();
-	                        variableScopeInstance.setVariable( name,
-	                                                           value );
-	                    } catch ( ClassNotFoundException e ) {
-	                        throw new IllegalArgumentException( "Could not reload variable " + name );
-	                    }
-	                }
-	            }
-	            while ( stream.readShort() == PersisterEnums.NODE_INSTANCE ) {
-	                readNodeInstance( context,
-	                                  (CompositeContextNodeInstance) nodeInstance,
-	                                  processInstance );
-	            }
-	            break;
-	        case PersisterEnums.FOR_EACH_NODE_INSTANCE :
-	            while ( stream.readShort() == PersisterEnums.NODE_INSTANCE ) {
-	                readNodeInstance( context,
-	                                  (ForEachNodeInstance) nodeInstance,
-	                                  processInstance );
-	            }
-	            break;
-	        default :
-	            // do nothing
-	    }
-		
-		return nodeInstance;
-	}
+        while (stream.readShort() == PersisterEnums.NODE_INSTANCE) {
+            readNodeInstance(context, processInstance, processInstance);
+        }
 
-	protected NodeInstanceImpl readNodeInstanceContent(int nodeType,
-			ObjectInputStream stream, MarshallerReaderContext context,
-			WorkflowProcessInstance processInstance) throws IOException {
-		NodeInstanceImpl nodeInstance = null;
-		switch ( nodeType ) {
-        case PersisterEnums.RULE_SET_NODE_INSTANCE :
-            nodeInstance = new RuleSetNodeInstance();
-            break;
-        case PersisterEnums.HUMAN_TASK_NODE_INSTANCE :
-            nodeInstance = new HumanTaskNodeInstance();
-            ((HumanTaskNodeInstance) nodeInstance).internalSetWorkItemId( stream.readLong() );
-            break;
-        case PersisterEnums.WORK_ITEM_NODE_INSTANCE :
-            nodeInstance = new WorkItemNodeInstance();
-            ((WorkItemNodeInstance) nodeInstance).internalSetWorkItemId( stream.readLong() );
-            break;
-        case PersisterEnums.SUB_PROCESS_NODE_INSTANCE :
-            nodeInstance = new SubProcessNodeInstance();
-            ((SubProcessNodeInstance) nodeInstance).internalSetProcessInstanceId( stream.readLong() );
-            break;
-        case PersisterEnums.MILESTONE_NODE_INSTANCE :
-            nodeInstance = new MilestoneNodeInstance();
-            int nbTimerInstances = stream.readInt();
-            if (nbTimerInstances > 0) {
-            	List<Long> timerInstances = new ArrayList<Long>();
-            	for (int i = 0; i < nbTimerInstances; i++) {
-            		timerInstances.add(stream.readLong());
-            	}
-            	((MilestoneNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
-            }
-            break;
-        case PersisterEnums.TIMER_NODE_INSTANCE :
-            nodeInstance = new TimerNodeInstance();
-            ((TimerNodeInstance) nodeInstance).internalSetTimerId( stream.readLong() );
-            break;
-        case PersisterEnums.JOIN_NODE_INSTANCE :
-            nodeInstance = new JoinInstance();
-            int number = stream.readInt();
-            if ( number > 0 ) {
-                Map<Long, Integer> triggers = new HashMap<Long, Integer>();
-                for ( int i = 0; i < number; i++ ) {
-                    long l = stream.readLong();
-                    int count = stream.readInt();
-                    triggers.put( l,
-                                  count );
+        processInstance.internalSetNodeInstanceCounter(nodeInstanceCounter);
+        if (wm != null) {
+            processInstance.reconnect();
+        }
+        return processInstance;
+    }
+
+    protected abstract WorkflowProcessInstanceImpl createProcessInstance();
+
+    public NodeInstance readNodeInstance(MarshallerReaderContext context,
+            NodeInstanceContainer nodeInstanceContainer,
+            WorkflowProcessInstance processInstance) throws IOException {
+        ObjectInputStream stream = context.stream;
+        long id = stream.readLong();
+        long nodeId = stream.readLong();
+        int nodeType = stream.readShort();
+        NodeInstanceImpl nodeInstance = readNodeInstanceContent(nodeType,
+                stream, context, processInstance);
+
+        nodeInstance.setNodeId(nodeId);
+        nodeInstance.setNodeInstanceContainer(nodeInstanceContainer);
+        nodeInstance.setProcessInstance(processInstance);
+        nodeInstance.setId(id);
+
+        switch (nodeType) {
+            case PersisterEnums.COMPOSITE_NODE_INSTANCE:
+                int nbVariables = stream.readInt();
+                if (nbVariables > 0) {
+                    Context variableScope = ((org.drools.process.core.Process) processInstance.getProcess()).getDefaultContext(VariableScope.VARIABLE_SCOPE);
+                    VariableScopeInstance variableScopeInstance = (VariableScopeInstance) ((CompositeContextNodeInstance) nodeInstance).getContextInstance(variableScope);
+                    for (int i = 0; i < nbVariables; i++) {
+                        String name = stream.readUTF();
+                        try {
+                            Object value = stream.readObject();
+                            variableScopeInstance.setVariable(name,
+                                    value);
+                        } catch (ClassNotFoundException e) {
+                            throw new IllegalArgumentException("Could not reload variable " + name);
+                        }
+                    }
                 }
-                ((JoinInstance) nodeInstance).internalSetTriggers( triggers );
-            }
-            break;
-        case PersisterEnums.COMPOSITE_NODE_INSTANCE :
-            nodeInstance = new CompositeContextNodeInstance();
-            nbTimerInstances = stream.readInt();
-            if (nbTimerInstances > 0) {
-            	List<Long> timerInstances = new ArrayList<Long>();
-            	for (int i = 0; i < nbTimerInstances; i++) {
-            		timerInstances.add(stream.readLong());
-            	}
-            	((CompositeContextNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
-            }
-            break;
-        case PersisterEnums.FOR_EACH_NODE_INSTANCE :
-            nodeInstance = new ForEachNodeInstance();
-            break;
-        case PersisterEnums.STATE_NODE_INSTANCE :
-            nodeInstance = new StateNodeInstance();
-            nbTimerInstances = stream.readInt();
-            if (nbTimerInstances > 0) {
-            	List<Long> timerInstances = new ArrayList<Long>();
-            	for (int i = 0; i < nbTimerInstances; i++) {
-            		timerInstances.add(stream.readLong());
-            	}
-            	((CompositeContextNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
-            }
-            break;
-        default :
-            throw new IllegalArgumentException( "Unknown node type: " + nodeType );
-		}
-		return nodeInstance;
+                while (stream.readShort() == PersisterEnums.NODE_INSTANCE) {
+                    readNodeInstance(context,
+                            (CompositeContextNodeInstance) nodeInstance,
+                            processInstance);
+                }
+                break;
+            case PersisterEnums.FOR_EACH_NODE_INSTANCE:
+                while (stream.readShort() == PersisterEnums.NODE_INSTANCE) {
+                    readNodeInstance(context,
+                            (ForEachNodeInstance) nodeInstance,
+                            processInstance);
+                }
+                break;
+            default:
+            // do nothing
+        }
 
-	}
+        return nodeInstance;
+    }
+
+    protected NodeInstanceImpl readNodeInstanceContent(int nodeType,
+            ObjectInputStream stream, MarshallerReaderContext context,
+            WorkflowProcessInstance processInstance) throws IOException {
+        NodeInstanceImpl nodeInstance = null;
+        switch (nodeType) {
+            case PersisterEnums.RULE_SET_NODE_INSTANCE:
+                nodeInstance = new RuleSetNodeInstance();
+                break;
+            case PersisterEnums.HUMAN_TASK_NODE_INSTANCE:
+                nodeInstance = new HumanTaskNodeInstance();
+                ((HumanTaskNodeInstance) nodeInstance).internalSetWorkItemId(stream.readLong());
+                break;
+            case PersisterEnums.WORK_ITEM_NODE_INSTANCE:
+                nodeInstance = new WorkItemNodeInstance();
+                ((WorkItemNodeInstance) nodeInstance).internalSetWorkItemId(stream.readLong());
+                break;
+            case PersisterEnums.SUB_PROCESS_NODE_INSTANCE:
+                nodeInstance = new SubProcessNodeInstance();
+                ((SubProcessNodeInstance) nodeInstance).internalSetProcessInstanceId(stream.readLong());
+                break;
+            case PersisterEnums.MILESTONE_NODE_INSTANCE:
+                nodeInstance = new MilestoneNodeInstance();
+                int nbTimerInstances = stream.readInt();
+                if (nbTimerInstances > 0) {
+                    List<Long> timerInstances = new ArrayList<Long>();
+                    for (int i = 0; i < nbTimerInstances; i++) {
+                        timerInstances.add(stream.readLong());
+                    }
+                    ((MilestoneNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
+                }
+                break;
+            case PersisterEnums.TIMER_NODE_INSTANCE:
+                nodeInstance = new TimerNodeInstance();
+                ((TimerNodeInstance) nodeInstance).internalSetTimerId(stream.readLong());
+                break;
+            case PersisterEnums.JOIN_NODE_INSTANCE:
+                nodeInstance = new JoinInstance();
+                int number = stream.readInt();
+                if (number > 0) {
+                    Map<Long, Integer> triggers = new HashMap<Long, Integer>();
+                    for (int i = 0; i < number; i++) {
+                        long l = stream.readLong();
+                        int count = stream.readInt();
+                        triggers.put(l,
+                                count);
+                    }
+                    ((JoinInstance) nodeInstance).internalSetTriggers(triggers);
+                }
+                break;
+            case PersisterEnums.COMPOSITE_NODE_INSTANCE:
+                nodeInstance = new CompositeContextNodeInstance();
+                nbTimerInstances = stream.readInt();
+                if (nbTimerInstances > 0) {
+                    List<Long> timerInstances = new ArrayList<Long>();
+                    for (int i = 0; i < nbTimerInstances; i++) {
+                        timerInstances.add(stream.readLong());
+                    }
+                    ((CompositeContextNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
+                }
+                break;
+            case PersisterEnums.FOR_EACH_NODE_INSTANCE:
+                nodeInstance = new ForEachNodeInstance();
+                break;
+            case PersisterEnums.STATE_NODE_INSTANCE:
+                nodeInstance = new StateNodeInstance();
+                nbTimerInstances = stream.readInt();
+                if (nbTimerInstances > 0) {
+                    List<Long> timerInstances = new ArrayList<Long>();
+                    for (int i = 0; i < nbTimerInstances; i++) {
+                        timerInstances.add(stream.readLong());
+                    }
+                    ((CompositeContextNodeInstance) nodeInstance).internalSetTimerInstances(timerInstances);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown node type: " + nodeType);
+        }
+        return nodeInstance;
+
+    }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/ProcessInstanceMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/ProcessInstanceMarshaller.java	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/ProcessInstanceMarshaller.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -26,12 +26,16 @@
 
 	public void writeProcessInstance(MarshallerWriteContext context,
 			ProcessInstance processInstance) throws IOException;
+    public void writeProcessInstance(MarshallerWriteContext context,
+			ProcessInstance processInstance, boolean includeVariables) throws IOException;
 
 	public void writeNodeInstance(MarshallerWriteContext context,
 			NodeInstance nodeInstance) throws IOException;
 
 	public ProcessInstance readProcessInstance(MarshallerReaderContext context)
 			throws IOException;
+    public ProcessInstance readProcessInstance(MarshallerReaderContext context,
+            boolean includeVariables) throws IOException;
 
 	public NodeInstance readNodeInstance(MarshallerReaderContext context,
 			NodeInstanceContainer nodeInstanceContainer,

Modified: labs/jbossrules/trunk/drools-persistence-jpa/pom.xml
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/pom.xml	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-persistence-jpa/pom.xml	2009-09-10 21:30:27 UTC (rev 29305)
@@ -69,7 +69,7 @@
     	<dependency>
     		<groupId>com.h2database</groupId>
     		<artifactId>h2</artifactId>
-    		<version>1.0.77</version>
+    		<version>1.1.117</version>
     	</dependency>
     	
     	<dependency>

Modified: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/JPAProcessInstanceManager.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/JPAProcessInstanceManager.java	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/JPAProcessInstanceManager.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -28,7 +28,7 @@
     }
 
     public void addProcessInstance(ProcessInstance processInstance) {
-        ProcessInstanceInfo processInstanceInfo = new ProcessInstanceInfo( processInstance );
+        ProcessInstanceInfo processInstanceInfo = new ProcessInstanceInfo( processInstance, this.workingMemory.getEnvironment() );
         EntityManager em = (EntityManager) this.workingMemory.getEnvironment().get( EnvironmentName.ENTITY_MANAGER );
         em.persist( processInstanceInfo );
         ((ProcessInstance) processInstance).setId( processInstanceInfo.getId() );
@@ -60,7 +60,7 @@
         }
         processInstanceInfo.updateLastReadDate();
         processInstance = (ProcessInstance)
-        	processInstanceInfo.getProcessInstance(workingMemory);
+        	processInstanceInfo.getProcessInstance(workingMemory,this.workingMemory.getEnvironment());
         Process process = ((InternalRuleBase) workingMemory.getRuleBase()).getProcess( processInstance.getProcessId() );
         if ( process == null ) {
             throw new IllegalArgumentException( "Could not find process " + processInstance.getProcessId() );

Modified: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -5,17 +5,27 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
 import javax.persistence.Lob;
+import javax.persistence.MapKey;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import javax.persistence.Transient;
 import javax.persistence.Version;
@@ -27,13 +37,27 @@
 import org.drools.marshalling.impl.MarshallerWriteContext;
 import org.drools.marshalling.impl.ProcessInstanceMarshaller;
 import org.drools.marshalling.impl.ProcessMarshallerRegistry;
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+import org.drools.process.instance.ContextableInstance;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.process.instance.impl.ProcessInstanceImpl;
+import org.drools.runtime.Environment;
+import org.drools.runtime.process.NodeInstance;
+import org.drools.runtime.process.NodeInstanceContainer;
 import org.drools.runtime.process.ProcessInstance;
+import org.drools.runtime.process.WorkflowProcessInstance;
+import org.drools.workflow.instance.impl.WorkflowProcessInstanceImpl;
+import org.drools.workflow.instance.node.CompositeContextNodeInstance;
 import org.hibernate.annotations.CollectionOfElements;
 
 @Entity
 public class ProcessInstanceInfo {
 
+    private static final String VARIABLE_SEPARATOR = ":";
+
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private  Long processInstanceId;
@@ -48,14 +72,17 @@
     private Date lastModificationDate;
     private int state;
     // TODO How do I mark a process instance info as dirty when the process
-    // instance
-    // has changed (so that byte array is regenerated and saved) ?
-    private @Lob
-    byte[] processInstanceByteArray;
-    @CollectionOfElements
-    private Set<String> eventTypes = new HashSet<String>();
-    private @Transient
-    ProcessInstance processInstance;
+	// instance has changed (so that byte array is regenerated and saved) ?
+	private @Lob byte[] processInstanceByteArray;
+	private @CollectionOfElements Set<String> eventTypes = new HashSet<String>();
+	private @Transient ProcessInstance processInstance;
+	private @Transient Environment env;
+	@OneToMany(cascade = CascadeType.ALL)
+	@JoinColumn(name = "processId")
+	@MapKey(name = "name")
+	private Map<String, VariableInstanceInfo> variables =
+		new HashMap<String, VariableInstanceInfo>();
+	private boolean externalVariables = false;
 
     ProcessInstanceInfo() {
     }
@@ -66,6 +93,13 @@
         startDate = new Date();
     }
 
+	public ProcessInstanceInfo(ProcessInstance processInstance, Environment env) {
+		this.processInstance = processInstance;
+		this.processId = processInstance.getProcessId();
+		startDate = new Date();
+		this.env = env;
+	}
+
     public long getId() {
         return processInstanceId;
     }
@@ -94,27 +128,83 @@
         return state;
     }
 
-    public ProcessInstance getProcessInstance(WorkingMemory workingMemory) {
+	public ProcessInstance getProcessInstance(WorkingMemory workingMemory, Environment env) {
+		this.env = env;
         if (processInstance == null) {
             try {
-                ByteArrayInputStream bais = new ByteArrayInputStream(
-                        processInstanceByteArray);
+				ByteArrayInputStream bais =
+					new ByteArrayInputStream(processInstanceByteArray);
                 MarshallerReaderContext context = new MarshallerReaderContext(
-                        bais, (InternalRuleBase) workingMemory.getRuleBase(), null, null);
+					bais, (InternalRuleBase) workingMemory.getRuleBase(),
+					null, null);
                 context.wm = (InternalWorkingMemory) workingMemory;
                 ProcessInstanceMarshaller marshaller = getMarshallerFromContext(context);
-                processInstance = marshaller.readProcessInstance(context);
+				processInstance = marshaller.readProcessInstance(context, !externalVariables);
+				if (externalVariables) {
+					restoreVariables();
+				}
                 context.close();
             } catch (IOException e) {
                 e.printStackTrace();
                 throw new IllegalArgumentException(
-                        "IOException while loading process instance: "
-                                + e.getMessage());
+					"IOException while loading process instance: " + e.getMessage(), e);
             }
         }
         return processInstance;
     }
 
+	private void restoreVariables() {
+		for (Map.Entry<String, VariableInstanceInfo> entry : variables.entrySet()) {
+			String[] variableHierarchy = entry.getKey().split(VARIABLE_SEPARATOR);
+			// last one is variable name
+			String variableName = variableHierarchy[variableHierarchy.length - 1];
+			// other ones are parent ids
+			List<Long> parentIds = new ArrayList<Long>();
+			for (int i = 0; i < variableHierarchy.length - 1; i++) {
+				parentIds.add(Long.valueOf(variableHierarchy[i]));
+			}
+			restoreVariable(entry.getValue(), parentIds, variableName,
+				(WorkflowProcessInstance) processInstance);
+		}
+	}
+
+	private void restoreVariable(VariableInstanceInfo variableInfo,
+			List<Long> parentIds, String variableName,
+			NodeInstanceContainer nodeInstanceContainer)
+			throws NumberFormatException {
+		if (parentIds.size() == 0) {
+			if (!(nodeInstanceContainer instanceof ContextableInstance)) {
+				throw new IllegalArgumentException(
+						"Parent node instance is not a contextable instance: "
+								+ nodeInstanceContainer);
+			}
+			VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+				((ContextableInstance) nodeInstanceContainer)
+					.getContextInstance(VariableScope.VARIABLE_SCOPE);
+			VariablePersistenceStrategy persistenceStrategy =
+				VariablePersistenceStrategyFactory.getVariablePersistenceStrategy();
+			Object value = persistenceStrategy.getVariable(variableInfo, this.env);
+			System.out.println(">>>>> Restoring variable " + variableName + " = " + value);
+			variableScopeInstance.setVariable(variableName, value);
+		} else {
+			Long nodeInstanceId = parentIds.get(0);
+			// find the node and get the variableScopeInstance and insert the
+			// variable..
+			Collection<NodeInstance> nodeInstances =
+				nodeInstanceContainer.getNodeInstances();
+			for (NodeInstance nodeInstance : nodeInstances) {
+				if (nodeInstance.getId() == nodeInstanceId) {
+					parentIds.remove(0);
+					restoreVariable(variableInfo, parentIds, variableName,
+						(CompositeContextNodeInstance) nodeInstance);
+				}
+				return;
+			}
+			throw new IllegalArgumentException("Could not find node instance "
+				+ nodeInstanceId + " in " + nodeInstanceContainer);
+		}
+	}
+
     private ProcessInstanceMarshaller getMarshallerFromContext(
             MarshallerReaderContext context) throws IOException {
         ObjectInputStream stream = context.stream;
@@ -134,15 +224,20 @@
     @PreUpdate
     public void update() {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		boolean variablesChanged = false;
         try {
             MarshallerWriteContext context = new MarshallerWriteContext(baos,
                     null, null, null, null);
-            String processType = ((ProcessInstanceImpl) processInstance).getProcess()
-                    .getType();
-            saveProcessInstanceType(context, processInstance, processType);
-            ProcessInstanceMarshaller marshaller = ProcessMarshallerRegistry.INSTANCE.getMarshaller(processType);
-            marshaller.writeProcessInstance(
-                    context, processInstance);
+			String processType = ((ProcessInstanceImpl) processInstance)
+					.getProcess().getType();
+			saveProcessInstanceType(context, processInstance, processType);
+			ProcessInstanceMarshaller marshaller = ProcessMarshallerRegistry.INSTANCE
+				.getMarshaller(processType);
+			externalVariables = VariablePersistenceStrategyFactory.getVariablePersistenceStrategy().isEnabled();
+			marshaller.writeProcessInstance(context, processInstance, !externalVariables);
+			if (externalVariables) {
+				variablesChanged = persistVariables();
+			}
             context.close();
         } catch (IOException e) {
             throw new IllegalArgumentException(
@@ -150,7 +245,8 @@
                             + processInstance.getId() + ": " + e.getMessage());
         }
         byte[] newByteArray = baos.toByteArray();
-        if (!Arrays.equals(newByteArray, processInstanceByteArray)) {
+		if (variablesChanged
+				|| !Arrays.equals(newByteArray, processInstanceByteArray)) {
             this.state = processInstance.getState();
             this.lastModificationDate = new Date();
             this.processInstanceByteArray = newByteArray;
@@ -159,5 +255,178 @@
                 eventTypes.add(type);
             }
         }
-    }
+	}
+
+        private boolean persistVariables() {
+		// Get Process Variables
+		VariableScopeInstance variableScopeInstance = (VariableScopeInstance) ((WorkflowProcessInstanceImpl) this.processInstance)
+			.getContextInstance(VariableScope.VARIABLE_SCOPE);
+		Map<String, Object> processVariables = variableScopeInstance.getVariables();
+		Map<String, VariableInstanceInfo> newVariables = new HashMap<String, VariableInstanceInfo>();
+		// persist process variables
+		persist(processVariables, "", newVariables);
+		// persist variables in nested variable scopes
+		Collection<NodeInstance> nodeInstances =
+			((WorkflowProcessInstanceImpl) this.processInstance).getNodeInstances();
+		if (nodeInstances.size() > 0) {
+			persistNodeVariables(nodeInstances, "", newVariables);
+                }
+		if (newVariables.size() > 0 || this.variables.size() > 0) {
+			// clear variables so unnecessary values are removed
+			this.variables.clear();
+			this.variables.putAll(newVariables);
+			// TODO: how can I know that no variables were changed?
+			return true;
+		} else {
+			return false;
+                }
+	}
+
+	private void persist(Map<String, Object> variables, String prefix, Map<String, VariableInstanceInfo> newVariables) {
+		VariablePersistenceStrategy persistenceStrategy =
+			VariablePersistenceStrategyFactory.getVariablePersistenceStrategy();
+		for (Map.Entry<String, Object> entries : variables.entrySet()) {
+			String variableName = prefix + entries.getKey();
+			Object value = entries.getValue();
+			VariableInstanceInfo oldValue = this.variables.get(variableName);
+			VariableInstanceInfo variable = persistenceStrategy
+				.persistVariable(variableName, value, oldValue, this.env);
+
+			if (variable != null) {
+                                System.out.println("<<<<< Persisting variable " + variableName + " = " + value);
+				newVariables.put(variableName, variable);
+			}else{
+                                System.out.println("<<<<< Variable " + variableName + " not persisted (value null)");
+                        }
+		}
+	}
+
+	private void persistNodeVariables(Collection<NodeInstance> nodeInstances,
+			String parentPrefix, Map<String, VariableInstanceInfo> newVariables) {
+		for (NodeInstance nodeInstance : nodeInstances) {
+			String prefix = parentPrefix + nodeInstance.getId()
+					+ VARIABLE_SEPARATOR;
+			if (nodeInstance instanceof ContextInstanceContainer) {
+				List<ContextInstance> variableScopeInstances = ((ContextInstanceContainer) nodeInstance)
+						.getContextInstances(VariableScope.VARIABLE_SCOPE);
+				for (ContextInstance contextInstance : variableScopeInstances) {
+					VariableScopeInstance variableScopeInstance = (VariableScopeInstance) contextInstance;
+					persist(variableScopeInstance.getVariables(), prefix, newVariables);
+				}
+			}
+			if (nodeInstance instanceof NodeInstanceContainer) {
+				Collection<NodeInstance> nodeInstancesInsideTheContainer = ((NodeInstanceContainer) nodeInstance)
+						.getNodeInstances();
+				persistNodeVariables(nodeInstancesInsideTheContainer, prefix, newVariables);
+			}
+		}
+	}
+
+	public Map<String, VariableInstanceInfo> getVariables() {
+		return variables;
+	}
+
+	public void setVariables(Map<String, VariableInstanceInfo> variables) {
+		this.variables = variables;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		final ProcessInstanceInfo other = (ProcessInstanceInfo) obj;
+		if (this.processInstanceId != other.processInstanceId
+				&& (this.processInstanceId == null || !this.processInstanceId
+						.equals(other.processInstanceId))) {
+			return false;
+		}
+		if (this.version != other.version) {
+			return false;
+		}
+		if ((this.processId == null) ? (other.processId != null)
+				: !this.processId.equals(other.processId)) {
+			return false;
+		}
+		if (this.startDate != other.startDate
+				&& (this.startDate == null || !this.startDate
+						.equals(other.startDate))) {
+			return false;
+		}
+		if (this.lastReadDate != other.lastReadDate
+				&& (this.lastReadDate == null || !this.lastReadDate
+						.equals(other.lastReadDate))) {
+			return false;
+		}
+		if (this.lastModificationDate != other.lastModificationDate
+				&& (this.lastModificationDate == null || !this.lastModificationDate
+						.equals(other.lastModificationDate))) {
+			return false;
+		}
+		if (this.state != other.state) {
+			return false;
+		}
+		if (!Arrays.equals(this.processInstanceByteArray,
+				other.processInstanceByteArray)) {
+			return false;
+		}
+		if (this.eventTypes != other.eventTypes
+				&& (this.eventTypes == null || !this.eventTypes
+						.equals(other.eventTypes))) {
+			return false;
+		}
+		if (this.processInstance != other.processInstance
+				&& (this.processInstance == null || !this.processInstance
+						.equals(other.processInstance))) {
+			return false;
+		}
+		if (this.env != other.env
+				&& (this.env == null || !this.env.equals(other.env))) {
+			return false;
+		}
+		if (this.variables != other.variables
+				&& (this.variables == null || !this.variables
+						.equals(other.variables))) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int hash = 7;
+		hash = 61
+				* hash
+				+ (this.processInstanceId != null ? this.processInstanceId
+						.hashCode() : 0);
+		hash = 61 * hash + this.version;
+		hash = 61 * hash
+				+ (this.processId != null ? this.processId.hashCode() : 0);
+		hash = 61 * hash
+				+ (this.startDate != null ? this.startDate.hashCode() : 0);
+		hash = 61
+				* hash
+				+ (this.lastReadDate != null ? this.lastReadDate.hashCode() : 0);
+		hash = 61
+				* hash
+				+ (this.lastModificationDate != null ? this.lastModificationDate
+						.hashCode()
+						: 0);
+		hash = 61 * hash + this.state;
+		hash = 61 * hash + Arrays.hashCode(this.processInstanceByteArray);
+		hash = 61 * hash
+				+ (this.eventTypes != null ? this.eventTypes.hashCode() : 0);
+		hash = 61
+				* hash
+				+ (this.processInstance != null ? this.processInstance
+						.hashCode() : 0);
+		hash = 61 * hash + (this.env != null ? this.env.hashCode() : 0);
+		hash = 61 * hash
+				+ (this.variables != null ? this.variables.hashCode() : 0);
+		return hash;
+	}
+
 }

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategy.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategy.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategy.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,159 @@
+package org.drools.persistence.processinstance;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.drools.persistence.processinstance.persisters.VariablePersister;
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.runtime.Environment;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+public class VariablePersistenceStrategy {
+
+	// map of variable persisters per type
+	private Map<String, String> types = new HashMap<String, String>();
+	// cache of already instantiated variable persisters
+	private Map<String, VariablePersister> variablePersisters =
+		new HashMap<String, VariablePersister>();
+	
+	public void setPersister(String type, String persisterClassname) {
+		types.put(type, persisterClassname);
+	}
+	
+	public boolean isEnabled() {
+		return !types.isEmpty();
+	}
+	
+	public VariableInstanceInfo persistVariable(String name, Object o,
+			VariableInstanceInfo oldValue, Environment env) {
+		VariablePersister persister = getVariablePersister(o);
+		VariableInstanceInfo variable = null;
+		if (persister != null) {
+			variable = persister.persistExternalVariable(name, o, oldValue, env);
+		}
+		return variable;
+	}
+
+	@SuppressWarnings("unchecked")
+	private VariablePersister getVariablePersister(Object o) {
+		VariablePersister persister = null;
+		String persisterFQN = getVariablePersistenceType(o);
+		if (persisterFQN != null && !persisterFQN.equals("")) {
+			Class<VariablePersister> persisterClass = null;
+			persister = variablePersisters.get(persisterFQN);
+			if (persister != null) {
+				return persister;
+			}
+			try {
+				persisterClass = (Class<VariablePersister>) Class.forName(persisterFQN);
+				Constructor<VariablePersister> constructor = persisterClass.getConstructor();
+				persister = (VariablePersister) constructor.newInstance();
+				variablePersisters.put(persisterFQN, persister);
+				return persister;
+			} catch (ClassNotFoundException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (NoSuchMethodException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (SecurityException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (InstantiationException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (IllegalAccessException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (IllegalArgumentException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			} catch (InvocationTargetException ex) {
+				Logger.getLogger(VariablePersistenceStrategy.class.getName())
+						.log(Level.SEVERE, null, ex);
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	public Object getVariable(VariableInstanceInfo variableInfo, Environment env) {
+		try {
+			String persisterFQN = variableInfo.getPersister();
+			VariablePersister persister = variablePersisters.get(persisterFQN);
+			if (persister == null) {
+				Class<VariablePersister> clazz = (Class<VariablePersister>) Class.forName(persisterFQN);
+				Constructor<VariablePersister> constructor = clazz.getDeclaredConstructor();
+				persister = (VariablePersister) constructor.newInstance();
+				variablePersisters.put(persisterFQN, persister);
+			}
+			return persister.getExternalPersistedVariable(variableInfo, env);
+		} catch (InstantiationException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (IllegalAccessException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (IllegalArgumentException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (InvocationTargetException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (NoSuchMethodException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (SecurityException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (ClassNotFoundException ex) {
+			ex.printStackTrace();
+			Logger.getLogger(VariablePersistenceStrategy.class.getName())
+				.log(Level.SEVERE, null, ex);
+		}
+		return null;
+	}
+
+	private String getVariablePersistenceType(Object o) {
+		if (o == null) {
+			return null;
+		}
+		Annotation[] annotations = o.getClass().getDeclaredAnnotations();
+		if (annotations != null) {
+			// First annotations, because annotations have more precedence
+			for (Annotation annotation : annotations) {
+				String persisterFQN = types.get(annotation.annotationType().getName());
+				if (persisterFQN != null && !persisterFQN.equals("")) {
+					return persisterFQN;
+				}
+			}
+		}
+		// Then interfaces
+		Class<?>[] interfaces = o.getClass().getInterfaces();
+		if (interfaces != null) {
+			for (Class<?> clazz : interfaces) {
+				String persisterFQN = types.get(clazz.getName());
+				if (persisterFQN != null && !persisterFQN.equals("")) {
+					return persisterFQN;
+				}
+			}
+		}
+		return null;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategyFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategyFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/VariablePersistenceStrategyFactory.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,48 @@
+package org.drools.persistence.processinstance;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+public class VariablePersistenceStrategyFactory {
+	
+	private static VariablePersistenceStrategy INSTANCE;
+
+	public static VariablePersistenceStrategy getVariablePersistenceStrategy() {
+		if (INSTANCE == null) {
+			INSTANCE = new VariablePersistenceStrategy();
+			loadPersisters();
+		}
+		return INSTANCE;
+	}
+	
+	private static VariablePersistenceStrategy loadPersisters() {
+		Properties props = new Properties();
+		try {
+			InputStream is = Thread.currentThread().getContextClassLoader()
+				.getResourceAsStream("META-INF/PersistenceStrategies.conf");
+			if (is != null) {
+				props.load(is);
+			}
+		} catch (IOException ex) {
+			Logger.getLogger(VariablePersistenceStrategyFactory.class.getName())
+				.log(Level.SEVERE, null, ex);
+		}
+		if (INSTANCE == null) {
+			INSTANCE = new VariablePersistenceStrategy();
+		}
+		for (Entry<Object, Object> entry : props.entrySet()) {
+			INSTANCE.setPersister((String) entry.getKey(), (String) entry.getValue());
+		}
+		return INSTANCE;
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/JPAVariablePersister.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/JPAVariablePersister.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/JPAVariablePersister.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,104 @@
+package org.drools.persistence.processinstance.persisters;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Id;
+
+import org.drools.persistence.processinstance.variabletypes.JPAPersistedVariable;
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.runtime.Environment;
+import org.drools.runtime.EnvironmentName;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+public class JPAVariablePersister implements VariablePersister {
+
+	public VariableInstanceInfo persistExternalVariable(String name, Object o,
+			VariableInstanceInfo oldValue, Environment env) {
+                if(o == null || (oldValue != null && oldValue.getPersister().equals(""))){
+                    return null;
+                }
+		try {
+			boolean newVariable = false;
+                        EntityManager em = (EntityManager) env.get(EnvironmentName.ENTITY_MANAGER);
+			JPAPersistedVariable result = null;
+			if (oldValue instanceof JPAPersistedVariable) {
+				result = (JPAPersistedVariable) oldValue;
+			}
+			if (result == null) {
+				result = new JPAPersistedVariable();
+				
+				newVariable = true;
+			}
+			Long idValue = getClassIdValue(o);
+			if (idValue != null) {
+                                System.out.println("Variable "+name +" -> Updating external Entity = "+o);
+				em.merge(o);
+			} else {
+                                System.out.println("Variable "+name +" -> Persisting external Entity for the first time ="+o);
+				em.persist(o);
+				idValue = getClassIdValue(o);
+			}
+			result.setPersister(this.getClass().getName());
+                        result.setName(name);
+                        // entity might have changed, updating info
+			result.setEntityId(idValue);
+			result.setEntity(o);
+			result.setEntityClass(o.getClass().getCanonicalName());
+                        if(newVariable){
+                            em.persist(result);
+                        }else{
+                            em.merge(result);
+                        }
+			System.out.println("Saving JPAPersistedVariable id=" + result.getId() + " entityId=" + result.getEntityId() + " class=" + result.getEntityClass() + " value=" + result.getEntity());
+			return result;
+		} catch (Throwable t) {
+			Logger.getLogger(JPAVariablePersister.class.getName())
+				.log(Level.SEVERE, null, t);
+			throw new RuntimeException("Could not persist external variable", t);
+		}
+	}
+
+	public Object getExternalPersistedVariable(
+			VariableInstanceInfo variableInstanceInfo, Environment env) {
+		EntityManager em = (EntityManager) env.get(EnvironmentName.ENTITY_MANAGER);
+                if(((JPAPersistedVariable) variableInstanceInfo) == null || ((JPAPersistedVariable) variableInstanceInfo).getEntityId() == null){
+                    return null;
+                }
+		System.out.println("Restoring JPAPersistedVariable id=" + ((JPAPersistedVariable) variableInstanceInfo).getId() + " entityId=" + ((JPAPersistedVariable) variableInstanceInfo).getEntityId() + " class=" + ((JPAPersistedVariable) variableInstanceInfo).getEntityClass() + " value=" + ((JPAPersistedVariable) variableInstanceInfo).getEntity());
+		try {
+			String varType = ((JPAPersistedVariable) variableInstanceInfo).getEntityClass();
+			return em.find(Class.forName(varType),
+				((JPAPersistedVariable) variableInstanceInfo).getEntityId());
+		} catch (ClassNotFoundException ex) {
+			Logger.getLogger(JPAVariablePersister.class.getName())
+				.log(Level.SEVERE, null, ex);
+			throw new RuntimeException("Could not restore external variable", ex);
+		}
+	}
+
+	private Long getClassIdValue(Object o) throws NoSuchMethodException,
+			SecurityException, IllegalAccessException,
+			InvocationTargetException, IllegalArgumentException {
+		Field[] fields = o.getClass().getDeclaredFields();
+		Long idValue = null;
+		for (int i = 0; i < fields.length; i++) {
+			Id id = fields[i].getAnnotation(Id.class);
+			if (id != null) {
+				idValue = (Long) o.getClass().getMethod("get"
+					+ Character.toUpperCase(fields[i].getName().charAt(0))
+					+ fields[i].getName().substring(1),
+					new Class<?>[] {}).invoke(o, new Object[] {});
+				break;
+			}
+		}
+		return idValue;
+	}
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/SerializableVariablePersister.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/SerializableVariablePersister.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/SerializableVariablePersister.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,111 @@
+package org.drools.persistence.processinstance.persisters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.persistence.EntityManager;
+
+import org.drools.persistence.processinstance.variabletypes.SerializablePersistedVariable;
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.runtime.Environment;
+import org.drools.runtime.EnvironmentName;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+public class SerializableVariablePersister implements VariablePersister {
+
+	public VariableInstanceInfo persistExternalVariable(String name, Object o,
+			VariableInstanceInfo oldValue, Environment env) {
+                boolean newVariable = false;
+		EntityManager em = (EntityManager) env.get(EnvironmentName.ENTITY_MANAGER);
+		SerializablePersistedVariable result = null;
+                if(o == null || (oldValue != null && oldValue.getPersister().equals(""))){
+                    return null;
+                }
+		if (oldValue instanceof SerializablePersistedVariable) {
+			result = (SerializablePersistedVariable) oldValue;
+		}
+		if (result == null) {
+			result = new SerializablePersistedVariable();
+			newVariable = true;
+			
+		}
+                result.setPersister(this.getClass().getName());
+                result.setName(name);
+		result.setContent(getBytes(o));
+                if(newVariable){
+                    em.persist(result);
+                }else{
+                    em.merge(result);
+                }
+                
+		return result;
+	}
+
+	public Object getExternalPersistedVariable(
+			VariableInstanceInfo variableInstanceInfo, Environment env) {
+		ObjectInputStream ois = null;
+		byte[] binaryArray = null;
+                if(((SerializablePersistedVariable) variableInstanceInfo) == null || ((SerializablePersistedVariable) variableInstanceInfo).getContent() == null){
+                    return null;
+                }
+		try {
+			binaryArray = ((SerializablePersistedVariable) variableInstanceInfo).getContent();
+			if (binaryArray == null) {
+				return null;
+			}
+			ByteArrayInputStream strmBytes = new ByteArrayInputStream(binaryArray);
+			ois = new ObjectInputStream(strmBytes);
+			return ois.readObject();
+		} catch (IOException ex) {
+			Logger.getLogger(SerializableVariablePersister.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} catch (ClassNotFoundException ex) {
+			Logger.getLogger(JPAVariablePersister.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} finally {
+			try {
+				if (ois != null) {
+					ois.close();
+				}
+			} catch (IOException ex) {
+				Logger.getLogger(SerializableVariablePersister.class.getName())
+					.log(Level.SEVERE, null, ex);
+			}
+		}
+		return null;
+	}
+
+	private byte[] getBytes(Object o) {
+		ObjectOutputStream oos = null;
+		try {
+			ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			oos = new ObjectOutputStream(bos);
+			oos.writeObject(o);
+			oos.flush();
+			oos.close();
+			bos.close();
+			byte[] data = bos.toByteArray();
+			return data;
+		} catch (IOException ex) {
+			Logger.getLogger(SerializableVariablePersister.class.getName())
+				.log(Level.SEVERE, null, ex);
+		} finally {
+			try {
+				oos.close();
+			} catch (IOException ex) {
+				Logger.getLogger(SerializableVariablePersister.class.getName())
+					.log(Level.SEVERE, null, ex);
+			}
+		}
+		return null;
+	}
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/VariablePersister.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/VariablePersister.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/persisters/VariablePersister.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,23 @@
+package org.drools.persistence.processinstance.persisters;
+
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.runtime.Environment;
+
+/**
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+public interface VariablePersister {
+    
+    VariableInstanceInfo persistExternalVariable(
+		String name,
+		Object o,
+		VariableInstanceInfo oldValue,
+		Environment env);
+
+    Object getExternalPersistedVariable(
+		VariableInstanceInfo variableInstanceInfo,
+		Environment env);
+
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/JPAPersistedVariable.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/JPAPersistedVariable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/JPAPersistedVariable.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,71 @@
+package org.drools.persistence.processinstance.variabletypes;
+
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+ at Entity
+public class JPAPersistedVariable extends VariableInstanceInfo {
+
+	private static final long serialVersionUID = 300L;
+
+	@Transient
+	private Object entity;
+	private String entityClass;
+	private Long entityId;
+
+	public String getEntityClass() {
+		return entityClass;
+	}
+
+	public void setEntityClass(String entityClass) {
+		this.entityClass = entityClass;
+	}
+
+	public Long getEntityId() {
+		return entityId;
+	}
+
+	public void setEntityId(Long varid) {
+		this.entityId = varid;
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+
+	public void setEntity(Object entity) {
+		this.entity = entity;
+	}
+	
+	public String toString() {
+		return super.toString() + " entityId=" + entityId + " entityClass=" + entityClass;
+	}
+	
+    @Override
+    public boolean equals(Object obj) {
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final JPAPersistedVariable other = (JPAPersistedVariable) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        if ((this.entityClass == null) ? (other.entityClass != null) : !this.entityClass.equals(other.entityClass)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        hash = 41 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        hash = 41 * hash + (this.entityClass != null ? this.entityClass.hashCode() : 0);
+        return hash;
+    }
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/SerializablePersistedVariable.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/SerializablePersistedVariable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/SerializablePersistedVariable.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,53 @@
+package org.drools.persistence.processinstance.variabletypes;
+
+import java.util.Arrays;
+import javax.persistence.Entity;
+import javax.persistence.Lob;
+
+/**
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+ at Entity
+public class SerializablePersistedVariable extends VariableInstanceInfo {
+
+	private static final long serialVersionUID = 300L;
+	
+	@Lob
+    private byte[] content;
+
+    public byte[] getContent() {
+        return content;
+    }
+
+    public void setContent(byte[] content) {
+        this.content = content;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final SerializablePersistedVariable other = (SerializablePersistedVariable) obj;
+        if (!Arrays.equals(this.content, other.content)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        hash = 41 * hash + Arrays.hashCode(this.content);
+        return hash;
+    }
+    
+    public String toString() {
+    	return super.toString() + " byteSize=" + (content == null ? 0 : content.length); 
+    }
+
+  
+
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/VariableInstanceInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/VariableInstanceInfo.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/java/org/drools/persistence/processinstance/variabletypes/VariableInstanceInfo.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,90 @@
+package org.drools.persistence.processinstance.variabletypes;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+/**
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ * @author salaboy
+ */
+ at Entity
+ at Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+ at DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=50)
+ at DiscriminatorValue("GEN")
+
+public class VariableInstanceInfo implements Serializable {
+	
+	private static final long serialVersionUID = 300L;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	private Long id;
+    private String name;
+    private String persister;
+
+    public Long getId() {
+		return id;
+	}
+
+	public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPersister() {
+        return persister;
+    }
+
+    public void setPersister(String persister) {
+        this.persister = persister;
+    }
+    
+    public String toString() {
+    	return getClass().getName() + " id=" + id + " name=" + name + " persister=" + persister;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final VariableInstanceInfo other = (VariableInstanceInfo) obj;
+        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
+            return false;
+        }
+        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+            return false;
+        }
+        if ((this.persister == null) ? (other.persister != null) : !this.persister.equals(other.persister)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 41 * hash + (this.id != null ? this.id.hashCode() : 0);
+        hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
+        hash = 41 * hash + (this.persister != null ? this.persister.hashCode() : 0);
+        return hash;
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-persistence-jpa/src/main/resources/META-INF/persistence.xml
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/main/resources/META-INF/persistence.xml	2009-09-10 21:01:12 UTC (rev 29304)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/main/resources/META-INF/persistence.xml	2009-09-10 21:30:27 UTC (rev 29305)
@@ -1,34 +1,25 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<persistence
-    version="1.0"
-    xsi:schemaLocation=
-    	"http://java.sun.com/xml/ns/persistence
-    	 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
-		 http://java.sun.com/xml/ns/persistence/orm 
-		 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
-    xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns="http://java.sun.com/xml/ns/persistence">
-
- <!--persistence-unit name="ProcessService">
-  <jta-data-source>java:/DefaultDS</jta-data-source>
-  <properties>
-   <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
-  </properties>
- </persistence-unit-->
-
-    <persistence-unit name="org.drools.persistence.jpa" transaction-type="JTA">
-        <provider>org.hibernate.ejb.HibernatePersistence</provider>
-        <jta-data-source>jdbc/testDS1</jta-data-source>        
-        <class>org.drools.persistence.session.SessionInfo</class>
-
-	    <properties>
-	        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>	        
-	        <property name="hibernate.max_fetch_depth" value="3"/>
-		    <property name="hibernate.hbm2ddl.auto" value="update" />
-            <property name="hibernate.show_sql" value="false" />	
-            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
-	    </properties>        
-    </persistence-unit>
-    
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd    http://java.sun.com/xml/ns/persistence/orm     http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
+ <!--persistence-unit name="ProcessService">
+  <jta-data-source>java:/DefaultDS</jta-data-source>
+  <properties>
+   <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+  </properties>
+ </persistence-unit-->
+    <persistence-unit name="org.drools.persistence.jpa" transaction-type="JTA">
+        <provider>org.hibernate.ejb.HibernatePersistence</provider>
+        <jta-data-source>jdbc/testDS1</jta-data-source>        
+        <class>org.drools.persistence.session.SessionInfo</class>
+    <class>org.drools.persistence.processinstance.ProcessInstanceInfo</class>
+    <class>org.drools.persistence.session.MyEntity</class>
+    <class>org.drools.persistence.processinstance.variabletypes.JPAPersistedVariable</class>
+    <class>org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo</class>
+	    <properties>
+	        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>	        
+	        <property name="hibernate.max_fetch_depth" value="3"/>
+		    <property name="hibernate.hbm2ddl.auto" value="update" />
+            <property name="hibernate.show_sql" value="false" />	
+            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
+	    </properties>        
+    </persistence-unit>
 </persistence>
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyEntity.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyEntity.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyEntity.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,87 @@
+package org.drools.persistence.session;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+/**
+ *
+ * @author salaboy
+ */
+ at Entity
+public class MyEntity implements Serializable {
+
+
+	private static final long serialVersionUID = 1L;
+	
+	@Id @GeneratedValue(strategy=GenerationType.AUTO)
+    private Long id;
+    private String test;
+
+    public MyEntity(){}
+
+    public MyEntity(String string) {
+        this.test= string;
+    }
+
+    /**
+     * @return the id
+     */
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * @param id the id to set
+     */
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the test
+     */
+    public String getTest() {
+        return test;
+    }
+
+    /**
+     * @param test the test to set
+     */
+    public void setTest(String test) {
+        this.test = test;
+    }
+    public String toString(){
+        return "VARIABLE: " +this.getId() + " - " + this.getTest();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final MyEntity other = (MyEntity) obj;
+        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
+            return false;
+        }
+        if ((this.test == null) ? (other.test != null) : !this.test.equals(other.test)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 41 * hash + (this.id != null ? this.id.hashCode() : 0);
+        hash = 41 * hash + (this.test != null ? this.test.hashCode() : 0);
+        return hash;
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyVariableSerializable.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyVariableSerializable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/MyVariableSerializable.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,59 @@
+package org.drools.persistence.session;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author salaboy
+ */
+public class MyVariableSerializable implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	
+	private String text = "";
+
+    public MyVariableSerializable(String string) {
+        this.text = string;
+    }
+
+    /**
+     * @return the text
+     */
+    public String getText() {
+        return text;
+    }
+
+    /**
+     * @param text the text to set
+     */
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final MyVariableSerializable other = (MyVariableSerializable) obj;
+        if ((this.text == null) ? (other.text != null) : !this.text.equals(other.text)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 37 * hash + (this.text != null ? this.text.hashCode() : 0);
+        return hash;
+    }
+
+    public String toString(){
+        return "Serializable Variable: "+this.getText();
+    }
+
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariableCheckerTestWorkItemHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariableCheckerTestWorkItemHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariableCheckerTestWorkItemHandler.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,33 @@
+package org.drools.persistence.session;
+
+import org.drools.runtime.process.WorkItem;
+import org.drools.runtime.process.WorkItemHandler;
+import org.drools.runtime.process.WorkItemManager;
+
+public class VariableCheckerTestWorkItemHandler implements WorkItemHandler {
+
+	private static VariableCheckerTestWorkItemHandler INSTANCE = new VariableCheckerTestWorkItemHandler();
+	
+	private WorkItem workItem;
+	
+	private VariableCheckerTestWorkItemHandler() {
+	}
+	
+	public static VariableCheckerTestWorkItemHandler getInstance() {
+		return INSTANCE;
+	}
+	
+	public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+		this.workItem = workItem;
+	}
+
+	public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+	}
+	
+	public WorkItem getWorkItem() {
+		WorkItem result = workItem;
+		workItem = null;
+		return result;
+	}
+
+}

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariablePersistenceStrategyTest.java
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariablePersistenceStrategyTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/java/org/drools/persistence/session/VariablePersistenceStrategyTest.java	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,274 @@
+package org.drools.persistence.session;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import junit.framework.TestCase;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.base.MapGlobalResolver;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderError;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.io.impl.ClassPathResource;
+import org.drools.persistence.jpa.JPAKnowledgeService;
+import org.drools.persistence.processinstance.VariablePersistenceStrategyFactory;
+import org.drools.persistence.processinstance.variabletypes.VariableInstanceInfo;
+import org.drools.runtime.Environment;
+import org.drools.runtime.EnvironmentName;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.process.ProcessInstance;
+import org.drools.runtime.process.WorkItem;
+import org.drools.runtime.process.WorkflowProcessInstance;
+
+import bitronix.tm.resource.jdbc.PoolingDataSource;
+
+public class VariablePersistenceStrategyTest extends TestCase {
+
+    PoolingDataSource ds1;
+
+    @Override
+    protected void setUp() throws Exception {
+        ds1 = new PoolingDataSource();
+        ds1.setUniqueName( "jdbc/testDS1" );
+        ds1.setClassName( "org.h2.jdbcx.JdbcDataSource" );
+        ds1.setMaxPoolSize( 3 );
+        ds1.setAllowLocalTransactions( true );
+        ds1.getDriverProperties().put( "user",
+                                       "sa" );
+        ds1.getDriverProperties().put( "password",
+                                       "sasa" );
+        ds1.getDriverProperties().put( "URL",
+                                       "jdbc:h2:mem:mydb" );
+        ds1.init();
+        VariablePersistenceStrategyFactory.getVariablePersistenceStrategy()
+        	.setPersister("javax.persistence.Entity",
+				"org.drools.persistence.processinstance.persisters.JPAVariablePersister");
+        VariablePersistenceStrategyFactory.getVariablePersistenceStrategy()
+	    	.setPersister("java.io.Serializable",
+				"org.drools.persistence.processinstance.persisters.SerializableVariablePersister");
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        ds1.close();
+    }
+
+    public void testPersistenceVariables() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( new ClassPathResource( "VariablePersistenceStrategyProcess.rf" ), ResourceType.DRF );
+        for (KnowledgeBuilderError error: kbuilder.getErrors()) {
+        	System.out.println(error);
+        }
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        EntityManagerFactory emf = 
+			Persistence.createEntityManagerFactory("org.drools.persistence.jpa");
+        Environment env = KnowledgeBaseFactory.newEnvironment();
+        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
+		env.set(EnvironmentName.GLOBALS, new MapGlobalResolver());
+
+        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
+        int id = ksession.getId();
+
+        System.out.println("### Starting process ###");
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("x", "SomeString");
+        parameters.put("y", new MyEntity("This is a test Entity"));
+        parameters.put("z", new MyVariableSerializable("This is a test SerializableObject"));
+        WorkflowProcessInstance processInstance = (WorkflowProcessInstance)
+        	ksession.startProcess( "com.sample.ruleflow", parameters );
+
+        TestWorkItemHandler handler = TestWorkItemHandler.getInstance();
+        WorkItem workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+        
+        List<?> result = emf.createEntityManager().createQuery("select i from VariableInstanceInfo i").getResultList();
+        assertEquals(3, result.size());
+
+        System.out.println("### Retrieving process instance ###");
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = (WorkflowProcessInstance) 
+        	ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        assertEquals("SomeString", processInstance.getVariable("x"));
+        assertEquals("This is a test Entity", ((MyEntity) processInstance.getVariable("y")).getTest());
+        assertEquals("This is a test SerializableObject", ((MyVariableSerializable) processInstance.getVariable("z")).getText());
+        assertNull(processInstance.getVariable("a"));
+        assertNull(processInstance.getVariable("b"));
+        assertNull(processInstance.getVariable("c"));
+        System.out.println("### Completing first work item ###");
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+        
+        System.out.println("### Retrieving variable instance infos ###");
+        result = emf.createEntityManager().createQuery("select i from VariableInstanceInfo i").getResultList();
+        assertEquals(6, result.size());
+        for (Object o: result) {
+        	System.out.println(((VariableInstanceInfo) o));
+        }
+        
+        System.out.println("### Retrieving process instance ###");
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(id, kbase, null, env);
+		processInstance = (WorkflowProcessInstance)
+			ksession.getProcessInstance(processInstance.getId());
+		assertNotNull(processInstance);
+        assertEquals("SomeString", processInstance.getVariable("x"));
+        assertEquals("This is a test Entity", ((MyEntity) processInstance.getVariable("y")).getTest());
+        assertEquals("This is a test SerializableObject", ((MyVariableSerializable) processInstance.getVariable("z")).getText());
+        assertEquals("Some new String", processInstance.getVariable("a"));
+        assertEquals("This is a new test Entity", ((MyEntity) processInstance.getVariable("b")).getTest());
+        assertEquals("This is a new test SerializableObject", ((MyVariableSerializable) processInstance.getVariable("c")).getText());
+        System.out.println("### Completing second work item ###");
+		ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null);
+
+        workItem = handler.getWorkItem();
+        assertNotNull(workItem);
+        
+        result = emf.createEntityManager().createQuery("select i from VariableInstanceInfo i").getResultList();
+        assertEquals(6, result.size());
+        
+        System.out.println("### Retrieving process instance ###");
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(id, kbase, null, env);
+        processInstance = (WorkflowProcessInstance)
+        	ksession.getProcessInstance(processInstance.getId());
+        assertNotNull(processInstance);
+        assertEquals("SomeString", processInstance.getVariable("x"));
+        assertEquals("This is a test Entity", ((MyEntity) processInstance.getVariable("y")).getTest());
+        assertEquals("This is a test SerializableObject", ((MyVariableSerializable) processInstance.getVariable("z")).getText());
+        assertEquals("Some changed String", processInstance.getVariable("a"));
+        assertEquals("This is a changed test Entity", ((MyEntity) processInstance.getVariable("b")).getTest());
+        assertEquals("This is a changed test SerializableObject", ((MyVariableSerializable) processInstance.getVariable("c")).getText());
+        System.out.println("### Completing third work item ###");
+        ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null);
+
+        workItem = handler.getWorkItem();
+        assertNull(workItem);
+        
+        result = emf.createEntityManager().createQuery("select i from VariableInstanceInfo i").getResultList();
+        //This was 6.. but I change it to 0 because all the variables will go away with the process instance..
+        //we need to change that to leave the variables there??? 
+        assertEquals(0, result.size());
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(id, kbase, null, env);
+        processInstance = (WorkflowProcessInstance)
+			ksession.getProcessInstance(processInstance.getId());
+        assertNull(processInstance);
+    }
+    
+    public void testPersistenceVariablesWithTypeChange() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( new ClassPathResource( "VariablePersistenceStrategyProcessTypeChange.rf" ), ResourceType.DRF );
+        for (KnowledgeBuilderError error: kbuilder.getErrors()) {
+        	System.out.println(error);
+        }
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory( "org.drools.persistence.jpa" );
+        Environment env = KnowledgeBaseFactory.newEnvironment();
+        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
+
+        env.set( EnvironmentName.GLOBALS, new MapGlobalResolver() );
+
+        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
+        int id = ksession.getId();
+
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("x", "SomeString");
+        parameters.put("y", new MyEntity("This is a test Entity"));
+        parameters.put("z", new MyVariableSerializable("This is a test SerializableObject"));
+        ProcessInstance processInstance = ksession.startProcess( "com.sample.ruleflow", parameters );
+
+        TestWorkItemHandler handler = TestWorkItemHandler.getInstance();
+        WorkItem workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNull( processInstance );
+    }
+    
+    public void testPersistenceVariablesSubProcess() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( new ClassPathResource( "VariablePersistenceStrategySubProcess.rf" ), ResourceType.DRF );
+        for (KnowledgeBuilderError error: kbuilder.getErrors()) {
+        	System.out.println(error);
+        }
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory( "org.drools.persistence.jpa" );
+        Environment env = KnowledgeBaseFactory.newEnvironment();
+        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
+
+        env.set( EnvironmentName.GLOBALS, new MapGlobalResolver() );
+
+        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
+        int id = ksession.getId();
+
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("x", "SomeString");
+        parameters.put("y", new MyEntity("This is a test Entity"));
+        parameters.put("z", new MyVariableSerializable("This is a test SerializableObject"));
+        ProcessInstance processInstance = ksession.startProcess( "com.sample.ruleflow", parameters );
+
+        TestWorkItemHandler handler = TestWorkItemHandler.getInstance();
+        WorkItem workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNotNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNotNull( processInstance );
+        ksession.getWorkItemManager().completeWorkItem( workItem.getId(), null );
+
+        workItem = handler.getWorkItem();
+        assertNull( workItem );
+
+        ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( id, kbase, null, env );
+        processInstance = ksession.getProcessInstance( processInstance.getId() );
+        assertNull( processInstance );
+    }
+    
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcess.rf
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcess.rf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcess.rf	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="ruleflow" id="com.sample.ruleflow" package-name="com.sample" >
+
+  <header>
+    <imports>
+      <import name="org.drools.persistence.session.MyEntity" />
+      <import name="org.drools.persistence.session.MyVariableSerializable" />
+    </imports>
+    <variables>
+      <variable name="x" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value></value>
+      </variable>
+      <variable name="y" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyEntity" />
+      </variable>
+      <variable name="z" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyVariableSerializable" />
+      </variable>
+      <variable name="a" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value></value>
+      </variable>
+      <variable name="b" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyEntity" />
+      </variable>
+      <variable name="c" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyVariableSerializable" />
+      </variable>
+    </variables>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="16" y="16" width="48" height="48" />
+    <end id="3" name="End" x="669" y="16" width="48" height="48" />
+    <humanTask id="4" name="Human Task" x="208" y="16" width="93" height="48" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="5" name="Action" x="96" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+    <actionNode id="6" name="Action" x="333" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+kcontext.setVariable("a", "Some new String");
+kcontext.setVariable("b", new MyEntity("This is a new test Entity"));
+kcontext.setVariable("c", new MyVariableSerializable("This is a new test SerializableObject"));</action>
+    </actionNode>
+    <humanTask id="7" name="Human Task" x="445" y="20" width="80" height="40" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="8" name="Action" x="557" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+System.out.println("a = " + a);
+System.out.println("b = " + b);
+System.out.println("c = " + c);
+kcontext.setVariable("a", "Some changed String");
+kcontext.setVariable("b", new MyEntity("This is a changed test Entity"));
+kcontext.setVariable("c", new MyVariableSerializable("This is a changed test SerializableObject"));</action>
+    </actionNode>
+    <humanTask id="9" name="Human Task" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="10" name="Action" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+System.out.println("a = " + a);
+System.out.println("b = " + b);
+System.out.println("c = " + c);</action>
+    </actionNode>
+  </nodes>
+
+  <connections>
+    <connection from="10" to="3" />
+    <connection from="5" to="4" />
+    <connection from="1" to="5" />
+    <connection from="4" to="6" />
+    <connection from="6" to="7" />
+    <connection from="7" to="8" />
+    <connection from="8" to="9" />
+    <connection from="9" to="10" />
+  </connections>
+
+</process>
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcessTypeChange.rf
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcessTypeChange.rf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategyProcessTypeChange.rf	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="ruleflow" id="com.sample.ruleflow" package-name="com.sample" >
+
+  <header>
+    <imports>
+      <import name="org.drools.persistence.session.MyEntity" />
+      <import name="org.drools.persistence.session.MyVariableSerializable" />
+    </imports>
+    <variables>
+      <variable name="x" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value></value>
+      </variable>
+      <variable name="y" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="java.lang.Object" />
+      </variable>
+      <variable name="z" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="java.lang.Object" />
+      </variable>
+      <variable name="a" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value></value>
+      </variable>
+      <variable name="b" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="java.lang.Object" />
+      </variable>
+      <variable name="c" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="java.lang.Object" />
+      </variable>
+    </variables>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="16" y="16" width="48" height="48" />
+    <end id="3" name="End" x="669" y="16" width="48" height="48" />
+    <actionNode id="6" name="Action" x="333" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+System.out.println("a = " + a);
+System.out.println("b = " + b);
+System.out.println("c = " + c);
+kcontext.setVariable("a", "Some new String");
+kcontext.setVariable("b", new MyEntity("This is a new test Entity"));
+kcontext.setVariable("c", new MyVariableSerializable("This is a new test SerializableObject"));</action>
+    </actionNode>
+    <humanTask id="7" name="Human Task" x="445" y="20" width="80" height="40" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="8" name="Action" x="557" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+System.out.println("a = " + a);
+System.out.println("b = " + b);
+System.out.println("c = " + c);
+kcontext.setVariable("a", "Some changed String");
+kcontext.setVariable("c", new MyEntity("This is a changed test Entity"));
+kcontext.setVariable("b", new MyVariableSerializable("This is a changed test SerializableObject"));</action>
+    </actionNode>
+    <humanTask id="9" name="Human Task" x="445" y="20" width="80" height="40" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="10" name="Action" x="557" y="20" width="80" height="40" >
+        <action type="expression" dialect="java" >System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);
+System.out.println("a = " + a);
+System.out.println("b = " + b);
+System.out.println("c = " + c);
+        </action>
+    </actionNode>
+  </nodes>
+
+  <connections>
+    <connection from="8" to="9" />
+    <connection from="9" to="10" />
+    <connection from="10" to="3" />
+    <connection from="1" to="6" />
+    <connection from="6" to="7" />
+    <connection from="7" to="8" />
+  </connections>
+
+</process>
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategySubProcess.rf
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategySubProcess.rf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/VariablePersistenceStrategySubProcess.rf	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="ruleflow" id="com.sample.ruleflow" package-name="com.sample" >
+
+  <header>
+    <imports>
+      <import name="org.drools.persistence.session.MyEntity" />
+      <import name="org.drools.persistence.session.MyVariableSerializable" />
+    </imports>
+    <variables>
+      <variable name="x" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+      </variable>
+      <variable name="y" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyEntity" />
+      </variable>
+      <variable name="z" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyVariableSerializable" />
+      </variable>
+      <variable name="v" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value>Default</value>
+      </variable>
+    </variables>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="16" y="16" width="48" height="48" />
+    <end id="3" name="End" x="669" y="16" width="48" height="48" />
+    <composite id="4" name="CompositeNode" x="187" y="33" width="326" height="327" >
+    <variables>
+      <variable name="y" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyEntity" />
+      </variable>
+      <variable name="z" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyVariableSerializable" />
+      </variable>
+      <variable name="x" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value></value>
+      </variable>
+      <variable name="w" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value>New default</value>
+      </variable>
+    </variables>
+      <nodes>
+    <actionNode id="1" name="Action" x="31" y="62" >
+        <action type="expression" dialect="mvel" >kcontext.setVariable("x", "new String");
+kcontext.setVariable("y", new MyEntity("This is a new test Entity"));
+kcontext.setVariable("z", new MyVariableSerializable("This is a new test SerializableObject"));</action>
+    </actionNode>
+    <humanTask id="2" name="Human Task" x="122" y="61" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="3" name="Action" x="211" y="61" >
+        <action type="expression" dialect="mvel" >System.out.println("v = " + v);
+System.out.println("w = " + w);
+System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+    <composite id="7" name="CompositeNode" x="26" y="136" width="273" height="173" >
+    <variables>
+      <variable name="a" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value>Newest Default 1</value>
+      </variable>
+      <variable name="z" >
+        <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        <value>Newest Default 2</value>
+      </variable>
+    </variables>
+      <nodes>
+    <actionNode id="1" name="Action" x="18" y="55" >
+        <action type="expression" dialect="mvel" >System.out.println("a = " + a);
+System.out.println("v = " + v);
+System.out.println("w = " + w);
+System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+    <humanTask id="2" name="Human Task" x="140" y="40" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="3" name="Action" x="163" y="112" >
+        <action type="expression" dialect="mvel" >System.out.println("a = " + a);
+System.out.println("v = " + v);
+System.out.println("w = " + w);
+System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+      </nodes>
+      <connections>
+    <connection from="1" to="2" />
+    <connection from="2" to="3" />
+      </connections>
+      <in-ports>
+        <in-port type="DROOLS_DEFAULT" nodeId="1" nodeInType="DROOLS_DEFAULT" />
+      </in-ports>
+      <out-ports>
+        <out-port type="DROOLS_DEFAULT" nodeId="3" nodeOutType="DROOLS_DEFAULT" />
+      </out-ports>
+    </composite>
+      </nodes>
+      <connections>
+    <connection from="1" to="2" />
+    <connection from="2" to="3" />
+    <connection from="3" to="7" />
+      </connections>
+      <in-ports>
+        <in-port type="DROOLS_DEFAULT" nodeId="1" nodeInType="DROOLS_DEFAULT" />
+      </in-ports>
+      <out-ports>
+        <out-port type="DROOLS_DEFAULT" nodeId="7" nodeOutType="DROOLS_DEFAULT" />
+      </out-ports>
+    </composite>
+    <actionNode id="5" name="Action" x="547" y="50" width="80" height="48" >
+        <action type="expression" dialect="mvel" >System.out.println("v = " + v);
+System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+    <humanTask id="6" name="Human Task" >
+      <work name="Human Task" >
+        <parameter name="ActorId" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Comment" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Content" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Priority" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="Skippable" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+        <parameter name="TaskName" >
+          <type name="org.drools.process.core.datatype.impl.type.StringDataType" />
+        </parameter>
+      </work>
+    </humanTask>
+    <actionNode id="7" name="Action" >
+        <action type="expression" dialect="mvel" >System.out.println("v = " + v);
+System.out.println("x = " + x);
+System.out.println("y = " + y);
+System.out.println("z = " + z);</action>
+    </actionNode>
+  </nodes>
+
+  <connections>
+    <connection from="7" to="3" />
+    <connection from="1" to="4" />
+    <connection from="4" to="5" />
+    <connection from="5" to="6" />
+    <connection from="6" to="7" />
+  </connections>
+
+</process>
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/testVariables.rf
===================================================================
--- labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/testVariables.rf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-persistence-jpa/src/test/resources/testVariables.rf	2009-09-10 21:30:27 UTC (rev 29305)
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="flow" id="testVariables" package-name="org.drools.examples" >
+
+  <header>
+    <variables>
+      <variable name="var1" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyEntity" />
+      </variable>
+      <variable name="var2" >
+        <type name="org.drools.process.core.datatype.impl.type.ObjectDataType" className="org.drools.persistence.session.MyVariableSerializable" />
+      </variable>
+    </variables>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="147" y="32" width="80" height="40" />
+ 
+    <workItem id="2" name="Log1" x="147" y="191" width="80" height="40" >
+      <work name="Log" >
+       
+      </work>
+      <mapping type="in" from="var1" to="var1" />
+      <mapping type="in" from="var2" to="var2" />
+      <mapping type="out" from="var1" to="var1" />
+      <mapping type="out" from="var2" to="var2" />
+    </workItem>
+    <actionNode id="3" name="Action1" x="146" y="117" width="80" height="40" >
+        <action type="expression" dialect="mvel" >
+            System.out.println("Variable Value: "+kcontext.getVariable("var1"));
+            System.out.println("Variable Value: "+kcontext.getVariable("var2"));
+        </action>
+    </actionNode>
+    <actionNode id="4" name="Action2" x="147" y="268" width="80" height="40" >
+        <action type="expression" dialect="mvel" >
+            System.out.println("Variable Value: "+kcontext.getVariable("var1"));
+            System.out.println("Variable Value: "+kcontext.getVariable("var2"));
+        </action>
+    </actionNode>
+    <workItem id="5" name="Log2" x="146" y="345" width="80" height="40" >
+      <work name="Log" >
+      
+      </work>
+     <mapping type="in" from="var1" to="var1" />
+      <mapping type="in" from="var2" to="var2" />
+      <mapping type="out" from="var1" to="var1" />
+      <mapping type="out" from="var2" to="var2" />
+    </workItem>
+    <actionNode id="6" name="Action3" x="144" y="422" width="80" height="40" >
+        <action type="expression" dialect="mvel" >
+            System.out.println("Variable Value: "+kcontext.getVariable("var1"));
+            System.out.println("Variable Value: "+kcontext.getVariable("var2"));
+        </action>
+    </actionNode>
+    <workItem id="7" name="Log3" x="146" y="345" width="80" height="40" >
+      <work name="Log" >
+        
+      </work>
+      <mapping type="in" from="var1" to="var1" />
+      <mapping type="in" from="var2" to="var2" />
+      <mapping type="out" from="var1" to="var1" />
+      <mapping type="out" from="var2" to="var2" />
+    </workItem>
+    <end id="8" name="End" x="145" y="494" width="80" height="40" />
+  </nodes>
+
+  <connections>
+    <connection from="3" to="2" />
+    <connection from="1" to="3" />
+    <connection from="2" to="4" />
+    <connection from="4" to="5" />
+    <connection from="5" to="6" />
+    <connection from="6" to="7" />
+    <connection from="7" to="8" />
+  </connections>
+
+</process>
\ No newline at end of file



More information about the jboss-svn-commits mailing list