### Eclipse Workspace Patch 1.0 #P jbpm4 Index: modules/api/src/main/java/org/jbpm/api/Execution.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/Execution.java (revision 6426) +++ modules/api/src/main/java/org/jbpm/api/Execution.java (working copy) @@ -229,4 +229,7 @@ /** id of the process definition used for this execution */ String getProcessDefinitionId(); + + /** returns user id/name who started the process, can be null */ + String getInitiator(); } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/AddTaskCommentCmd.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/AddTaskCommentCmd.java (revision 6588) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/AddTaskCommentCmd.java (working copy) @@ -24,8 +24,11 @@ import org.jbpm.api.JbpmException; import org.jbpm.api.cmd.Environment; import org.jbpm.api.history.HistoryComment; +import org.jbpm.pvm.internal.client.ClientExecution; import org.jbpm.pvm.internal.history.model.HistoryCommentImpl; +import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl; import org.jbpm.pvm.internal.history.model.HistoryTaskImpl; +import org.jbpm.pvm.internal.model.ScopeInstanceImpl; import org.jbpm.pvm.internal.session.DbSession; @@ -51,7 +54,15 @@ throw new JbpmException("task "+taskDbid+" doesn't exist"); } HistoryCommentImpl comment = new HistoryCommentImpl(message); - historyTask.addDetail(comment); + + ClientExecution execution = dbSession.findExecutionById(historyTask.getExecutionId()); + if (execution != null) { + HistoryProcessInstanceImpl historyProcessInstance = dbSession.get(HistoryProcessInstanceImpl.class, ((ScopeInstanceImpl)execution.getProcessInstance()).getDbid()); + + historyTask.addDetail(comment, historyProcessInstance); + } else { + historyTask.addDetail(comment); + } dbSession.save(comment); return comment; } Index: modules/api/src/main/java/org/jbpm/api/history/HistoryDetailUpdate.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/history/HistoryDetailUpdate.java (revision 0) +++ modules/api/src/main/java/org/jbpm/api/history/HistoryDetailUpdate.java (revision 0) @@ -0,0 +1,19 @@ +package org.jbpm.api.history; + +/** + * Additional interface for HistoryDetails to allow retrieving both old and new values. + * + * @author Tom Baeyens + */ +public interface HistoryDetailUpdate { + + /** + * Returns previous value of the item. + */ + T getOldValue(); + + /** + * Returns new value of the item. + */ + T getNewValue(); +} Property changes on: modules\api\src\main\java\org\jbpm\api\history\HistoryDetailUpdate.java ___________________________________________________________________ Added: svn:keywords + Id Revision Added: svn:eol-style + LF Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryPriorityUpdateImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryPriorityUpdateImpl.java (revision 6403) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryPriorityUpdateImpl.java (working copy) @@ -21,11 +21,13 @@ */ package org.jbpm.pvm.internal.history.model; +import org.jbpm.api.history.HistoryDetailUpdate; + /** * @author Tom Baeyens */ -public class HistoryPriorityUpdateImpl extends HistoryDetailImpl { +public class HistoryPriorityUpdateImpl extends HistoryDetailImpl implements HistoryDetailUpdate { private static final long serialVersionUID = 1L; @@ -46,4 +48,12 @@ public String toString() { return (userId!=null ? userId+" updated priority" : "priority updated")+" from "+oldPriority+" to "+newPriority; } + + public Integer getNewValue() { + return this.newPriority; + } + + public Integer getOldValue() { + return this.oldPriority; + } } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceImpl.java (revision 6555) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceImpl.java (working copy) @@ -52,6 +52,9 @@ protected Date startTime; protected Date endTime; protected Long duration; + protected String subProcessInstanceId; + protected String superProcessInstanceId; + protected String initiator; protected int nextDetailIndex = 1; /** only here to get hibernate cascade */ @@ -80,6 +83,10 @@ this.key = processInstance.getKey(); this.state = "active"; this.startTime = Clock.getTime(); + this.initiator = processInstance.getInitiator(); + if (processInstance.getSuperProcessExecution() != null) { + this.superProcessInstanceId = processInstance.getSuperProcessExecution().getId(); + } } public void setEndTime(Date endTime) { @@ -118,6 +125,9 @@ public String getKey() { return key; } + public void setKey(String key) { + this.key = key; + } public String getState() { return state; } @@ -139,4 +149,19 @@ public Set getHistoryVariables() { return historyVariables; } + public String getSubProcessInstanceId() { + return subProcessInstanceId; + } + public String getSuperProcessInstanceId() { + return superProcessInstanceId; + } + public void setSubProcessInstanceId(String subProcessInstanceId) { + this.subProcessInstanceId = subProcessInstanceId; + } + public void setSuperProcessInstanceId(String superProcessInstanceId) { + this.superProcessInstanceId = superProcessInstanceId; + } + public String getInitiator() { + return this.initiator; + } } Index: modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java (revision 6403) +++ modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java (working copy) @@ -60,4 +60,10 @@ /** the outcome of this task */ String getOutcome(); + + /** name of this task */ + String getName(); + + /** date and time when this task was completed. This might be null. */ + Date getDuedate(); } \ No newline at end of file Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskAssignmentImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskAssignmentImpl.java (revision 6403) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskAssignmentImpl.java (working copy) @@ -21,11 +21,13 @@ */ package org.jbpm.pvm.internal.history.model; +import org.jbpm.api.history.HistoryDetailUpdate; + /** * @author Tom Baeyens */ -public class HistoryTaskAssignmentImpl extends HistoryDetailImpl { +public class HistoryTaskAssignmentImpl extends HistoryDetailImpl implements HistoryDetailUpdate { private static final long serialVersionUID = 1L; @@ -46,4 +48,12 @@ public String toString() { return (userId!=null ? userId+" assigned task" : "task assigned")+" from "+oldAssignee+" to "+newAssignee; } + + public String getNewValue() { + return this.newAssignee; + } + + public String getOldValue() { + return this.oldAssignee; + } } Index: modules/pvm/src/main/resources/jbpm.execution.hbm.xml =================================================================== --- modules/pvm/src/main/resources/jbpm.execution.hbm.xml (revision 6478) +++ modules/pvm/src/main/resources/jbpm.execution.hbm.xml (working copy) @@ -58,6 +58,7 @@ + executions = new ArrayList(); @@ -182,7 +185,9 @@ this.processInstance = this; this.state = STATE_CREATED; this.key = key; - + if (EnvironmentImpl.getCurrent() != null) { + this.initiator = EnvironmentImpl.getCurrent().getAuthenticatedUserId(); + } save(); HistoryEvent.fire(new ProcessInstanceCreate(), this); @@ -1041,6 +1046,7 @@ } subProcessInstance = (ExecutionImpl) processDefinition.createProcessInstance(key); subProcessInstance.setSuperProcessExecution(this); + return subProcessInstance; } @@ -1347,4 +1353,10 @@ public void setEventCompletedOperation(AtomicOperation eventCompletedOperation) { this.eventCompletedOperation = eventCompletedOperation; } + public String getInitiator() { + return initiator; + } + public void setInitiator(String initiator) { + this.initiator = initiator; + } } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskAssign.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskAssign.java (revision 6426) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskAssign.java (working copy) @@ -45,6 +45,8 @@ public void process() { DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class); HistoryTaskImpl historyTaskInstance = dbSession.get(HistoryTaskImpl.class, task.getDbid()); + + historyTaskInstance.updated(task); historyTaskInstance.setAssignee(assignee); } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java (revision 6478) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java (working copy) @@ -41,6 +41,7 @@ protected long dbid; protected int dbversion; + protected String name; protected String executionId; protected String assignee; protected String state; @@ -60,11 +61,14 @@ /** only here to get hibernate cascade */ protected Set details = new HashSet(); + + public HistoryTaskImpl() { } public HistoryTaskImpl(TaskImpl task) { this.dbid = task.getDbid(); + this.name = task.getName(); this.assignee = task.getAssignee(); this.priority = task.getPriority(); this.duedate = task.getDuedate(); @@ -97,6 +101,13 @@ this.details.add(detail); nextDetailIndex++; } + + public void addDetail(HistoryDetailImpl detail, HistoryProcessInstanceImpl historyProcessInstance) { + detail.setHistoryTask(this, nextDetailIndex); + detail.setHistoryProcessInstance(historyProcessInstance, nextDetailIndex); + this.details.add(detail); + nextDetailIndex++; + } // subtasks ///////////////////////////////////////////////////////////////// @@ -159,5 +170,11 @@ } public void setExecutionId(String executionId) { this.executionId = executionId; + } + public String getName() { + return this.name; } + public Date getDuedate() { + return this.duedate; + } } Index: modules/api/src/main/java/org/jbpm/api/history/HistoryProcessInstance.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/history/HistoryProcessInstance.java (revision 6403) +++ modules/api/src/main/java/org/jbpm/api/history/HistoryProcessInstance.java (working copy) @@ -46,6 +46,12 @@ /** the process instance id (== the root execution id) */ String getProcessInstanceId(); + + /** the supper process instance id */ + String getSuperProcessInstanceId(); + + /** the sub process instance id */ + String getSubProcessInstanceId(); /** reference to the process definition */ String getProcessDefinitionId(); @@ -73,4 +79,7 @@ /** Returns the name of the end state that was reached when the process was ended. */ String getEndActivityName(); + + /** returns user id/name who started this process instance */ + String getInitiator(); } \ No newline at end of file Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableImpl.java (revision 6478) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableImpl.java (working copy) @@ -75,13 +75,16 @@ if ( (value==null && newValue!=null) || (value!=null && (!value.equals(newValue))) ) { + addDetail(new HistoryVariableUpdateImpl(value, newValue)); this.value = newValue; - addDetail(new HistoryVariableUpdateImpl(value, newValue)); } } public void addDetail(HistoryDetailImpl detail) { detail.setHistoryVariable(this, nextDetailIndex); + detail.setHistoryProcessInstance(this.historyProcessInstance, nextDetailIndex); + detail.setHistoryTask(this.historyTask, nextDetailIndex); + details.add(detail); nextDetailIndex++; } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskDuedateUpdateImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskDuedateUpdateImpl.java (revision 6403) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskDuedateUpdateImpl.java (working copy) @@ -23,11 +23,13 @@ import java.util.Date; +import org.jbpm.api.history.HistoryDetailUpdate; + /** * @author Tom Baeyens */ -public class HistoryTaskDuedateUpdateImpl extends HistoryDetailImpl { +public class HistoryTaskDuedateUpdateImpl extends HistoryDetailImpl implements HistoryDetailUpdate { private static final long serialVersionUID = 1L; @@ -48,4 +50,12 @@ public String toString() { return (userId!=null ? userId+" updated task duedate" : "task duedate updated")+" from "+oldDuedate+" to "+newDuedate; } + + public Date getNewValue() { + return this.newDuedate; + } + + public Date getOldValue() { + return this.oldDuedate; + } } Index: modules/test-db/src/test/java/org/jbpm/test/query/HistoryDetailQueryTest.java =================================================================== --- modules/test-db/src/test/java/org/jbpm/test/query/HistoryDetailQueryTest.java (revision 6616) +++ modules/test-db/src/test/java/org/jbpm/test/query/HistoryDetailQueryTest.java (working copy) @@ -21,13 +21,17 @@ */ package org.jbpm.test.query; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.List; import org.jbpm.api.ProcessInstance; import org.jbpm.api.history.HistoryComment; import org.jbpm.api.history.HistoryDetail; import org.jbpm.api.history.HistoryDetailQuery; +import org.jbpm.api.history.HistoryDetailUpdate; import org.jbpm.api.task.Task; +import org.jbpm.pvm.internal.util.Clock; import org.jbpm.test.JbpmTestCase; import org.jbpm.test.assertion.QueryAssertions; @@ -148,4 +152,159 @@ taskService.deleteTaskCascade(task.getId()); } + @SuppressWarnings("unchecked") + public void testHistoryVariable() { + + deployJpdlXmlString("" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + ""); + ProcessInstance pi = executionService.startProcessInstanceByKey("HistoryTaskDetail"); + + assertEquals("alex", executionService.getVariable(pi.getId(), "variable-to-update")); + + executionService.setVariable(pi.getId(), "variable-to-update", "peter"); + + List tasks = taskService.findPersonalTasks("johndoe"); + assertEquals(1, tasks.size()); + + assertEquals("peter", executionService.getVariable(pi.getId(), "variable-to-update")); + + executionService.setVariable(pi.getId(), "variable-to-update", "jack"); + assertEquals("jack", historyService.getVariable(pi.getId(), "variable-to-update")); + + List history = historyService.createHistoryDetailQuery().processInstanceId(pi.getId()).list(); + assertNotNull(history); + assertEquals(2, history.size()); + assertEquals("updated variable variable-to-update from alex to peter", history.get(0).toString()); + assertEquals("updated variable variable-to-update from peter to jack", history.get(1).toString()); + + assertEquals("alex", ((HistoryDetailUpdate)history.get(0)).getOldValue()); + assertEquals("peter", ((HistoryDetailUpdate)history.get(0)).getNewValue()); + + assertEquals("peter", ((HistoryDetailUpdate)history.get(1)).getOldValue()); + assertEquals("jack", ((HistoryDetailUpdate)history.get(1)).getNewValue()); + } + + @SuppressWarnings("unchecked") + public void testTaskReassignment() { + deployJpdlXmlString( + "" + + " " + + " " + + " " + + " " + + "" + ); + + executionService.startProcessInstanceByKey("TaskCommentReassignment"); + + String taskId = taskService.createTaskQuery().uniqueResult().getId(); + + processEngine.setAuthenticatedUserId("johndoe"); + taskService.assignTask(taskId, "alex"); + + + List historyDetails = historyService.createHistoryDetailQuery().list(); + assertEquals(1, historyDetails.size()); + assertEquals("johndoe", historyDetails.get(0).getUserId()); + assertEquals("johndoe", ((HistoryDetailUpdate)historyDetails.get(0)).getOldValue()); + assertEquals("alex", ((HistoryDetailUpdate)historyDetails.get(0)).getNewValue()); + + } + + @SuppressWarnings("unchecked") + public void testTaskChangePriority() { + deployJpdlXmlString( + "" + + " " + + " " + + " " + + " " + + "" + ); + + executionService.startProcessInstanceByKey("TaskCommentReassignment"); + + String taskId = taskService.createTaskQuery().uniqueResult().getId(); + Task task = taskService.getTask(taskId); + task.setPriority(10); + processEngine.setAuthenticatedUserId("johndoe"); + taskService.saveTask(task); + + + List historyDetails = historyService.createHistoryDetailQuery().list(); + assertEquals(1, historyDetails.size()); + assertEquals("johndoe", historyDetails.get(0).getUserId()); + assertEquals(0, ((HistoryDetailUpdate)historyDetails.get(0)).getOldValue()); + assertEquals(10, ((HistoryDetailUpdate)historyDetails.get(0)).getNewValue()); + + } + + @SuppressWarnings("unchecked") + public void testTaskChangeDuedate() { + deployJpdlXmlString( + "" + + " " + + " " + + " " + + " " + + "" + ); + + executionService.startProcessInstanceByKey("TaskCommentReassignment"); + + String taskId = taskService.createTaskQuery().uniqueResult().getId(); + Task task = taskService.getTask(taskId); + try { + task.setDuedate(new SimpleDateFormat("yyyy-MM-dd").parse("2010-09-30")); + } catch (ParseException e) { + e.printStackTrace(); + } + processEngine.setAuthenticatedUserId("johndoe"); + taskService.saveTask(task); + + + List historyDetails = historyService.createHistoryDetailQuery().list(); + assertEquals(1, historyDetails.size()); + assertEquals("johndoe", historyDetails.get(0).getUserId()); + assertNull(((HistoryDetailUpdate)historyDetails.get(0)).getOldValue()); + assertNotNull(((HistoryDetailUpdate)historyDetails.get(0)).getNewValue()); + + } + + public void testHistoryTaskComment() { + + deployJpdlXmlString("" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + ""); + + ProcessInstance processInstance = executionService.startProcessInstanceByKey("HistoryTaskDetail"); + String processInstanceId = processInstance.getId(); + + List tasks = taskService.findPersonalTasks("johndoe"); + assertEquals(1, tasks.size()); + String taskId = tasks.get(0).getId(); + taskService.addTaskComment(taskId, "Hello world."); + + assertEquals(1, historyService.createHistoryDetailQuery().list().size()); + + assertEquals(1, historyService.createHistoryDetailQuery().processInstanceId(processInstanceId).comments().list().size()); + } + + } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceMigrationImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceMigrationImpl.java (revision 6403) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryProcessInstanceMigrationImpl.java (working copy) @@ -21,11 +21,13 @@ */ package org.jbpm.pvm.internal.history.model; +import org.jbpm.api.history.HistoryDetailUpdate; + /** * @author Koen Aers */ -public class HistoryProcessInstanceMigrationImpl extends HistoryDetailImpl { +public class HistoryProcessInstanceMigrationImpl extends HistoryDetailImpl implements HistoryDetailUpdate { private static final long serialVersionUID = 1L; @@ -46,4 +48,12 @@ public String toString() { return "migrated process instance " + this.historyProcessInstance.getProcessInstanceId() + " from " + oldProcessDefinitionId + " to " + newProcessDefinitionId; } + + public String getNewValue() { + return this.newProcessDefinitionId; + } + + public String getOldValue() { + return this.oldProcessDefinitionId; + } } Index: modules/pvm/src/main/resources/jbpm.history.hbm.xml =================================================================== --- modules/pvm/src/main/resources/jbpm.history.hbm.xml (revision 6478) +++ modules/pvm/src/main/resources/jbpm.history.hbm.xml (working copy) @@ -18,6 +18,8 @@ + + @@ -99,7 +101,8 @@ - + + @@ -108,6 +111,7 @@ + + index="IDX_HDET_HVAR" lazy="false"/> Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableUpdateImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableUpdateImpl.java (revision 6403) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryVariableUpdateImpl.java (working copy) @@ -21,11 +21,13 @@ */ package org.jbpm.pvm.internal.history.model; +import org.jbpm.api.history.HistoryDetailUpdate; + /** * @author Tom Baeyens */ -public class HistoryVariableUpdateImpl extends HistoryDetailImpl { +public class HistoryVariableUpdateImpl extends HistoryDetailImpl implements HistoryDetailUpdate { private static final long serialVersionUID = 1L; @@ -46,4 +48,14 @@ public String toString() { return (userId!=null ? userId+" " : "")+"updated variable "+this.historyVariable.getVariableName()+" from "+oldValue+" to "+newValue; } + + public String getNewValue() { + return this.newValue; + } + + public String getOldValue() { + return this.oldValue; + } + + }