📄 undotest.java
字号:
package org.jbpm.service;
import java.util.*;
import junit.framework.*;
import org.jbpm.*;
import org.jbpm.delegation.*;
import org.jbpm.model.definition.*;
import org.jbpm.model.execution.impl.*;
import org.jbpm.model.log.*;
public class UndoTest extends TestCase {
public static TestHelper helper = new TestHelper();
private ExecutionService executionService = helper.getExecutionService();
static {
helper.deployProcess( "process/undoableprocess.xml" );
helper.deployProcess( "process/undoableactionprocess.xml" );
}
public void testStateUndo() throws Exception {
// retrieve the definition
Definition definition = executionService.getLatestDefinition( "the undoable process" );
// start a process instance
InvocationLog invocationLog = executionService.startProcessInstance( "start-actor", definition.getId() );
ProcessInstanceImpl pi = (ProcessInstanceImpl) invocationLog.getProcessInstance();
Long piId = pi.getId();
Long tokenId = pi.getRoot().getId();
Date date = new Date();
// now we are going to execute the process like the procession of Echternach
// thats a procession in which the participants take two steps forward and one step back :-)
// one step forward
assertEquals( "one", getStateName( tokenId ) );
InvocationLog firstInvocationLog = executionService.endOfState( "actor-one", tokenId );
assertEquals( "two", getStateName( tokenId ) );
// one step back
executionService.undo( "testrunner", piId, firstInvocationLog.getDate() );
assertEquals( "one", getStateName( tokenId ) );
// two steps forward
firstInvocationLog = executionService.endOfState( "actor-two", tokenId );
InvocationLog secondInvocationLog = executionService.endOfState( "actor-three", tokenId );
assertEquals( "three", getStateName( tokenId ) );
// one step back
executionService.undo( "testrunner", piId, secondInvocationLog.getDate() );
assertEquals( "two", getStateName( tokenId ) );
// one step forward
executionService.endOfState( "actor-four", tokenId );
invocationLog = executionService.endOfState( "actor-five", tokenId );
// check that the process has ended
Date firstEndDate = invocationLog.getProcessInstance().getEnd();
assertTrue( isPiEnded( piId ) );
assertTrue( isRootEnded( piId ) );
// two steps back
executionService.undo( "testrunner", piId, date );
assertEquals( "one", getStateName( tokenId ) );
assertFalse( isPiEnded( piId ) );
assertFalse( isRootEnded( piId ) );
// three steps forward
executionService.endOfState( "actor-three", tokenId );
assertEquals( "two", getStateName( tokenId ) );
executionService.endOfState( "actor-four", tokenId );
assertEquals( "three", getStateName( tokenId ) );
date = new Date();
invocationLog = executionService.endOfState( "actor-five", tokenId );
assertTrue( isPiEnded( piId ) );
assertTrue( isRootEnded( piId ) );
// one step back
executionService.undo( "testrunner", piId, date );
assertEquals( "three", getStateName( tokenId ) );
assertFalse( isPiEnded( piId ) );
assertFalse( isRootEnded( piId ) );
}
public boolean isPiEnded( Long processInstanceId ) {
ProcessInstanceImpl pi = (ProcessInstanceImpl) executionService.getProcessInstance( processInstanceId, null );
return pi.hasEnded();
}
public boolean isRootEnded( Long processInstanceId ) {
ProcessInstanceImpl pi = (ProcessInstanceImpl) executionService.getProcessInstance( processInstanceId, null );
return pi.getRoot().hasEnded();
}
public void testUndoException() throws Exception {
// retrieve the definition
Definition definition = executionService.getLatestDefinition( "the undoable process" );
// start a process instance
InvocationLog invocationLog = executionService.startProcessInstance( "start-actor", definition.getId() );
ProcessInstanceImpl pi = (ProcessInstanceImpl) invocationLog.getProcessInstance();
Long piId = pi.getId();
Long tokenId = pi.getRoot().getId();
// now we are going to execute the process like the procession of Echternach
// thats a procession in which the participants take two steps forward and one step back :-)
try {
// rollback the process till 1900 somewhere
executionService.undo( "testrunner", piId, new Date( 0 ) );
fail();
} catch (UnUndoableException e) {
// OK
}
try {
// rollback the process till one minute in the future
executionService.undo( "testrunner", piId, new Date( new Date().getTime() + (1000*60) ) );
fail();
} catch (UnUndoableException e) {
// OK
}
}
private String getStateName(Long tokenId) {
TokenImpl token = (TokenImpl) executionService.getToken( tokenId, null );
return token.getState().getName();
}
public void testVariablesUndo() throws Exception {
// retrieve the definition
Definition definition = executionService.getLatestDefinition( "the undoable process" );
// create the variables
Map variables = new HashMap();
variables.put( "text", "this text wants to remain the same" );
variables.put( "number", new Long(1) );
variables.put( "overridden.text", "this text wants to be changed and undone" );
variables.put( "overridden.number", new Long(2) );
// start a process instance
InvocationLog invocationLog = executionService.startProcessInstance( "start-actor", definition.getId(), variables );
ProcessInstanceImpl pi = (ProcessInstanceImpl) invocationLog.getProcessInstance();
Long piId = pi.getId();
Long tokenId = pi.getRoot().getId();
// check the process variables
variables = executionService.getVariables( tokenId );
checkVariablesInStateOne(variables);
// remember the date for later rollback
Date date = new Date();
// one step forward
variables = new HashMap();
variables.put( "added.variable", "with a fresh value" );
variables.put( "overridden.text", "undo me !" );
variables.put( "overridden.number", new Long(13) ); // if even this number works, it *must* be correct
executionService.endOfState( "actor-one", tokenId, variables );
// check the process variables
variables = executionService.getVariables( tokenId );
assertEquals( "this text wants to remain the same", variables.get( "text" ) );
assertEquals( new Long(1), variables.get( "number" ) );
assertEquals( "undo me !", variables.get( "overridden.text" ) );
assertEquals( new Long(13), variables.get( "overridden.number" ) );
assertEquals( "with a fresh value", variables.get( "added.variable" ) );
// one step back
executionService.undo( "testrunner", piId, date );
// check the process variables
variables = executionService.getVariables( tokenId );
checkVariablesInStateOne(variables);
}
private void checkVariablesInStateOne(Map variables) {
assertEquals( "this text wants to remain the same", variables.get( "text" ) );
assertEquals( new Long(1), variables.get( "number" ) );
assertEquals( "this text wants to be changed and undone", variables.get( "overridden.text" ) );
assertEquals( new Long(2), variables.get( "overridden.number" ) );
assertNull( variables.get( "added.variable" ) );
}
public static class UndoableTestActionHandler implements UndoableActionHandler {
public static boolean hasBeenExecuted = false;
public static boolean hasBeenUndone = false;
public static Object variableValue = null;
public void execute(ExecutionContext executionContext) {
hasBeenExecuted = true;
executionContext.setVariable( "action var", "the original value" );
}
public void undo(ExecutionContext executionContext) {
hasBeenUndone = true;
variableValue = executionContext.getVariable( "client var" );
executionContext.setVariable( "action var", "undo value" );
}
}
public void testUndoableActionHandler() throws Exception {
// retrieve the definition
Definition definition = executionService.getLatestDefinition( "the undoable action process" );
// create the variables
Map variables = new HashMap();
variables.put( "client var", "the client value" );
// start a process instance
InvocationLog invocationLog = executionService.startProcessInstance( "start-actor", definition.getId(), variables );
ProcessInstanceImpl pi = (ProcessInstanceImpl) invocationLog.getProcessInstance();
Long piId = pi.getId();
Long tokenId = pi.getRoot().getId();
Date date = new Date();
assertFalse( UndoableTestActionHandler.hasBeenExecuted );
assertFalse( UndoableTestActionHandler.hasBeenUndone );
executionService.endOfState( "actor-one", tokenId );
variables = executionService.getVariables( tokenId );
assertEquals( "the client value", variables.get( "client var" ) );
assertEquals( "the original value", variables.get( "action var" ) );
assertTrue( UndoableTestActionHandler.hasBeenExecuted );
assertFalse( UndoableTestActionHandler.hasBeenUndone );
executionService.undo( "actor-one", piId, date );
variables = executionService.getVariables( tokenId );
assertEquals( "the client value", variables.get( "client var" ) );
// the action var variable instance is created in the action, that's why it should be null after the undo
assertNull( variables.get( "action var" ) );
assertEquals( "the client value", UndoableTestActionHandler.variableValue );
assertTrue( UndoableTestActionHandler.hasBeenExecuted );
assertTrue( UndoableTestActionHandler.hasBeenUndone );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -