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

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Dec 11 04:57:40 EST 2009


Author: tom.baeyens at jboss.com
Date: 2009-12-11 04:57:40 -0500 (Fri, 11 Dec 2009)
New Revision: 5949

Added:
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdateTest.java
Removed:
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdate.java
Modified:
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/serializablevariable/UpdateSerializedVariables.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/DeserializedObjects.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
   jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch07-Variables.xml
Log:
JBPM-2684 automatic saving of updates to serializable variables

Modified: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/serializablevariable/UpdateSerializedVariables.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/serializablevariable/UpdateSerializedVariables.java	2009-12-11 09:29:37 UTC (rev 5948)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/serializablevariable/UpdateSerializedVariables.java	2009-12-11 09:57:40 UTC (rev 5949)
@@ -21,13 +21,11 @@
  */
 package org.jbpm.examples.serializablevariable;
 
-import java.util.List;
 import java.util.Set;
 
 import org.jbpm.api.activity.ActivityBehaviour;
 import org.jbpm.api.activity.ActivityExecution;
 
-
 /**
  * @author Tom Baeyens
  */
@@ -42,5 +40,4 @@
     messages.add("was");
     messages.add("updated");
   }
-
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/DeserializedObjects.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/DeserializedObjects.java	2009-12-11 09:29:37 UTC (rev 5948)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/DeserializedObjects.java	2009-12-11 09:57:40 UTC (rev 5949)
@@ -23,10 +23,13 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
 import org.jbpm.pvm.internal.type.Variable;
+import org.jbpm.pvm.internal.type.converter.SerializableToBytesConverter;
+import org.jbpm.pvm.internal.type.variable.BlobVariable;
 
 
 /**
@@ -35,6 +38,8 @@
 public class DeserializedObjects implements Serializable {
 
   private static final long serialVersionUID = 1L;
+  
+  private static final SerializableToBytesConverter serializableToBytesConverter = new SerializableToBytesConverter();
 
   protected List<Object[]> deserializedObjects = new ArrayList<Object[]>();
 
@@ -50,15 +55,24 @@
     for (Object[] triple: copy) {
       Object deserializedObject = triple[0];
       ScopeInstanceImpl scopeInstance = (ScopeInstanceImpl) triple[1];
-      Variable variable = (Variable) triple[2];
+      BlobVariable blobVariable = (BlobVariable) triple[2];
+      
+      String variableName = blobVariable.getKey();
+      Object currentValue = scopeInstance.getVariable(variableName);
 
-      String variableName = variable.getKey();
-      Object currentValue = scopeInstance.getVariable(variableName);
-      
+      // first check if the deserialized object still is the value for that variable.
+      // a different, new object (of any type) might have been set in the meantime in that key-value-pair 
       if ( (currentValue!=null)
            && (currentValue==deserializedObject)
          ) {
-        variable.setValue(deserializedObject, scopeInstance);
+        // next, we check if the serialized object was actually changed or not
+        byte[] newBytes = (byte[]) serializableToBytesConverter.convert(currentValue, null, null);
+        byte[] persistedBytes = blobVariable.getLob().extractBytes();
+        // if it is changed
+        if (!Arrays.equals(persistedBytes, newBytes)) {
+          // then do an automatic update
+          blobVariable.setValue(deserializedObject, scopeInstance);
+        }
       }
     }
   }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java	2009-12-11 09:29:37 UTC (rev 5948)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java	2009-12-11 09:57:40 UTC (rev 5949)
@@ -32,7 +32,6 @@
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
 import org.jbpm.pvm.internal.env.Transaction;
 import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
-import org.jbpm.pvm.internal.session.DbSession;
 import org.jbpm.pvm.internal.type.Converter;
 import org.jbpm.pvm.internal.type.Variable;
 

Deleted: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdate.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdate.java	2009-12-11 09:29:37 UTC (rev 5948)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdate.java	2009-12-11 09:57:40 UTC (rev 5949)
@@ -1,97 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.test.variables;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jbpm.api.ProcessInstance;
-import org.jbpm.api.activity.ActivityBehaviour;
-import org.jbpm.api.activity.ActivityExecution;
-import org.jbpm.test.JbpmTestCase;
-import org.jbpm.test.activity.custom.CustomConfigurationsTest.MyCustomAutomatic;
-
-
-/**
- * @author Tom Baeyens
- */
-public class SerializedVariableUpdate extends JbpmTestCase {
-  
-  public static class UpdateAndReplace implements ActivityBehaviour {
-
-    private static final long serialVersionUID = 1L;
-
-    public void execute(ActivityExecution execution) throws Exception {
-      Set<String> messages = (Set<String>) execution.getVariable("messages");
-      messages.clear();
-      messages.add("i");
-      messages.add("was");
-      messages.add("updated");
-
-      Set<String> newMessagesObject = new HashSet<String>();
-      newMessagesObject.add("completely");
-      newMessagesObject.add("new");
-      newMessagesObject.add("object");
-      execution.setVariable("messages", newMessagesObject);
-    }
-    
-  }
-
-  public void testSerializableVariableUpdate() {
-    deployJpdlXmlString(
-      "<process name='SerializedVariableUpdate'>" +
-      "  <start>" +
-      "    <transition to='wait before' />" +
-      "  </start>" +
-      "  <state name='wait before'>" +
-      "    <transition to='update' />" +
-      "  </state>" +
-      "  <custom name='update' class='"+UpdateAndReplace.class.getName()+"'>" +
-      "    <transition to='wait after' />" +
-      "  </custom>" +
-      "  <state name='wait after'/>" +
-      "</process>"
-    );
-
-    Set<String> messages = new HashSet<String>();
-    messages.add("serialize");
-    messages.add("me");
-
-    Map<String, Object> variables = new HashMap<String, Object>();
-    variables.put("messages", messages);
-    
-    ProcessInstance processInstance = executionService.startProcessInstanceByKey("SerializedVariableUpdate", variables);
-    String pid = processInstance.getId();
-    executionService.signalExecutionById(pid);
-
-    Set<String> expectedMessages = new HashSet<String>();
-    expectedMessages.add("completely");
-    expectedMessages.add("new");
-    expectedMessages.add("object");
-
-    messages = (Set<String>) executionService.getVariable(pid, "messages");
-    assertEquals(expectedMessages, messages);
-  }
-
-}

