Permalink
Browse files

Fixed ACT-1731: eager init of binary variables when included in query

  • Loading branch information...
frederikheremans committed Jul 17, 2013
1 parent 88c789e commit 6934243a916bed7010c26a006e06724fd5b5ffe7
@@ -1387,9 +1387,14 @@ public String getCurrentActivityName() {
}
return variables;
}

public List<VariableInstanceEntity> getQueryVariables() {
if(queryVariables == null && Context.getCommandContext() != null) {
queryVariables = new VariableInitializingList();
}
return queryVariables;
}

public void setQueryVariables(List<VariableInstanceEntity> queryVariables) {
this.queryVariables = queryVariables;
}
@@ -19,6 +19,7 @@
import java.util.Map;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.util.ClockUtil;

@@ -114,8 +115,12 @@ public void setSuperProcessInstanceId(String superProcessInstanceId) {
}

public List<HistoricVariableInstanceEntity> getQueryVariables() {
if(queryVariables == null && Context.getCommandContext() != null) {
queryVariables = new HistoricVariableInitializingList();
}
return queryVariables;
}

public void setQueryVariables(List<HistoricVariableInstanceEntity> queryVariables) {
this.queryVariables = queryVariables;
}
@@ -19,6 +19,7 @@
import java.util.Map;

import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.db.PersistentObject;
import org.activiti.engine.impl.util.ClockUtil;

@@ -186,9 +187,14 @@ public Long getWorkTimeInMillis() {
}
return variables;
}

public List<HistoricVariableInstanceEntity> getQueryVariables() {
if(queryVariables == null && Context.getCommandContext() != null) {
queryVariables = new HistoricVariableInitializingList();
}
return queryVariables;
}

public void setQueryVariables(List<HistoricVariableInstanceEntity> queryVariables) {
this.queryVariables = queryVariables;
}
@@ -0,0 +1,67 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.activiti.engine.impl.persistence.entity;

import java.util.ArrayList;
import java.util.Collection;

import org.activiti.engine.impl.context.Context;


