提交 2ee7f6ce 编写于 作者: X Xu Huisheng

ACT-1789, historicTaskinstanceQuery support candidate

上级 cac7df97
......@@ -15,6 +15,7 @@ package org.activiti.engine.history;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import org.activiti.engine.query.Query;
import org.activiti.engine.task.Task;
......@@ -144,10 +145,26 @@ public interface HistoricTaskInstanceQuery extends Query<HistoricTaskInstanceQu
*/
HistoricTaskInstanceQuery taskOwnerLike(String taskOwnerLike);
/** Only select historic tasks for which the given user is a candidate. */
HistoricTaskInstanceQuery taskCandidateUser(String candidateUser);
/** Only select historic task for which there exist an {@link HistoricIdentityLink} with the given user, including tasks
* which have been assigned to the given user (assignee) or owned by the given user (owner). */
HistoricTaskInstanceQuery taskInvolvedUser(String involvedUser);
/** Only select historic tasks for which users in the given group are candidates. */
HistoricTaskInstanceQuery taskCandidateGroup(String candidateGroup);
/**
* Only select tasks for which the 'candidateGroup' is one of the given groups.
*
* @throws ActivitiIllegalArgumentException
* When query is executed and {@link #taskCandidateGroup(String)} or
* {@link #taskCandidateUser(String)} has been executed on the query instance.
* When passed group list is empty or <code>null</code>.
*/
HistoricTaskInstanceQuery taskCandidateGroupIn(List<String> candidateGroups);
/**
* Only select historic task instances with the given priority.
*/
......
......@@ -13,11 +13,14 @@
package org.activiti.engine.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
......@@ -53,6 +56,9 @@ public class HistoricTaskInstanceQueryImpl extends AbstractVariableQueryImpl<His
protected String taskAssigneeLike;
protected String taskDefinitionKey;
protected String taskDefinitionKeyLike;
protected String candidateUser;
protected String candidateGroup;
private List<String> candidateGroups;
protected String involvedUser;
protected Integer taskPriority;
protected Integer taskMinPriority;
......@@ -392,6 +398,53 @@ public class HistoricTaskInstanceQueryImpl extends AbstractVariableQueryImpl<His
return this;
}
public HistoricTaskInstanceQuery taskCandidateUser(String candidateUser) {
if (candidateUser == null) {
throw new ActivitiIllegalArgumentException("Candidate user is null");
}
if (candidateGroup != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateUser and candidateGroup");
}
if (candidateGroups != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateUser and candidateGroupIn");
}
this.candidateUser = candidateUser;
return this;
}
public HistoricTaskInstanceQuery taskCandidateGroup(String candidateGroup) {
if (candidateGroup == null) {
throw new ActivitiIllegalArgumentException("Candidate group is null");
}
if (candidateUser != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateGroup and candidateUser");
}
if (candidateGroups != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateGroup and candidateGroupIn");
}
this.candidateGroup = candidateGroup;
return this;
}
public HistoricTaskInstanceQuery taskCandidateGroupIn(List<String> candidateGroups) {
if(candidateGroups == null) {
throw new ActivitiIllegalArgumentException("Candidate group list is null");
}
if(candidateGroups.size()== 0) {
throw new ActivitiIllegalArgumentException("Candidate group list is empty");
}
if (candidateUser != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateGroupIn and candidateUser");
}
if (candidateGroup != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateGroupIn and candidateGroup");
}
this.candidateGroups = candidateGroups;
return this;
}
@Override
public HistoricTaskInstanceQuery taskInvolvedUser(String involvedUser) {
this.involvedUser = involvedUser;
......@@ -503,7 +556,34 @@ public class HistoricTaskInstanceQueryImpl extends AbstractVariableQueryImpl<His
}
return specialOrderBy;
}
public List<String> getCandidateGroups() {
if (candidateGroup!=null) {
List<String> candidateGroupList = new java.util.ArrayList<String>(1);
candidateGroupList.add(candidateGroup);
return candidateGroupList;
} else if (candidateUser != null) {
return getGroupsForCandidateUser(candidateUser);
} else if(candidateGroups != null) {
return candidateGroups;
}
return null;
}
protected List<String> getGroupsForCandidateUser(String candidateUser) {
// TODO: Discuss about removing this feature? Or document it properly and maybe recommend to not use it
// and explain alternatives
List<Group> groups = Context
.getCommandContext()
.getGroupIdentityManager()
.findGroupsByUser(candidateUser);
List<String> groupIds = new ArrayList<String>();
for (Group group : groups) {
groupIds.add(group.getId());
}
return groupIds;
}
// getters and setters //////////////////////////////////////////////////////
public String getProcessInstanceId() {
......@@ -566,6 +646,12 @@ public class HistoricTaskInstanceQueryImpl extends AbstractVariableQueryImpl<His
public Date getCreationDate() {
return creationDate;
}
public String getCandidateUser() {
return candidateUser;
}
public String getCandidateGroup() {
return candidateGroup;
}
public String getInvolvedUser() {
return involvedUser;
}
......
......@@ -240,6 +240,9 @@
</sql>
<sql id="commonSelectHistoricTaskInstancesByQueryCriteriaSql">
<if test="candidateUser != null || candidateGroups != null">
inner join ${prefix}ACT_HI_IDENTITYLINK HI on HI.TASK_ID_ = RES.ID_
</if>
<if test="processFinished || processUnfinished || processInstanceBusinessKey != null || processInstanceBusinessKeyLike != null">
inner join ${prefix}ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_
</if>
......@@ -377,6 +380,26 @@
<if test="completedAfterDate != null">
and RES.END_TIME_ &gt; #{completedAfterDate}
</if>
<if test="candidateUser != null || candidateGroups != null">
and RES.ASSIGNEE_ is null
and HI.TYPE_ = 'candidate'
and
(
<if test="candidateUser != null">
HI.USER_ID_ = #{candidateUser}
</if>
<if test="candidateUser != null &amp;&amp; candidateGroups != null &amp;&amp; candidateGroups.size() &gt; 0">
or
</if>
<if test="candidateGroups != null &amp;&amp; candidateGroups.size() &gt; 0">
HI.GROUP_ID_ IN
<foreach item="group" index="index" collection="candidateGroups"
open="(" separator="," close=")">
#{group}
</foreach>
</if>
)
</if>
<if test="involvedUser != null">
and (
exists(select LINK.USER_ID_ from ${prefix}ACT_HI_IDENTITYLINK LINK where USER_ID_ = #{involvedUser} and LINK.TASK_ID_ = RES.ID_)
......@@ -459,23 +482,23 @@
</sql>
<select id="selectHistoricTaskInstanceByNativeQuery" parameterType="java.util.Map" resultMap="historicTaskInstanceResultMap">
<if test="resultType == 'LIST_PAGE'">
${limitBefore}
<if test="resultType == 'LIST_PAGE'">
${limitBefore}
</if>
${sql}
<if test="resultType == 'LIST_PAGE'">
${limitAfter}
${limitAfter}
</if>
</select>
<select id="selectHistoricTaskInstanceByNativeQuery_mssql_or_db2" parameterType="java.util.Map" resultMap="historicTaskInstanceResultMap">
<if test="resultType == 'LIST_PAGE'">
${limitBeforeNativeQuery}
</if>
${sql}
<if test="resultType == 'LIST_PAGE'">
${limitAfter}
</if>
${limitBeforeNativeQuery}
</if>
${sql}
<if test="resultType == 'LIST_PAGE'">
${limitAfter}
</if>
</select>
<select id="selectHistoricTaskInstanceCountByNativeQuery" parameterType="java.util.Map" resultType="long">
......
......@@ -143,6 +143,23 @@ public class HistoricTaskAndVariablesQueryTest extends PluggableActivitiTestCase
}
}
@Deployment
public void testCandidate() {
if(processEngineConfiguration.getHistoryLevel().isAtLeast(HistoryLevel.ACTIVITY)) {
List<HistoricTaskInstance> tasks = null;
tasks = historyService.createHistoricTaskInstanceQuery().taskCandidateUser("kermit").list();
assertEquals(2, tasks.size());
tasks = historyService.createHistoricTaskInstanceQuery().taskCandidateGroup("management").list();
assertEquals(0, tasks.size());
List<String> groups = new ArrayList<String>();
groups.add("management");
groups.add("accountancy");
tasks = historyService.createHistoricTaskInstanceQuery().taskCandidateGroupIn(groups).list();
assertEquals(0, tasks.size());
}
}
public void testQueryWithPagingAndVariables() {
List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
.includeProcessVariables()
......
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="oneTaskProcess" name="The One Task Process">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theProcessTask" />
<userTask id="theProcessTask" name="my process task" activiti:candidateUsers="kermit" activiti:candidateGroups="management" />
<sequenceFlow id="flow2" sourceRef="theProcessTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册