Copied: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdateTest.java (from rev 5944, jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdate.java)
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdateTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdateTest.java	2009-12-11 09:57:40 UTC (rev 5949)
@@ -0,0 +1,144 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.variables;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.activity.ActivityBehaviour;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class SerializedVariableUpdateTest extends JbpmTestCase {
+  
+  public static class UpdateAndReplace implements ActivityBehaviour {
+
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ActivityExecution execution) throws Exception {
+      Set<String> messages = (Set<String>) execution.getVariable("messages");
+      messages.clear();
+      messages.add("i");
+      messages.add("was");
+      messages.add("updated");
+
+      Set<String> newMessagesObject = new HashSet<String>();
+      newMessagesObject.add("completely");
+      newMessagesObject.add("new");
+      newMessagesObject.add("object");
+      execution.setVariable("messages", newMessagesObject);
+    }
+    
+  }
+
+  public void testSerializableVariableUpdate() {
+    deployJpdlXmlString(
+      "<process name='SerializedVariableUpdate'>" +
+      "  <start>" +
+      "    <transition to='wait before' />" +
+      "  </start>" +
+      "  <state name='wait before'>" +
+      "    <transition to='update' />" +
+      "  </state>" +
+      "  <custom name='update' class='"+UpdateAndReplace.class.getName()+"'>" +
+      "    <transition to='wait after' />" +
+      "  </custom>" +
+      "  <state name='wait after'/>" +
+      "</process>"
+    );
+
+    Set<String> messages = new HashSet<String>();
+    messages.add("serialize");
+    messages.add("me");
+
+    Map<String, Object> variables = new HashMap<String, Object>();
+    variables.put("messages", messages);
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("SerializedVariableUpdate", variables);
+    String pid = processInstance.getId();
+    executionService.signalExecutionById(pid);
+
+    Set<String> expectedMessages = new HashSet<String>();
+    expectedMessages.add("completely");
+    expectedMessages.add("new");
+    expectedMessages.add("object");
+
+    messages = (Set<String>) executionService.getVariable(pid, "messages");
+    assertEquals(expectedMessages, messages);
+  }
+
+
+  public static class ReadOnly implements ActivityBehaviour {
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ActivityExecution execution) throws Exception {
+      execution.getVariable("messages");
+      execution.getVariable("messages");
+    }
+  }
+  
+  public void testReadOnly() {
+    deployJpdlXmlString(
+      "<process name='SerializedVariableUpdate'>" +
+      "  <start>" +
+      "    <transition to='wait before' />" +
+      "  </start>" +
+      "  <state name='wait before'>" +
+      "    <transition to='update' />" +
+      "  </state>" +
+      "  <custom name='update' class='"+ReadOnly.class.getName()+"'>" +
+      "    <transition to='wait after' />" +
+      "  </custom>" +
+      "  <state name='wait after'/>" +
+      "</process>"
+    );
+  
+    Set<String> messages = new HashSet<String>();
+    messages.add("serialize");
+    messages.add("me");
+  
+    Map<String, Object> variables = new HashMap<String, Object>();
+    variables.put("messages", messages);
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("SerializedVariableUpdate", variables);
+    String pid = processInstance.getId();
+    executionService.signalExecutionById(pid);
+  
+    Set<String> expectedMessages = new HashSet<String>();
+    expectedMessages.add("serialize");
+    expectedMessages.add("me");
+  
+    messages = (Set<String>) executionService.getVariable(pid, "messages");
+    assertEquals(expectedMessages, messages);
+    
+    // TODO find some way to assert that NO variable update is issued to the history service
+    // for now, i just did that check once manually in the debugger :-)  11/12/2009
+  }
+
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/variables/SerializedVariableUpdateTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch07-Variables.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch07-Variables.xml	2009-12-11 09:29:37 UTC (rev 5948)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch07-Variables.xml	2009-12-11 09:57:40 UTC (rev 5949)
@@ -79,5 +79,39 @@
     the variable is stored.
     </para>
   </section>
