[jbpm-commits] JBoss JBPM SVN: r5747 - in jbpm4/trunk/modules: jpdl/src/test/java/org/jbpm/jpdl/migration and 2 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Oct 15 22:31:43 EDT 2009


Author: koen.aers at jboss.com
Date: 2009-10-15 22:31:43 -0400 (Thu, 15 Oct 2009)
New Revision: 5747

Added:
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/MigrationHelper.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/AbortMigrationHandler.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/DefaultMigrationHandler.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationHandler.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java
Removed:
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java
Modified:
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
   jbpm4/trunk/modules/jpdl/src/test/java/org/jbpm/jpdl/migration/InstanceMigratorTest.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/InstanceMigrator.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationDescriptor.java
Log:
new test scenario's added for instance migration:
- no migration
- migration handler
- simple abortion 
- simple migration
- correct activity mapping
- incorrect activity mapping
- absolute version range 
- relative version range
- mixed version range
- wildcard
new functionality:
- user defined migration handler
- migrate a version range of the depoyed processes

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-10-15 22:59:55 UTC (rev 5746)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -47,6 +47,8 @@
 import org.jbpm.pvm.internal.email.impl.MailTemplateRegistry;
 import org.jbpm.pvm.internal.email.spi.MailProducer;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.migration.AbortMigrationHandler;
+import org.jbpm.pvm.internal.migration.DefaultMigrationHandler;
 import org.jbpm.pvm.internal.migration.MigrationDescriptor;
 import org.jbpm.pvm.internal.model.ActivityCoordinatesImpl;
 import org.jbpm.pvm.internal.model.ActivityImpl;
@@ -72,7 +74,6 @@
 import org.jbpm.pvm.internal.wire.binding.MailTemplateBinding;
 import org.jbpm.pvm.internal.wire.binding.ObjectBinding;
 import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor;
-import org.jbpm.pvm.internal.wire.operation.Operation;
 import org.jbpm.pvm.internal.wire.usercode.UserCodeReference;
 import org.jbpm.pvm.internal.wire.xml.WireParser;
 import org.jbpm.pvm.internal.xml.Bindings;
@@ -258,7 +259,7 @@
       // process migration information
       Element migrationElement = XmlUtil.element(documentElement, "migrate-instances");
       if (migrationElement != null) {
-        parseMigrationDescriptor(migrationElement, parse, processDefinition);
+        MigrationHelper.parseMigrationDescriptor(migrationElement, parse, processDefinition);
       }
 
     } finally {
@@ -282,33 +283,14 @@
     }
   }
 
