提交 424f373f 编写于 作者: J Joram Barrez

Implementing ACT-2089 : Task sorting on due date needs to place those with due...

Implementing ACT-2089 : Task sorting on due date needs to place those with due date null after those with a duedate

Note that this is implemented in a generic way. If other queries would benefit from nulls first/last it could easily be added now.
上级 40c48009
...@@ -17,6 +17,7 @@ import java.util.List; ...@@ -17,6 +17,7 @@ import java.util.List;
import org.activiti.engine.ActivitiException; import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException; import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.db.ListQueryParameterObject; import org.activiti.engine.impl.db.ListQueryParameterObject;
import org.activiti.engine.impl.interceptor.Command; import org.activiti.engine.impl.interceptor.Command;
...@@ -41,15 +42,25 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa ...@@ -41,15 +42,25 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa
private static enum ResultType { private static enum ResultType {
LIST, LIST_PAGE, SINGLE_RESULT, COUNT LIST, LIST_PAGE, SINGLE_RESULT, COUNT
} }
protected transient CommandExecutor commandExecutor; protected transient CommandExecutor commandExecutor;
protected transient CommandContext commandContext; protected transient CommandContext commandContext;
protected String databaseType;
protected String orderBy; protected String orderBy;
protected ResultType resultType; protected ResultType resultType;
protected QueryProperty orderProperty; protected QueryProperty orderProperty;
public static enum NullHandlingOnOrder {
NULLS_FIRST, NULLS_LAST
}
protected NullHandlingOnOrder nullHandlingOnOrder;
protected AbstractQuery() { protected AbstractQuery() {
parameter = this; parameter = this;
} }
...@@ -72,6 +83,13 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa ...@@ -72,6 +83,13 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa
this.orderProperty = property; this.orderProperty = property;
return (T) this; return (T) this;
} }
@SuppressWarnings("unchecked")
public T orderBy(QueryProperty property, NullHandlingOnOrder nullHandlingOnOrder) {
orderBy(property);
this.nullHandlingOnOrder = nullHandlingOnOrder;
return (T) this;
}
public T asc() { public T asc() {
return direction(Direction.ASCENDING); return direction(Direction.ASCENDING);
...@@ -86,8 +104,9 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa ...@@ -86,8 +104,9 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa
if (orderProperty==null) { if (orderProperty==null) {
throw new ActivitiIllegalArgumentException("You should call any of the orderBy methods first before specifying a direction"); throw new ActivitiIllegalArgumentException("You should call any of the orderBy methods first before specifying a direction");
} }
addOrder(orderProperty.getName(), direction.getName()); addOrder(orderProperty.getName(), direction.getName(), nullHandlingOnOrder);
orderProperty = null; orderProperty = null;
nullHandlingOnOrder = null;
return (T) this; return (T) this;
} }
...@@ -164,13 +183,55 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa ...@@ -164,13 +183,55 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa
return null; return null;
} }
protected void addOrder(String column, String sortOrder) { protected void addOrder(String column, String sortOrder, NullHandlingOnOrder nullHandlingOnOrder) {
if (orderBy==null) {
if (orderBy==null) {
orderBy = ""; orderBy = "";
} else { } else {
orderBy = orderBy+", "; orderBy = orderBy+", ";
} }
orderBy = orderBy+column+" "+sortOrder;
String defaultOrderByClause = column + " "+sortOrder;
if (nullHandlingOnOrder != null) {
if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_FIRST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)) {
orderBy = orderBy + defaultOrderByClause + " NULLS FIRST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "isnull(" + column +") desc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 1 else 0 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
} else if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_LAST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)) {
orderBy = orderBy + column + " "+sortOrder + " NULLS LAST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "order by isnull(" + column +") asc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 0 else 1 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
}
} else {
orderBy = orderBy + defaultOrderByClause;
}
} }
public String getOrderBy() { public String getOrderBy() {
...@@ -180,4 +241,13 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa ...@@ -180,4 +241,13 @@ public abstract class AbstractQuery<T extends Query<?,?>, U> extends ListQueryPa
return orderBy; return orderBy;
} }
} }
public String getDatabaseType() {
return databaseType;
}
public void setDatabaseType(String databaseType) {
this.databaseType = databaseType;
}
} }
...@@ -12,14 +12,26 @@ ...@@ -12,14 +12,26 @@
*/ */
package org.activiti.engine.impl; package org.activiti.engine.impl;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.interceptor.CommandExecutor; import org.activiti.engine.impl.interceptor.CommandExecutor;
/** /**
* @author Tom Baeyens * @author Tom Baeyens
* @author Joram Barrez
*/ */
public class ServiceImpl { public class ServiceImpl {
protected ProcessEngineConfigurationImpl processEngineConfiguration;
public ServiceImpl() {
}
public ServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
this.processEngineConfiguration = processEngineConfiguration;
}
protected CommandExecutor commandExecutor; protected CommandExecutor commandExecutor;
......
...@@ -37,6 +37,7 @@ import org.activiti.engine.task.TaskQuery; ...@@ -37,6 +37,7 @@ import org.activiti.engine.task.TaskQuery;
public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> implements TaskQuery { public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> implements TaskQuery {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
protected String taskId; protected String taskId;
protected String name; protected String name;
protected String nameLike; protected String nameLike;
...@@ -87,7 +88,7 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im ...@@ -87,7 +88,7 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im
protected boolean bothCandidateAndAssigned = false; protected boolean bothCandidateAndAssigned = false;
protected boolean orActive; protected boolean orActive;
protected TaskQueryImpl orQueryObject; protected TaskQueryImpl orQueryObject;
public TaskQueryImpl() { public TaskQueryImpl() {
} }
...@@ -98,7 +99,12 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im ...@@ -98,7 +99,12 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im
public TaskQueryImpl(CommandExecutor commandExecutor) { public TaskQueryImpl(CommandExecutor commandExecutor) {
super(commandExecutor); super(commandExecutor);
} }
public TaskQueryImpl(CommandExecutor commandExecutor, String databaseType) {
super(commandExecutor);
this.databaseType = databaseType;
}
public TaskQueryImpl taskId(String taskId) { public TaskQueryImpl taskId(String taskId) {
if (taskId == null) { if (taskId == null) {
throw new ActivitiIllegalArgumentException("Task id is null"); throw new ActivitiIllegalArgumentException("Task id is null");
...@@ -908,6 +914,15 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im ...@@ -908,6 +914,15 @@ public class TaskQueryImpl extends AbstractVariableQueryImpl<TaskQuery, Task> im
return orderBy(TaskQueryProperty.DUE_DATE); return orderBy(TaskQueryProperty.DUE_DATE);
} }
public TaskQuery orderByDueDateNullsFirst() {
return orderBy(TaskQueryProperty.DUE_DATE, NullHandlingOnOrder.NULLS_FIRST);
}
@Override
public TaskQuery orderByDueDateNullsLast() {
return orderBy(TaskQueryProperty.DUE_DATE, NullHandlingOnOrder.NULLS_LAST);
}
@Override @Override
public TaskQuery orderByTenantId() { public TaskQuery orderByTenantId() {
return orderBy(TaskQueryProperty.TENANT_ID); return orderBy(TaskQueryProperty.TENANT_ID);
......
...@@ -22,6 +22,7 @@ import java.util.Map; ...@@ -22,6 +22,7 @@ import java.util.Map;
import org.activiti.engine.ActivitiIllegalArgumentException; import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.TaskService; import org.activiti.engine.TaskService;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.cmd.AddCommentCmd; import org.activiti.engine.impl.cmd.AddCommentCmd;
import org.activiti.engine.impl.cmd.AddIdentityLinkCmd; import org.activiti.engine.impl.cmd.AddIdentityLinkCmd;
import org.activiti.engine.impl.cmd.ClaimTaskCmd; import org.activiti.engine.impl.cmd.ClaimTaskCmd;
...@@ -71,6 +72,14 @@ import org.activiti.engine.task.TaskQuery; ...@@ -71,6 +72,14 @@ import org.activiti.engine.task.TaskQuery;
* @author Joram Barrez * @author Joram Barrez
*/ */
public class TaskServiceImpl extends ServiceImpl implements TaskService { public class TaskServiceImpl extends ServiceImpl implements TaskService {
public TaskServiceImpl() {
}
public TaskServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
super(processEngineConfiguration);
}
public Task newTask() { public Task newTask() {
return newTask(null); return newTask(null);
...@@ -195,7 +204,7 @@ public class TaskServiceImpl extends ServiceImpl implements TaskService { ...@@ -195,7 +204,7 @@ public class TaskServiceImpl extends ServiceImpl implements TaskService {
} }
public TaskQuery createTaskQuery() { public TaskQuery createTaskQuery() {
return new TaskQueryImpl(commandExecutor); return new TaskQueryImpl(commandExecutor, processEngineConfiguration.getDatabaseType());
} }
public NativeTaskQuery createNativeTaskQuery() { public NativeTaskQuery createNativeTaskQuery() {
......
...@@ -248,7 +248,7 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig ...@@ -248,7 +248,7 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
protected RuntimeService runtimeService = new RuntimeServiceImpl(); protected RuntimeService runtimeService = new RuntimeServiceImpl();
protected HistoryService historyService = new HistoryServiceImpl(); protected HistoryService historyService = new HistoryServiceImpl();
protected IdentityService identityService = new IdentityServiceImpl(); protected IdentityService identityService = new IdentityServiceImpl();
protected TaskService taskService = new TaskServiceImpl(); protected TaskService taskService = new TaskServiceImpl(this);
protected FormService formService = new FormServiceImpl(); protected FormService formService = new FormServiceImpl();
protected ManagementService managementService = new ManagementServiceImpl(); protected ManagementService managementService = new ManagementServiceImpl();
...@@ -591,34 +591,41 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig ...@@ -591,34 +591,41 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
} }
protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings(); protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
public static final String DATABASE_TYPE_H2 = "h2";
public static final String DATABASE_TYPE_MYSQL = "mysql";
public static final String DATABASE_TYPE_ORACLE = "oracle";
public static final String DATABASE_TYPE_POSTGRES = "postgres";
public static final String DATABASE_TYPE_MSSQL = "mssql";
public static final String DATABASE_TYPE_DB2 = "db2";
protected static Properties getDefaultDatabaseTypeMappings() { protected static Properties getDefaultDatabaseTypeMappings() {
Properties databaseTypeMappings = new Properties(); Properties databaseTypeMappings = new Properties();
databaseTypeMappings.setProperty("H2","h2"); databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
databaseTypeMappings.setProperty("MySQL","mysql"); databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
databaseTypeMappings.setProperty("Oracle","oracle"); databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
databaseTypeMappings.setProperty("PostgreSQL","postgres"); databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
databaseTypeMappings.setProperty("Microsoft SQL Server","mssql"); databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
databaseTypeMappings.setProperty("DB2","db2"); databaseTypeMappings.setProperty(DATABASE_TYPE_DB2,DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2","db2"); databaseTypeMappings.setProperty(DATABASE_TYPE_DB2,DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT","db2"); databaseTypeMappings.setProperty("DB2/NT",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT64","db2"); databaseTypeMappings.setProperty("DB2/NT64",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDP","db2"); databaseTypeMappings.setProperty("DB2 UDP",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX","db2"); databaseTypeMappings.setProperty("DB2/LINUX",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX390","db2"); databaseTypeMappings.setProperty("DB2/LINUX390",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXX8664","db2"); databaseTypeMappings.setProperty("DB2/LINUXX8664",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXZ64","db2"); databaseTypeMappings.setProperty("DB2/LINUXZ64",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/400 SQL","db2"); databaseTypeMappings.setProperty("DB2/400 SQL",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/6000","db2"); databaseTypeMappings.setProperty("DB2/6000",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB iSeries","db2"); databaseTypeMappings.setProperty("DB2 UDB iSeries",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/AIX64","db2"); databaseTypeMappings.setProperty("DB2/AIX64",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HPUX","db2"); databaseTypeMappings.setProperty("DB2/HPUX",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HP64","db2"); databaseTypeMappings.setProperty("DB2/HP64",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN","db2"); databaseTypeMappings.setProperty("DB2/SUN",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN64","db2"); databaseTypeMappings.setProperty("DB2/SUN64",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/PTX","db2"); databaseTypeMappings.setProperty("DB2/PTX",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/2","db2"); databaseTypeMappings.setProperty("DB2/2",DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB AS400", "db2"); databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
return databaseTypeMappings; return databaseTypeMappings;
} }
......
...@@ -453,9 +453,24 @@ public interface TaskQuery extends Query<TaskQuery, Task>{ ...@@ -453,9 +453,24 @@ public interface TaskQuery extends Query<TaskQuery, Task>{
/** Order by execution id (needs to be followed by {@link #asc()} or {@link #desc()}). */ /** Order by execution id (needs to be followed by {@link #asc()} or {@link #desc()}). */
TaskQuery orderByExecutionId(); TaskQuery orderByExecutionId();
/** Order by due date (needs to be followed by {@link #asc()} or {@link #desc()}). */ /**
* Order by due date (needs to be followed by {@link #asc()} or {@link #desc()}).
* This will use the default handling of null values of the used database.
*/
TaskQuery orderByDueDate(); TaskQuery orderByDueDate();
/**
* Order by due date (needs to be followed by {@link #asc()} or {@link #desc()}).
* If any of the tasks have null for the due date, these will be first in the result.
*/
TaskQuery orderByDueDateNullsFirst();
/**
* Order by due date (needs to be followed by {@link #asc()} or {@link #desc()}).
* If any of the tasks have null for the due date, these will be last in the result.
*/
TaskQuery orderByDueDateNullsLast();
/** Order by tenant id (needs to be followed by {@link #asc()} or {@link #desc()}). */ /** Order by tenant id (needs to be followed by {@link #asc()} or {@link #desc()}). */
TaskQuery orderByTenantId(); TaskQuery orderByTenantId();
} }
/* 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.test.api.task;
import java.text.SimpleDateFormat;
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;
import java.util.Map;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.impl.history.HistoryLevel;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.VariableInstanceEntity;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.activiti.engine.test.Deployment;
/**
* @author Joram Barrez
* @author Frederik Heremans
* @author Falko Menge
*/
public class TaskDueDateTest extends PluggableActivitiTestCase {
@Override
protected void tearDown() throws Exception {
for (Task task : taskService.createTaskQuery().list()) {
taskService.deleteTask(task.getId(), true);
}
super.tearDown();
}
/**
* See http://jira.codehaus.org/browse/ACT-2089
*/
public void testDueDateSortingWithNulls() {
Date now = processEngineConfiguration.getClock().getCurrentTime();
// 4 tasks with a due date
Task task0 = createTask("task0", new Date(now.getTime() + (4L * 7L * 24L * 60L * 60L * 1000L))); // 4 weeks in future
Task task1 = createTask("task1", new Date(now.getTime() + (2 * 24L * 60L * 60L * 1000L))); // 2 days in future
Task task2 = createTask("task2", new Date(now.getTime() + (7L * 24L * 60L * 60L * 1000L))); // 1 week in future
Task task3 = createTask("task3", new Date(now.getTime() + (24L * 60L * 60L * 1000L))); // 1 day in future
// 2 tasks without a due date
createTask("task4", null);
createTask("task5", null);
assertEquals(6, taskService.createTaskQuery().count());
// Sorting on due date asc should put the nulls at the end
List<Task> tasks = taskService.createTaskQuery().orderByDueDateNullsLast().asc().list();
for (int i=0; i<4; i++) {
assertNotNull(tasks.get(i).getDueDate());
}
assertEquals("task3", tasks.get(0).getName());
assertEquals("task1", tasks.get(1).getName());
assertEquals("task2", tasks.get(2).getName());
assertEquals("task0", tasks.get(3).getName());
assertNull(tasks.get(4).getDueDate());
assertNull(tasks.get(5).getDueDate());
// The same, but now desc
tasks = taskService.createTaskQuery().orderByDueDateNullsLast().desc().list();
for (int i=0; i<4; i++) {
assertNotNull(tasks.get(i).getDueDate());
}
assertEquals("task0", tasks.get(0).getName());
assertEquals("task2", tasks.get(1).getName());
assertEquals("task1", tasks.get(2).getName());
assertEquals("task3", tasks.get(3).getName());
assertNull(tasks.get(4).getDueDate());
assertNull(tasks.get(5).getDueDate());
// The same but now nulls first
tasks = taskService.createTaskQuery().orderByDueDateNullsFirst().asc().list();
assertNull(tasks.get(0).getDueDate());
assertNull(tasks.get(1).getDueDate());
assertEquals("task3", tasks.get(2).getName());
assertEquals("task1", tasks.get(3).getName());
assertEquals("task2", tasks.get(4).getName());
assertEquals("task0", tasks.get(5).getName());
// And now desc
tasks = taskService.createTaskQuery().orderByDueDateNullsFirst().desc().list();
assertNull(tasks.get(0).getDueDate());
assertNull(tasks.get(1).getDueDate());
assertEquals("task0", tasks.get(2).getName());
assertEquals("task2", tasks.get(3).getName());
assertEquals("task1", tasks.get(4).getName());
assertEquals("task3", tasks.get(5).getName());
}
private Task createTask(String name, Date dueDate) {
Task task = taskService.newTask();
task.setName(name);
task.setDueDate(dueDate);
taskService.saveTask(task);
return task;
}
}
...@@ -2251,6 +2251,14 @@ public class TaskQueryTest extends PluggableActivitiTestCase { ...@@ -2251,6 +2251,14 @@ public class TaskQueryTest extends PluggableActivitiTestCase {
.deploymentId("invalid").count()); .deploymentId("invalid").count());
} }
private Task createTask(String name, Date dueDate) {
Task task = taskService.newTask();
task.setName(name);
task.setDueDate(dueDate);
taskService.saveTask(task);
return task;
}
/** /**
* Generates some test tasks. - 6 tasks where kermit is a candidate - 1 tasks * 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 * where gonzo is assignee - 2 tasks assigned to management group - 2 tasks
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
package org.activiti.engine.test.api.task; package org.activiti.engine.test.api.task;
import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -87,4 +88,44 @@ public class TaskVariablesTest extends PluggableActivitiTestCase { ...@@ -87,4 +88,44 @@ public class TaskVariablesTest extends PluggableActivitiTestCase {
assertEquals(expectedVariables, runtimeService.getVariables(processInstanceId)); assertEquals(expectedVariables, runtimeService.getVariables(processInstanceId));
assertEquals(expectedVariables, runtimeService.getVariablesLocal(processInstanceId)); assertEquals(expectedVariables, runtimeService.getVariablesLocal(processInstanceId));
} }
public void testSerializableTaskVariable() {
Task task = taskService.newTask();
task.setName("MyTask");
taskService.saveTask(task);
// Set variable
Map<String, Object> vars = new HashMap<String, Object>();
MyVariable myVariable = new MyVariable("Hello world");
vars.put("theVar", myVariable);
taskService.setVariables(task.getId(), vars);
// Fetch variable
MyVariable variable = (MyVariable) taskService.getVariable(task.getId(), "theVar");
assertEquals("Hello world", variable.getValue());
// Cleanup
taskService.deleteTask(task.getId(), true);
}
public static class MyVariable implements Serializable {
private String value;
public MyVariable(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册