+
+  <section>
+    <title>Updating serialized process variables</title>
+    <para>(Since jBPM 4.3)</para>
+    <para>In <literal>custom</literal>s, <literal>event-handler</literal>s and other 
+    user code, you can retrieve process variables.  In case a process variable 
+    is stored as a serialized object, you can just make updates to your deserialized 
+    objects without the need for an explicit save.  jBPM will manage deserialized process 
+    variables and update them automatically if you change.  For example (@see examples package 
+    org.jbpm.examples.serializedobject), look at this piece of user code inside a <literal>custom</literal>'s activity behaviour:   
+    </para>
+    <programlisting>public class UpdateSerializedVariables implements ActivityBehaviour {
+
+  public void execute(ActivityExecution execution) {
+    Set&lt;String&gt; messages = (Set&lt;String&gt;) execution.getVariable(&quot;messages&quot;);
+    messages.clear();
+    messages.add(&quot;i&quot;);
+    messages.add(&quot;was&quot;);
+    messages.add(&quot;updated&quot;);
+  }
+}</programlisting>
+    <para>When the transaction commits in which this usercode was called, the
+    updated messages set will be updated in the database automatically.  
+    </para>
+    <para>When reading process variables that are stored in serialized format from the DB 
+    jBPM will monitor that deserialized object.  Right before the commit of the transaction,
+    jBPM will serialize and update the variable automatically if that is necessary.  jBPM 
+    will ignore updates to the deserialized object if another object was set as the value 
+    in that scope  (which even can be of another type).  jBPM will also skip updating of the 
+    variable if the deserialized object has not been changed.  The check to see if the 
+    object has changed is based on comparing the byte arrays from serializing the object 
+    again and comparing that with the byte array that was originally loaded from the db.   
+    </para>
+  </section>
   
 </chapter>



More information about the jbpm-commits mailing list