-  @SuppressWarnings("unchecked")
-  public void parseMigrationDescriptor(Element migrationElement, Parse parse, ProcessDefinition processDefinition) {
-    Map<ProcessDefinition, MigrationDescriptor> migrations = (Map<ProcessDefinition, MigrationDescriptor>)parse.contextMapGet(Parse.CONTEXT_KEY_MIGRATIONS);
-    if (migrations == null) {
-      migrations = new HashMap<ProcessDefinition, MigrationDescriptor>();
-      parse.contextMapPut(Parse.CONTEXT_KEY_MIGRATIONS, migrations);
-    }
-    MigrationDescriptor migrationDescriptor = new MigrationDescriptor();
-    NodeList activityMappings = migrationElement.getElementsByTagName("activity-mapping");
-    for (int i = 0; i < activityMappings.getLength(); i++) {
-      Node activityMapping = activityMappings.item(i);
-      if (activityMapping instanceof Element) {
-        String oldName = ((Element)activityMapping).getAttribute("old-name");
-        String newName = ((Element)activityMapping).getAttribute("new-name");
-        migrationDescriptor.addMigrationElement(MigrationDescriptor.ACTIVITY_TYPE, oldName, newName);
-      }
-    }
-    migrations.put(processDefinition, migrationDescriptor);
-  }
-
   public void parseActivities(Element documentElement, Parse parse, CompositeElementImpl compositeElement) {
     List<Element> elements = XmlUtil.elements(documentElement);
     for (Element nestedElement : elements) {
       String tagName = XmlUtil.getTagLocalName(nestedElement);
       if ("on".equals(tagName) 
           || "timer".equals(tagName)
-          || "swimlane".equals(tagName)) continue;
+          || "swimlane".equals(tagName) 
+          || "migrate-instances".equals(tagName)) continue;
 
       JpdlBinding activityBinding = (JpdlBinding) getBinding(nestedElement, CATEGORY_ACTIVITY);
       if (activityBinding == null) {

Added: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/MigrationHelper.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/MigrationHelper.java	                        (rev 0)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/MigrationHelper.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -0,0 +1,119 @@
+package org.jbpm.jpdl.internal.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.pvm.internal.migration.AbortMigrationHandler;
+import org.jbpm.pvm.internal.migration.DefaultMigrationHandler;
+import org.jbpm.pvm.internal.migration.MigrationDescriptor;
+import org.jbpm.pvm.internal.xml.Parse;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class MigrationHelper {
+
+  @SuppressWarnings("unchecked")
+  public static void parseMigrationDescriptor(Element migrationElement, Parse parse, ProcessDefinition processDefinition) {
+    Map<ProcessDefinition, MigrationDescriptor> migrations = (Map<ProcessDefinition, MigrationDescriptor>)parse.contextMapGet(Parse.CONTEXT_KEY_MIGRATIONS);
+    if (migrations == null) {
+      migrations = new HashMap<ProcessDefinition, MigrationDescriptor>();
+      parse.contextMapPut(Parse.CONTEXT_KEY_MIGRATIONS, migrations);
+    }
+    MigrationDescriptor migrationDescriptor = new MigrationDescriptor();
+    String action = migrationElement.getAttribute("action");
+    if ("abort".equals(action)) {
+      migrationDescriptor.addMigrationHandlerClassName(AbortMigrationHandler.class.getName());
+    } else if ("custom".equals(action)) {
+      parseMigrationHandlers(migrationElement, migrationDescriptor);
+    } else {
+      migrationDescriptor.addMigrationHandlerClassName(DefaultMigrationHandler.class.getName());
+      parseActivityMappings(migrationElement, migrationDescriptor);
+    }
+    String versions = migrationElement.getAttribute("versions");
+    if (versions != null && !"".equals(versions)) {
+      addVersionInformation(versions, migrationDescriptor);
+    }
+    migrations.put(processDefinition, migrationDescriptor);
+  }
+  
+  private static void addVersionInformation(String versions, MigrationDescriptor migrationDescriptor) {
+    boolean isStartInfoRelative = false;
+    boolean isEndInfoRelative = false;
+    int startValue = -1;
+    int endValue = -1;
+    if ("*".equals(versions)) {
+      migrationDescriptor.setStartVersion(1);
+      migrationDescriptor.setEndVersion(Integer.MAX_VALUE);
+    } else {
+      int separatorIndex = versions.indexOf("..");
+      if (separatorIndex == -1) 
+        throw new JbpmException("Wrong version information in migrate-instances descriptor.");
+      String start = versions.substring(0, separatorIndex).trim();
+      int minusIndex = start.indexOf('-');
+      if (minusIndex != -1) {
+        if (!"x".equals(start.substring(0, minusIndex).trim())) 
+          throw new JbpmException("Relative version info should be of the form 'x - n'");
+        isStartInfoRelative = true;
+        start = start.substring(minusIndex + 1).trim();
+      }
+      try {
+        startValue = new Integer(start);
+        if (isStartInfoRelative) {
+          migrationDescriptor.setStartOffset(startValue); 
+        } else {
+          migrationDescriptor.setStartVersion(startValue);
+        }
+      } catch (NumberFormatException e) {
+        throw new JbpmException("Version information should be numeric.");
+      }
+      String end = versions.substring(separatorIndex + 2).trim();
+      if ("x".equals(end)) return;
+      minusIndex = end.indexOf('-');
+      if (minusIndex != -1) {
+        if (!"x".equals(end.substring(0, minusIndex).trim()))
+          throw new JbpmException("Relative version info should be of the form 'x - n'");
+        isEndInfoRelative = true;
+        end = end.substring(minusIndex + 1).trim();
+      }
+      try {
+        endValue = new Integer(end);
+        if (isEndInfoRelative) {
+          migrationDescriptor.setEndOffset(endValue);
+        } else {
+          migrationDescriptor.setEndVersion(endValue);
+        } 
+      } catch (NumberFormatException e) {
+        throw new JbpmException("Version information should be numeric.");
+      }      
+    }
+  }
+
+  private static void parseActivityMappings(Element migrationElement, MigrationDescriptor migrationDescriptor) {
+    NodeList activityMappings = migrationElement.getElementsByTagName("activity-mapping");
+    for (int i = 0; i < activityMappings.getLength(); i++) {
+      Node activityMapping = activityMappings.item(i);
+      if (activityMapping instanceof Element) {
+        String oldName = ((Element)activityMapping).getAttribute("old-name");
+        String newName = ((Element)activityMapping).getAttribute("new-name");
+        migrationDescriptor.addMigrationElement(MigrationDescriptor.ACTIVITY_TYPE, oldName, newName);
+      }
+    }
+  }
+
+  private static void parseMigrationHandlers(Element migrationElement, MigrationDescriptor migrationDescriptor) {
+    NodeList migrationHandlers = migrationElement.getElementsByTagName("migration-handler");
+    for (int i = 0; i < migrationHandlers.getLength(); i++) {
+      Node migrationHandler = migrationHandlers.item(i);
+      if (migrationHandler instanceof Element) {
+        String className = ((Element)migrationHandler).getAttribute("class");
+        if (className != null && !"".equals(className)) {
+          migrationDescriptor.addMigrationHandlerClassName(className);
+        }
+      }
+    }
+  }
+}


Property changes on: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/MigrationHelper.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/jpdl/src/test/java/org/jbpm/jpdl/migration/InstanceMigratorTest.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/test/java/org/jbpm/jpdl/migration/InstanceMigratorTest.java	2009-10-15 22:59:55 UTC (rev 5746)
+++ jbpm4/trunk/modules/jpdl/src/test/java/org/jbpm/jpdl/migration/InstanceMigratorTest.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -6,6 +6,7 @@
 import org.jbpm.api.ProcessDefinition;
 import org.jbpm.api.ProcessInstance;
 import org.jbpm.api.history.HistoryDetail;
+import org.jbpm.api.task.Task;
 import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceMigrationImpl;
 import org.jbpm.test.JbpmTestCase;
 
@@ -14,35 +15,42 @@
   
   private String firstVersion = 
     "<process name='foobar'>" +
+    "  <swimlane name='phelps' assignee='fredje'/>" +
     "  <start>" +
     "    <transition to='foo'/>" +
     "  </start>" +
     "  <state name='foo'>" +
     "    <transition to='bar'/>" +
     "  </state>" +
-    "  <state name='bar'>" +
+    "  <task name='bar' swimlane='phelps'>" +
     "    <transition to='end'/>" +
-    "  </state>" +
+    "  </task>" +
     "  <end name='end'/>" +
     "</process>";
   
   private String secondVersion = 
     "<process name='foobar'>" +
+    "  <swimlane name='baltimore bullet' assignee='fredje'/>" +
     "  <start>" +
     "    <transition to='foo'/>" +
     "  </start>" +
     "  <state name='foo'>" +
-    "    <transition to='bar'/>" +
+    "    <transition to='fu'/>" +
     "  </state>" +
-    "  <state name='bar'>" +
+    "  <task name='fu' swimlane='baltimore bullet'>" +
+    "    <transition name='to end' to='end'/>" +
+    "    <transition name='to baz' to='baz'/>" +
+    "  </task>" +
+    "  <task name='baz' swimlane='baltimore bullet'>" +
     "    <transition to='end'/>" +
-    "  </state>" +
+    "  </task>" +
     "  <end name='end'/>" +
-    "  <migrate-instances/>" +
+    "  <migrate-instances>" +
+    "    <activity-mapping old-name='bar' new-name='fu'/>" +
+    "  </migrate-instances>" +
     "</process>";
-  
-  
-  public void testSimpleMigration() {
+    
+  public void testHistoryProcessInstanceMigration() {
     String deploymentId1 = repositoryService.createDeployment()
         .addResourceFromString("foobar.jpdl.xml", firstVersion)
         .deploy();
@@ -54,11 +62,6 @@
         .startProcessInstanceById(processDefinition1.getId())
         .findActiveExecutionIn("foo");
     executionService.signalExecutionById(execution.getId());
-    ProcessInstance processInstance1 = executionService
-        .createProcessInstanceQuery()
-        .processDefinitionId(processDefinition1.getId())
-        .uniqueResult();
-    assertNotNull(processInstance1.findActiveExecutionIn("bar"));
     
     String deploymentId2 = repositoryService.createDeployment()
         .addResourceFromString("foobar.jpdl.xml", secondVersion)
@@ -67,16 +70,14 @@
         .createProcessDefinitionQuery()
         .deploymentId(deploymentId2)
         .uniqueResult();
-    ProcessInstance processInstance2 = executionService
+    ProcessInstance processInstance = executionService
         .createProcessInstanceQuery()
         .processDefinitionId(processDefinition2.getId())
         .uniqueResult();
     
-    assertNotNull(processInstance2);
-    
     List<HistoryDetail> historyDetails = historyService
         .createHistoryDetailQuery()
-        .processInstanceId(processInstance2.getId())
+        .processInstanceId(processInstance.getId())
         .list();
     HistoryProcessInstanceMigrationImpl historyProcessInstanceMigration = null;
     for (HistoryDetail historyDetail : historyDetails) {
@@ -92,4 +93,39 @@
     
   }
 
+  public void testSwimlaneMigration() {
+    
+    identityService.createUser("fredje", "Frederik", "Deburghgraeve");
+    
+    String deploymentId1 = repositoryService.createDeployment()
+        .addResourceFromString("foobar.jpdl.xml", firstVersion)
+        .deploy();
+    ProcessDefinition processDefinition1 = repositoryService
+        .createProcessDefinitionQuery()
+        .deploymentId(deploymentId1)
+        .uniqueResult();
+    Execution execution = executionService
+        .startProcessInstanceById(processDefinition1.getId())
+        .findActiveExecutionIn("foo");
+    executionService.signalExecutionById(execution.getId());
+    
+    Task task = taskService.createTaskQuery().assignee("fredje").uniqueResult();
+    assertNotNull(task);
+    
+    String deploymentId2 = repositoryService.createDeployment()
+        .addResourceFromString("foobar.jpdl.xml", secondVersion)
+        .deploy();
+        
+    taskService.completeTask(task.getId(), "to baz");
+        
+    task = taskService.createTaskQuery().assignee("fredje").uniqueResult();
+    assertNotNull(task);
+
+    identityService.deleteUser("fredje");
+    
+    repositoryService.deleteDeploymentCascade(deploymentId2);
+    repositoryService.deleteDeploymentCascade(deploymentId1);
+    
+  }
+
 }

Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/AbortMigrationHandler.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/AbortMigrationHandler.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/AbortMigrationHandler.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -0,0 +1,17 @@
+package org.jbpm.pvm.internal.migration;
+
+import org.jbpm.api.ExecutionService;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+
+
+public class AbortMigrationHandler implements MigrationHandler {
+
+  public void migrateInstance(ProcessDefinition newProcessDefinition, ProcessInstance processInstance, MigrationDescriptor migrationDescriptor) {
+    ExecutionService executionService = EnvironmentImpl.getFromCurrent(ExecutionService.class);
+    if (executionService == null) return;
+    executionService.endProcessInstance(processInstance.getId(), "aborted");
+  }
+
+}


Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/AbortMigrationHandler.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/DefaultMigrationHandler.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/DefaultMigrationHandler.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/DefaultMigrationHandler.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -0,0 +1,57 @@
+package org.jbpm.pvm.internal.migration;
+
+import org.jbpm.api.Execution;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.pvm.internal.history.HistoryEvent;
+import org.jbpm.pvm.internal.history.events.ProcessInstanceMigration;
+import org.jbpm.pvm.internal.model.Activity;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
+
+
+public class DefaultMigrationHandler implements MigrationHandler {
+
+  public void migrateInstance(
+          ProcessDefinition newProcessDefinition, 
+          ProcessInstance processInstance, 
+          MigrationDescriptor migrationDescriptor) {
+    migrateExecutions(newProcessDefinition, processInstance, migrationDescriptor);
+    logMigration(processInstance, newProcessDefinition);
+  }
+
+  private void migrateChildExecutions(
+          ProcessDefinition processDefinition, 
+          Execution execution, 
+          MigrationDescriptor migrationDescriptor) {
+    for (Execution child : execution.getExecutions()) {
+      migrateExecutions(processDefinition, child, migrationDescriptor);
+    }
+  }
+
+  private void migrateExecutions(ProcessDefinition processDefinition, Execution execution, MigrationDescriptor migrationDescriptor) {
+    migrateChildExecutions(processDefinition, execution, migrationDescriptor);
+    if (!(execution instanceof ExecutionImpl) || !(processDefinition instanceof ProcessDefinitionImpl))
+      return;
+    ((ExecutionImpl)execution).setProcessDefinition((ProcessDefinitionImpl)processDefinition);
+    String oldName = ((ExecutionImpl) execution).getActivityName();
+    if (oldName == null)
+      return;
+    String newName = migrationDescriptor.getNewName(MigrationDescriptor.ACTIVITY_TYPE, oldName);
+    if (newName == null)
+      newName = oldName;
+    Activity newActivity = ((ProcessDefinitionImpl) processDefinition).getActivity(newName);
+    if (newActivity != null) {
+      ((ExecutionImpl) execution).setActivity(newActivity);
+    } else {
+      throw new JbpmException("the activity " + newActivity + " could not be found in the new process definition.");
+    }
+  }
+  
+  private static void logMigration(ProcessInstance processInstance, ProcessDefinition processDefinition) {
+    ProcessInstanceMigration processInstanceMigrate = new ProcessInstanceMigration(processInstance, processDefinition);
+    HistoryEvent.fire(processInstanceMigrate);
+  }
+  
+}


Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/DefaultMigrationHandler.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/InstanceMigrator.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/InstanceMigrator.java	2009-10-15 22:59:55 UTC (rev 5746)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/InstanceMigrator.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -1,5 +1,6 @@
 package org.jbpm.pvm.internal.migration;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.jbpm.api.Execution;
@@ -7,24 +8,23 @@
 import org.jbpm.api.ProcessDefinition;
 import org.jbpm.api.ProcessDefinitionQuery;
 import org.jbpm.api.ProcessInstance;
-import org.jbpm.api.ProcessInstanceQuery;
+import org.jbpm.internal.log.Log;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.history.HistoryEvent;
-import org.jbpm.pvm.internal.history.events.ProcessInstanceMigration;
-import org.jbpm.pvm.internal.model.Activity;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
 import org.jbpm.pvm.internal.session.RepositorySession;
+import org.jbpm.pvm.internal.util.ReflectUtil;
 
 public class InstanceMigrator {
 
+  private static Log log = Log.getLog(InstanceMigrator.class.getName());
+
   public static void migrateAll(ProcessDefinition processDefinition, MigrationDescriptor migrationDescriptor) {
-    String oldVersionId = getOldVersionId(processDefinition.getName());
-    ExecutionService executionService = (ExecutionService) EnvironmentImpl.getFromCurrent(ExecutionService.class);
-    ProcessInstanceQuery processInstanceQuery = executionService
-      .createProcessInstanceQuery()
-      .processDefinitionId(oldVersionId);
-    List<ProcessInstance> processInstances = processInstanceQuery.list();
+//    String oldVersionId = getOldVersionId(processDefinition.getName());
+//    ExecutionService executionService = (ExecutionService) EnvironmentImpl.getFromCurrent(ExecutionService.class);
+//    ProcessInstanceQuery processInstanceQuery = executionService
+//      .createProcessInstanceQuery()
+//      .processDefinitionId(oldVersionId);
+//    List<ProcessInstance> processInstances = processInstanceQuery.list();
+    List<ProcessInstance> processInstances = getProcessInstancesToMigrate(processDefinition.getName(), migrationDescriptor);
     for (ProcessInstance processInstance : processInstances) {
       migrateInstance(processDefinition, processInstance, migrationDescriptor);
     }
@@ -34,44 +34,98 @@
           ProcessDefinition processDefinition, 
           ProcessInstance processInstance, 
           MigrationDescriptor migrationDescriptor) {
-    migrateExecutions(processDefinition, processInstance, migrationDescriptor);
+    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    for (String className : migrationDescriptor.getMigrationHandlerClassNames()) {
+      try {
+        Class<?> clazz = classLoader.loadClass(className);
+        MigrationHandler handler = (MigrationHandler)ReflectUtil.newInstance(clazz);
+        handler.migrateInstance(processDefinition, processInstance, migrationDescriptor);
+      } catch (ClassNotFoundException e) {
+        log.error("Class " + className + " not found on the classpath.", e);
+      }
+    }
+    //migrateExecutions(processDefinition, processInstance, migrationDescriptor);
     // migrateSwimlanes(processInstance, migrationDescriptor);
     // migrateVariables(processInstance, migrationDescriptor);
-    logMigration(processInstance, processDefinition);
+    //logMigration(processInstance, processDefinition);
   }
 
   private static void migrateExecutions(ProcessDefinition processDefinition, Execution execution, MigrationDescriptor migrationDescriptor) {
+    migrateChildExecutions(processDefinition, execution, migrationDescriptor);
+//    if (!(execution instanceof ExecutionImpl) || !(processDefinition instanceof ProcessDefinitionImpl))
+//      return;
+//    ((ExecutionImpl)execution).setProcessDefinition((ProcessDefinitionImpl)processDefinition);
+//    String oldName = ((ExecutionImpl) execution).getActivityName();
+//    if (oldName == null)
+//      return;
+//    String newName = migrationDescriptor.getNewName(MigrationDescriptor.ACTIVITY_TYPE, oldName);
+//    if (newName == null)
+//      return;
+//    Activity newActivity = ((ProcessDefinitionImpl) processDefinition).getActivity(newName);
+//    if (newActivity != null) {
+//      ((ExecutionImpl) execution).setActivity(newActivity);
+//    }
+  }
+  
+  private static void migrateChildExecutions(ProcessDefinition processDefinition, Execution execution, MigrationDescriptor migrationDescriptor) {
     for (Execution child : execution.getExecutions()) {
       migrateExecutions(processDefinition, child, migrationDescriptor);
     }
-    if (!(execution instanceof ExecutionImpl) || !(processDefinition instanceof ProcessDefinitionImpl))
-      return;
-    ((ExecutionImpl)execution).setProcessDefinition((ProcessDefinitionImpl)processDefinition);
-    String oldName = ((ExecutionImpl) execution).getActivityName();
-    if (oldName == null)
-      return;
-    String newName = migrationDescriptor.getNewName(MigrationDescriptor.ACTIVITY_TYPE, oldName);
-    if (newName == null)
-      return;
-    Activity newActivity = ((ProcessDefinitionImpl) processDefinition).getActivity(newName);
-    if (newActivity != null) {
-      ((ExecutionImpl) execution).setActivity(newActivity);
-    }
   }
 
-  private static void logMigration(ProcessInstance processInstance, ProcessDefinition processDefinition) {
-    ProcessInstanceMigration processInstanceMigrate = new ProcessInstanceMigration(processInstance, processDefinition);
-    HistoryEvent.fire(processInstanceMigrate);
+//  private static void logMigration(ProcessInstance processInstance, ProcessDefinition processDefinition) {
+//    ProcessInstanceMigration processInstanceMigrate = new ProcessInstanceMigration(processInstance, processDefinition);
+//    HistoryEvent.fire(processInstanceMigrate);
+//  }
+  
+  private static List<ProcessInstance> getProcessInstancesToMigrate(String processDefinitionName, MigrationDescriptor migrationDescriptor) {
+    List<ProcessInstance> result = new ArrayList<ProcessInstance>();
+    ExecutionService executionService = (ExecutionService) EnvironmentImpl.getFromCurrent(ExecutionService.class);
+    List<ProcessDefinition> processesToMigrate = getProcessesToMigrate(processDefinitionName, migrationDescriptor);
+    for (ProcessDefinition processDefinition : processesToMigrate) {
+      result.addAll(
+              executionService
+                .createProcessInstanceQuery()
+                .processDefinitionId(processDefinition.getId()).list());
+    }
+    return result;
   }
 
-  private static String getOldVersionId(String processDefinitionName) {
+  private static List<ProcessDefinition> getProcessesToMigrate(String processDefinitionName, MigrationDescriptor migrationDescriptor) {
     RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
-    ProcessDefinition process = repositorySession.createProcessDefinitionQuery().processDefinitionName(processDefinitionName).orderDesc(
-            ProcessDefinitionQuery.PROPERTY_VERSION).page(1, 1).uniqueResult();
-    if (process != null) {
-      return process.getId();
+    List<ProcessDefinition> processDefinitions = repositorySession
+        .createProcessDefinitionQuery()
+        .processDefinitionName(processDefinitionName)
+        .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)
+        .list();
+    int startIndex = calculateStartIndex(processDefinitions.size() - 1, migrationDescriptor);
+    int endIndex = calculateEndIndex(processDefinitions.size() - 1, migrationDescriptor);
+    if (startIndex > endIndex) startIndex = endIndex;
+    return processDefinitions.subList(startIndex, endIndex);
+  }
+  
+  private static int calculateStartIndex(int max, MigrationDescriptor migrationDescriptor) {
+    int result = max - 1;
+    if (migrationDescriptor.getStartVersion() != -1) {
+      result = migrationDescriptor.getStartVersion() - 1;
+    } else if (migrationDescriptor.getStartOffset() != -1) {
+      result = max - migrationDescriptor.getStartOffset();
     }
-    return null;
+    if (result < 0) result = 0;
+    if (result > max - 1) result = max - 1;
+    return result;
   }
-
+  
+  private static int calculateEndIndex(int max, MigrationDescriptor migrationDescriptor) {
+    int result = max;
+    if (migrationDescriptor.getEndVersion() != -1) {
+      result = migrationDescriptor.getEndVersion();
+    } else if (migrationDescriptor.getEndOffset() != -1) {
+      result = max - migrationDescriptor.getEndOffset() + 1;
+    }
+    if (result < 1) result = 1;
+    if (result > max - 1) result = max;
+    return result;
+  }
+  
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationDescriptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationDescriptor.java	2009-10-15 22:59:55 UTC (rev 5746)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationDescriptor.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -1,6 +1,8 @@
 package org.jbpm.pvm.internal.migration;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class MigrationDescriptor {
@@ -10,6 +12,13 @@
   public static final String SWIMLANE_TYPE = "org.jbpm.pvm.internal.migration.swimlane";
 
   private Map<String, Map<String, String>> migrationMap = new HashMap<String, Map<String, String>>();
+  private List<String> migrationHandlerClassNames = new ArrayList<String>();
+  
+  private int startOffset = -1;
+  private int endOffset = -1;
+  
+  private int startVersion = -1;
+  private int endVersion = -1;
 
   public void addMigrationElement(String type, String oldName, String newName) {
     Map<String, String> typeMap = migrationMap.get(type);
@@ -28,5 +37,45 @@
     }
     return result;
   }
+  
+  public void addMigrationHandlerClassName(String className) {
+    migrationHandlerClassNames.add(className);
+  }
+  
+  public List<String> getMigrationHandlerClassNames() {
+    return migrationHandlerClassNames;
+  }
+  
+  public int getStartOffset() {
+    return startOffset;
+  }
+  
+  public void setStartOffset(int startOffset) {
+    this.startOffset = startOffset;
+  }
+  
+  public int getEndOffset() {
+    return endOffset;
+  }
+  
+  public void setEndOffset(int endOffset) {
+    this.endOffset = endOffset;
+  }
+  
+  public int getStartVersion() {
+    return startVersion;
+  }
+  
+  public void setStartVersion(int startVersion) {
+    this.startVersion = startVersion;
+  }
+  
+  public int getEndVersion() {
+    return endVersion;
+  }
+  
+  public void setEndVersion(int endVersion) {
+    this.endVersion = endVersion;
+  }
 
 }

Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationHandler.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationHandler.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationHandler.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -0,0 +1,14 @@
+package org.jbpm.pvm.internal.migration;
+
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessInstance;
+
+
+public interface MigrationHandler {
+  
+  void migrateInstance(
+          ProcessDefinition newProcessDefinition, 
+          ProcessInstance processInstance,
+          MigrationDescriptor migrationDescriptor);
+
+}


Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/migration/MigrationHandler.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Deleted: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java	2009-10-15 22:59:55 UTC (rev 5746)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -1,94 +0,0 @@
-package org.jbpm.test.migration;
-
-import org.jbpm.api.Execution;
-import org.jbpm.api.ProcessDefinition;
-import org.jbpm.api.ProcessInstance;
-import org.jbpm.test.JbpmTestCase;
-
-
-public class InstanceMigratorTest extends JbpmTestCase {
-  
-  private String firstVersion = 
-    "<process name='foobar'>" +
-    "  <start>" +
-    "    <transition to='foo'/>" +
-    "  </start>" +
-    "  <state name='foo'>" +
-    "    <transition to='bar'/>" +
-    "  </state>" +
-    "  <state name='bar'>" +
-    "    <transition to='end'/>" +
-    "  </state>" +
-    "  <end name='end'/>" +
-    "</process>";
-  
-  private String secondVersion = 
-    "<process name='foobar'>" +
-    "  <start>" +
-    "    <transition to='foo'/>" +
-    "  </start>" +
-    "  <state name='foo'>" +
-    "    <transition to='fu'/>" +
-    "  </state>" +
-    "  <state name='fu'>" +
-    "    <transition name='to end' to='end'/>" +
-    "    <transition name='to baz' to='baz'/>" +
-    "  </state>" +
-    "  <state name='baz'>" +
-    "    <transition to='end'/>" +
-    "  </state>" +
-    "  <end name='end'/>" +
-    "  <migrate-instances>" +
-    "    <activity-mapping old-name='bar' new-name='fu'/>" +
-    "  </migrate-instances>" +
-    "</process>";
-  
-  
-  public void testSimpleMigration() {
-    String deploymentId1 = repositoryService.createDeployment()
-        .addResourceFromString("foobar.jpdl.xml", firstVersion)
-        .deploy();
-    ProcessDefinition processDefinition1 = repositoryService
-        .createProcessDefinitionQuery()
-        .deploymentId(deploymentId1)
-        .uniqueResult();
-    Execution execution = executionService
-        .startProcessInstanceById(processDefinition1.getId())
-        .findActiveExecutionIn("foo");
-    executionService.signalExecutionById(execution.getId());
-    ProcessInstance processInstance1 = executionService
-        .createProcessInstanceQuery()
-        .processDefinitionId(processDefinition1.getId())
-        .uniqueResult();
-    execution = processInstance1.findActiveExecutionIn("bar");
-    assertNotNull(execution);
-    
-    String deploymentId2 = repositoryService.createDeployment()
-        .addResourceFromString("foobar.jpdl.xml", secondVersion)
-        .deploy();
-    ProcessDefinition processDefinition2 = repositoryService
-        .createProcessDefinitionQuery()
-        .deploymentId(deploymentId2)
-        .uniqueResult();
-    ProcessInstance processInstance2 = executionService
-        .createProcessInstanceQuery()
-        .processDefinitionId(processDefinition2.getId())
-        .uniqueResult();
-    execution = processInstance2.findActiveExecutionIn("fu");
-    assertNotNull(execution);
-    
-    executionService.signalExecutionById(execution.getId(), "to baz");
-    
-    processInstance2 = executionService
-      .createProcessInstanceQuery()
-      .processDefinitionId(processDefinition2.getId())
-      .uniqueResult();
-    execution = processInstance2.findActiveExecutionIn("baz");
-    assertNotNull(execution);
-    
-    repositoryService.deleteDeploymentCascade(deploymentId2);
-    repositoryService.deleteDeploymentCascade(deploymentId1);
-    
-  }
-
-}

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/migration/InstanceMigratorTest.java	2009-10-16 02:31:43 UTC (rev 5747)
@@ -0,0 +1,437 @@
+package org.jbpm.test.migration;
+
+import java.util.HashSet;
+
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.pvm.internal.migration.MigrationDescriptor;
+import org.jbpm.pvm.internal.migration.MigrationHandler;
+import org.jbpm.test.JbpmTestCase;
+
+
+public class InstanceMigratorTest extends JbpmTestCase {
+  
+  private String originalVersion = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "</process>";
+  
+  private String versionWithMigrationHandler = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances action='custom'>" +
+    "    <migration-handler class='org.jbpm.test.migration.InstanceMigratorTest$TestHandler'/>" +
+    "  </migrate-instances>" +
+    "</process>";
+  
+  private String versionWithSimpleAbortion = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances action='abort'/>" +
+    "</process>";
+  
+  private String versionWithSimpleMigration = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances/>" +
+    "</process>";
+  
+  private String versionWithCorrectMappings = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='d'/>" +
+    "  </state>" +
+    "  <state name='d'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances>" +
+    "    <activity-mapping old-name='b' new-name='a'/>" +
+    "    <activity-mapping old-name='c' new-name='d'/>" +
+    "  </migrate-instances>" +
+    "</process>";
+  
+  private String versionWithIncorrectMappings = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='d'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances>" +
+    "    <activity-mapping old-name='a' new-name='z'/>" +
+    "    <activity-mapping old-name='b' new-name='c'/>" +
+    "  </migrate-instances>" +
+    "</process>";
+
+  private String versionWithAbsoluteVersionRange = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances versions='2..3'/>" +
+    "</process>";
+  
+  private String versionWithRelativeVersionRange = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances versions='x-2..x'/>" +
+    "</process>";
+
+  private String versionWithMixedVersionRange = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances versions='1..x-3'/>" +
+    "</process>";
+
+  private String versionWithWildcardVersionRange = 
+    "<process name='foobar'>" +
+    "  <start>" +
+    "    <transition to='a'/>" +
+    "  </start>" +
+    "  <state name='a'>" +
+    "    <transition to='b'/>" +
+    "  </state>" +
+    "  <state name='b'>" +
+    "    <transition to='c'/>" +
+    "  </state>" +
+    "  <state name='c'>" +
+    "    <transition to='end'/>" +
+    "  </state>" +
+    "  <end name='end'/>" +
+    "  <migrate-instances versions='*'/>" +
+    "</process>";
+
+  private static HashSet<String> PROCESS_INSTANCES_SET = new HashSet<String>();
+  
+  public static class TestHandler implements MigrationHandler {
+    public void migrateInstance(
+            ProcessDefinition processDefinition, 
+            ProcessInstance processInstance,
+            MigrationDescriptor migrationDescriptor) {
+      PROCESS_INSTANCES_SET.add(processInstance.getId());
+    }    
+  }
+  
+  protected void tearDown() throws Exception {
+    PROCESS_INSTANCES_SET.clear();
+    super.tearDown();
+  }
+  
+    
+  private ProcessDefinition deployProcessDefinition(String name, String processDefinitionXml) {
+    String deploymentId = repositoryService
+        .createDeployment()
+        .addResourceFromString(name + ".jpdl.xml", processDefinitionXml)
+        .deploy();
+    return repositoryService
+        .createProcessDefinitionQuery()
+        .deploymentId(deploymentId)
+        .uniqueResult();
+  }
+  
+  private ProcessInstance startAndSignal(ProcessDefinition processDefinition, String endActivityName) {
+    ProcessInstance result = executionService
+        .startProcessInstanceById(processDefinition.getId());
+    while (result.findActiveExecutionIn(endActivityName) == null) {
+      result = executionService.signalExecutionById(result.getId());
+    }
+    return result;
+  }
+    
+
+  public void testNoMigration() {    
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessInstance pi2 = startAndSignal(pd1, "b");    
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", originalVersion);   
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    assertEquals(pd1.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd1.getId(), pi2.getProcessDefinitionId());    
+    assertTrue(pi1.findActiveActivityNames().contains("a"));
+    assertTrue(pi2.findActiveActivityNames().contains("b"));
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+  }
+  
+  public void testMigrationHandler() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessInstance pi2 = startAndSignal(pd1, "b");    
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", versionWithMigrationHandler);    
+    assertTrue(PROCESS_INSTANCES_SET.contains(pi1.getId()));
+    assertTrue(PROCESS_INSTANCES_SET.contains(pi2.getId()));
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+  }
+  
+  public void testSimpleAbortion() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessInstance pi2 = startAndSignal(pd1, "b");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", versionWithSimpleAbortion);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    assertNull(pi1);
+    assertNull(pi2);
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+  }
+  
+  public void testSimpleMigration() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessInstance pi2 = startAndSignal(pd1, "b");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", versionWithSimpleMigration);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    assertEquals(pd2.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd2.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pi1, pi1.findActiveExecutionIn("a"));
+    assertEquals(pi2, pi2.findActiveExecutionIn("b"));
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+  }
+  
+  public void testCorrectlyMappedMigration() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessInstance pi2 = startAndSignal(pd1, "b");
+    ProcessInstance pi3 = startAndSignal(pd1, "c");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", versionWithCorrectMappings);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    assertEquals(pd2.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd2.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pd2.getId(), pi3.getProcessDefinitionId());
+    assertEquals(pi1, pi1.findActiveExecutionIn("a"));
+    assertEquals(pi2, pi2.findActiveExecutionIn("a"));
+    assertEquals(pi3, pi3.findActiveExecutionIn("d"));
+    pi1 = executionService.signalExecutionById(pi1.getId());
+    pi2 = executionService.signalExecutionById(pi2.getId());
+    pi2 = executionService.signalExecutionById(pi2.getId());
+    pi3 = executionService.signalExecutionById(pi3.getId());
+    assertEquals(pi1, pi1.findActiveExecutionIn("b"));
+    assertEquals(pi2, pi2.findActiveExecutionIn("c"));
+    assertTrue(pi3.isEnded());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    assertNull(pi3);
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+  }
+  
+  public void testIncorrectlyMappedMigration() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    startAndSignal(pd1, "a");
+    startAndSignal(pd1, "b");
+    try {
+      deployProcessDefinition("foobar", versionWithIncorrectMappings);
+      fail();
+    } catch (JbpmException e) {
+      repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    }
+  }
+  
+  public void testAbsoluteVersionRange() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi2 = startAndSignal(pd2, "a");
+    ProcessDefinition pd3 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi3 = startAndSignal(pd3, "a");
+    ProcessDefinition pd4 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi4 = startAndSignal(pd4, "a");
+    ProcessDefinition pd5 = deployProcessDefinition("foobar", versionWithAbsoluteVersionRange);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    pi4 = executionService.findProcessInstanceById(pi4.getId());
+    assertEquals(pd1.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi3.getProcessDefinitionId());
+    assertEquals(pd4.getId(), pi4.getProcessDefinitionId());
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd3.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd4.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd5.getDeploymentId());   
+  }
+
+  public void testRelativeVersionRange() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi2 = startAndSignal(pd2, "a");
+    ProcessDefinition pd3 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi3 = startAndSignal(pd3, "a");
+    ProcessDefinition pd4 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi4 = startAndSignal(pd4, "a");
+    ProcessDefinition pd5 = deployProcessDefinition("foobar", versionWithRelativeVersionRange);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    pi4 = executionService.findProcessInstanceById(pi4.getId());
+    assertEquals(pd1.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd2.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi3.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi4.getProcessDefinitionId());
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd3.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd4.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd5.getDeploymentId());   
+  }
+
+  public void testMixedVersionRange() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi2 = startAndSignal(pd2, "a");
+    ProcessDefinition pd3 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi3 = startAndSignal(pd3, "a");
+    ProcessDefinition pd4 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi4 = startAndSignal(pd4, "a");
+    ProcessDefinition pd5 = deployProcessDefinition("foobar", versionWithMixedVersionRange);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    pi4 = executionService.findProcessInstanceById(pi4.getId());
+    assertEquals(pd5.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pd3.getId(), pi3.getProcessDefinitionId());
+    assertEquals(pd4.getId(), pi4.getProcessDefinitionId());
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd3.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd4.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd5.getDeploymentId());   
+  }
+
+  public void testWildcardVersionRange() {
+    ProcessDefinition pd1 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi1 = startAndSignal(pd1, "a");
+    ProcessDefinition pd2 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi2 = startAndSignal(pd2, "a");
+    ProcessDefinition pd3 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi3 = startAndSignal(pd3, "a");
+    ProcessDefinition pd4 = deployProcessDefinition("foobar", originalVersion);
+    ProcessInstance pi4 = startAndSignal(pd4, "a");
+    ProcessDefinition pd5 = deployProcessDefinition("foobar", versionWithWildcardVersionRange);
+    pi1 = executionService.findProcessInstanceById(pi1.getId());
+    pi2 = executionService.findProcessInstanceById(pi2.getId());
+    pi3 = executionService.findProcessInstanceById(pi3.getId());
+    pi4 = executionService.findProcessInstanceById(pi4.getId());
+    assertEquals(pd5.getId(), pi1.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi2.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi3.getProcessDefinitionId());
+    assertEquals(pd5.getId(), pi4.getProcessDefinitionId());
+    repositoryService.deleteDeploymentCascade(pd1.getDeploymentId());
+    repositoryService.deleteDeploymentCascade(pd2.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd3.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd4.getDeploymentId());   
+    repositoryService.deleteDeploymentCascade(pd5.getDeploymentId());   
+  }
+
+}


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



More information about the jbpm-commits mailing list