/**
* List that initialises binary variable values if command-context is active.
*
* @author Frederik Heremans
*/
public class HistoricVariableInitializingList extends ArrayList<HistoricVariableInstanceEntity> {

private static final long serialVersionUID = 1L;

@Override
public void add(int index, HistoricVariableInstanceEntity e) {
super.add(index, e);
initializeBinaryVariable(e);
}

@Override
public boolean add(HistoricVariableInstanceEntity e) {
initializeBinaryVariable(e);
return super.add(e);
}
@Override
public boolean addAll(Collection< ? extends HistoricVariableInstanceEntity> c) {
for(HistoricVariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(c);
}
@Override
public boolean addAll(int index, Collection< ? extends HistoricVariableInstanceEntity> c) {
for(HistoricVariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(index, c);
}

/**
* If the passed {@link HistoricVariableInstanceEntity} is a binary variable and the command-context is active,
* the variable value is fetched to ensure the byte-array is populated.
*/
@SuppressWarnings("deprecation")
protected void initializeBinaryVariable(HistoricVariableInstanceEntity e) {
if(Context.getCommandContext() != null && e != null && e.getByteArrayValueId() != null) {
e.getValue();
}
}
}
@@ -733,50 +733,4 @@ public void setQueryVariables(List<VariableInstanceEntity> queryVariables) {
this.queryVariables = queryVariables;
}

/**
* List that initialized binary variable values if command-context is active.
*
* @author Frederik Heremans
*/
private class VariableInitializingList extends ArrayList<VariableInstanceEntity> {

private static final long serialVersionUID = 1L;

@Override
public void add(int index, VariableInstanceEntity e) {
super.add(index, e);
initializeBinaryVariable(e);
}

@Override
public boolean add(VariableInstanceEntity e) {
initializeBinaryVariable(e);
return super.add(e);
}
@Override
public boolean addAll(Collection< ? extends VariableInstanceEntity> c) {
for(VariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(c);
}
@Override
public boolean addAll(int index, Collection< ? extends VariableInstanceEntity> c) {
for(VariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(index, c);
}

/**
* If the passed {@link VariableInstanceEntity} is a binary variable and the command-context is active,
* the variable value is fetched to ensure the byte-array is populated.
*/
@SuppressWarnings("deprecation")
protected void initializeBinaryVariable(VariableInstanceEntity e) {
if(Context.getCommandContext() != null && e != null && e.getByteArrayValueId() != null) {
e.getValue();
}
}
}
}
@@ -0,0 +1,67 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.activiti.engine.impl.persistence.entity;

import java.util.ArrayList;
import java.util.Collection;

import org.activiti.engine.impl.context.Context;


/**
* List that initialises binary variable values if command-context is active.
*
* @author Frederik Heremans
*/
public class VariableInitializingList extends ArrayList<VariableInstanceEntity> {

private static final long serialVersionUID = 1L;

@Override
public void add(int index, VariableInstanceEntity e) {
super.add(index, e);
initializeBinaryVariable(e);
}

@Override
public boolean add(VariableInstanceEntity e) {
initializeBinaryVariable(e);
return super.add(e);
}
@Override
public boolean addAll(Collection< ? extends VariableInstanceEntity> c) {
for(VariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(c);
}
@Override
public boolean addAll(int index, Collection< ? extends VariableInstanceEntity> c) {
for(VariableInstanceEntity e : c) {
initializeBinaryVariable(e);
}
return super.addAll(index, c);
}

/**
* If the passed {@link VariableInstanceEntity} is a binary variable and the command-context is active,
* the variable value is fetched to ensure the byte-array is populated.
*/
@SuppressWarnings("deprecation")
protected void initializeBinaryVariable(VariableInstanceEntity e) {
if(Context.getCommandContext() != null && e != null && e.getByteArrayValueId() != null) {
e.getValue();
}
}
}
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -1322,6 +1323,24 @@ public void testNativeQuery() {
assertEquals(piCount, runtimeService.createNativeProcessInstanceQuery().sql("SELECT count(*) FROM " + managementService.getTableName(ProcessInstance.class)).count());
}

/**
* Test confirming fix for ACT-1731
*/
@Deployment(resources={
"org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml"})
public void testIncludeBinaryVariables() throws Exception {
// Start process with a binary variable
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess",
Collections.singletonMap("binaryVariable", (Object)"It is I, le binary".getBytes()));

processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId())
.includeProcessVariables().singleResult();
assertNotNull(processInstance);
// Query process, including variables
byte[] bytes = (byte[]) processInstance.getProcessVariables().get("binaryVariable");
assertEquals("It is I, le binary", new String(bytes));
}

public void testNativeQueryPaging() {
assertEquals(5, runtimeService.createNativeProcessInstanceQuery().sql("SELECT * FROM " + managementService.getTableName(ProcessInstance.class)).listPage(0, 5).size());
}
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -949,6 +950,33 @@ public void testNativeQuery() {
assertEquals(1, taskService.createNativeTaskQuery().sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T WHERE T.NAME_ = #{taskName}").parameter("taskName", "gonzoTask").count());
}

/**
* Test confirming fix for ACT-1731
*/
@Deployment(resources={"org/activiti/engine/test/api/task/TaskQueryTest.testProcessDefinition.bpmn20.xml"})
public void testIncludeBinaryVariables() throws Exception {
// Start process with a binary variable
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess",
Collections.singletonMap("binaryVariable", (Object)"It is I, le binary".getBytes()));
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task);
taskService.setVariableLocal(task.getId(), "binaryTaskVariable", (Object)"It is I, le binary".getBytes());

// Query task, including processVariables
task = taskService.createTaskQuery().taskId(task.getId()).includeProcessVariables().singleResult();
assertNotNull(task);
assertNotNull(task.getProcessVariables());
byte[] bytes = (byte[]) task.getProcessVariables().get("binaryVariable");
assertEquals("It is I, le binary", new String(bytes));

// Query task, including taskVariables
task = taskService.createTaskQuery().taskId(task.getId()).includeTaskLocalVariables().singleResult();
assertNotNull(task);
assertNotNull(task.getTaskLocalVariables());
bytes = (byte[]) task.getTaskLocalVariables().get("binaryTaskVariable");
assertEquals("It is I, le binary", new String(bytes));
}

/**
* Generates some test tasks. - 6 tasks where kermit is a candidate - 1 tasks
* where gonzo is assignee - 2 tasks assigned to management group - 2 tasks
@@ -15,6 +15,7 @@

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -28,6 +29,8 @@
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricFormProperty;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.history.HistoricVariableInstanceQuery;
import org.activiti.engine.history.HistoricVariableUpdate;
@@ -1299,4 +1302,59 @@ public void testReadJpaVariableValueFromHistoricVariableUpdate() {

assertEquals(entity.getId(), ((FieldAccessJPAEntity)update.getValue()).getId());
}

/**
* Test confirming fix for ACT-1731
*/
@Deployment(
resources={"org/activiti/engine/test/history/oneTaskProcess.bpmn20.xml"})
public void testQueryHistoricTaskIncludeBinaryVariable() throws Exception {
// Start process with a binary variable
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess",
Collections.singletonMap("binaryVariable", (Object)"It is I, le binary".getBytes()));
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task);
taskService.setVariableLocal(task.getId(), "binaryTaskVariable", (Object)"It is I, le binary".getBytes());

// Complete task
taskService.complete(task.getId());

// Query task, including processVariables
HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery().taskId(task.getId()).includeProcessVariables().singleResult();
assertNotNull(historicTask);
assertNotNull(historicTask.getProcessVariables());
byte[] bytes = (byte[]) historicTask.getProcessVariables().get("binaryVariable");
assertEquals("It is I, le binary", new String(bytes));

// Query task, including taskVariables
historicTask = historyService.createHistoricTaskInstanceQuery().taskId(task.getId()).includeTaskLocalVariables().singleResult();
assertNotNull(historicTask);
assertNotNull(historicTask.getTaskLocalVariables());
bytes = (byte[]) historicTask.getTaskLocalVariables().get("binaryTaskVariable");
assertEquals("It is I, le binary", new String(bytes));
}

/**
* Test confirming fix for ACT-1731
*/
@Deployment(
resources={"org/activiti/engine/test/history/oneTaskProcess.bpmn20.xml"})
public void testQueryHistoricProcessInstanceIncludeBinaryVariable() throws Exception {
// Start process with a binary variable
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess",
Collections.singletonMap("binaryVariable", (Object)"It is I, le binary".getBytes()));
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task);

// Complete task to end process
taskService.complete(task.getId());

// Query task, including processVariables
HistoricProcessInstance historicProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getId()).includeProcessVariables().singleResult();
assertNotNull(historicProcess);
assertNotNull(historicProcess.getProcessVariables());
byte[] bytes = (byte[]) historicProcess.getProcessVariables().get("binaryVariable");
assertEquals("It is I, le binary", new String(bytes));

}
}

0 comments on commit 6934243

Please sign in to comment.