TSK-1188 Enable combo filter for tasks

This commit is contained in:
Jörg Heffner 2020-04-09 09:35:43 +02:00
parent f8945ecfa7
commit 101072d3e9
11 changed files with 279 additions and 11 deletions

View File

@ -611,6 +611,23 @@ public interface TaskQuery extends BaseQuery<TaskSummary, TaskQueryColumnName> {
*/
TaskQuery orderByClassificationName(SortDirection sortDirection);
/**
* Add your wildcard search value for pattern matching to your query. It will be compared in SQL
* with the LIKE operator. You may use a wildcard like % to specify the pattern.
*
* @param wildcardSearchValue the wildcard search value
* @return the query
*/
TaskQuery wildcardSearchValueLike(String wildcardSearchValue);
/**
* Add the values of the wildcard search fields for exact matching to your query.
*
* @param wildcardSearchFields the values of your wildcard search fields
* @return the query
*/
TaskQuery wildcardSearchFieldsIn(WildcardSearchFields... wildcardSearchFields);
/**
* This method sorts the query result according to the completed timestamp.
*

View File

@ -0,0 +1,51 @@
package pro.taskana.task.api;
import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public enum WildcardSearchFields {
NAME("NAME"),
DESCRIPTION("DESCRIPTION"),
CUSTOM_1("CUSTOM_1"),
CUSTOM_2("CUSTOM_2"),
CUSTOM_3("CUSTOM_3"),
CUSTOM_4("CUSTOM_4"),
CUSTOM_5("CUSTOM_5"),
CUSTOM_6("CUSTOM_6"),
CUSTOM_7("CUSTOM_7"),
CUSTOM_8("CUSTOM_8"),
CUSTOM_9("CUSTOM_9"),
CUSTOM_10("CUSTOM_10"),
CUSTOM_11("CUSTOM_11"),
CUSTOM_12("CUSTOM_12"),
CUSTOM_13("CUSTOM_13"),
CUSTOM_14("CUSTOM_14"),
CUSTOM_15("CUSTOM_15"),
CUSTOM_16("CUSTOM_16");
WildcardSearchFields(String name) {
this.name = name;
}
private static final Map<String, WildcardSearchFields> STRING_TO_ENUM =
Arrays.stream(values())
.collect(
Collectors.toMap(
WildcardSearchFields::toString,
e -> e,
(first, second) -> first,
() -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER)));
private String name;
public static WildcardSearchFields fromString(String name) {
return STRING_TO_ENUM.get(name);
}
@Override
public String toString() {
return name;
}
}

View File

@ -24,6 +24,7 @@ import pro.taskana.task.api.ObjectReferenceQuery;
import pro.taskana.task.api.TaskQuery;
import pro.taskana.task.api.TaskQueryColumnName;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.WildcardSearchFields;
import pro.taskana.task.api.models.TaskSummary;
import pro.taskana.task.internal.models.TaskSummaryImpl;
import pro.taskana.workbasket.api.WorkbasketPermission;
@ -147,6 +148,8 @@ public class TaskQueryImpl implements TaskQuery {
private TimeInterval[] dueIn;
private List<String> orderBy;
private List<String> orderColumns;
private WildcardSearchFields[] wildcardSearchFieldsIn;
private String wildcardSearchValueLike;
private boolean useDistinctKeyword = false;
private boolean joinWithAttachments = false;
@ -737,6 +740,18 @@ public class TaskQueryImpl implements TaskQuery {
: addOrderCriteria("c.NAME", sortDirection);
}
@Override
public TaskQuery wildcardSearchValueLike(String wildcardSearchValue) {
this.wildcardSearchValueLike = wildcardSearchValue;
return this;
}
@Override
public TaskQuery wildcardSearchFieldsIn(WildcardSearchFields... wildcardSearchFields) {
this.wildcardSearchFieldsIn = wildcardSearchFields;
return this;
}
@Override
public TaskQuery orderByCompleted(SortDirection sortDirection) {
return addOrderCriteria("COMPLETED", sortDirection);
@ -1588,6 +1603,14 @@ public class TaskQueryImpl implements TaskQuery {
addAttachmentClassificationNameToSelectClauseForOrdering;
}
public WildcardSearchFields[] getWildcardSearchFieldIn() {
return wildcardSearchFieldsIn;
}
public String getWildcardSearchValueLike() {
return wildcardSearchValueLike;
}
private String getDatabaseId() {
return this.taskanaEngine.getSqlSession().getConfiguration().getDatabaseId();
}
@ -1663,7 +1686,8 @@ public class TaskQueryImpl implements TaskQuery {
.getWorkbasketService()
.checkAuthorization(workbasketId, WorkbasketPermission.OPEN, WorkbasketPermission.READ);
} catch (WorkbasketNotFoundException e) {
LOGGER.warn("The workbasket with the ID '" + workbasketId + "' does not exist.", e);
LOGGER.warn(
String.format("The workbasket with the ID ' %s ' does not exist.", workbasketId), e);
}
}
@ -1680,11 +1704,9 @@ public class TaskQueryImpl implements TaskQuery {
WorkbasketPermission.READ);
} catch (WorkbasketNotFoundException e) {
LOGGER.warn(
"The workbasket with the KEY '"
+ keyDomain.getKey()
+ "' and DOMAIN '"
+ keyDomain.getDomain()
+ "'does not exist.",
String.format(
"The workbasket with the KEY ' %s ' and DOMAIN ' %s ' does not exist.",
keyDomain.getKey(), keyDomain.getDomain()),
e);
}
}
@ -1899,6 +1921,10 @@ public class TaskQueryImpl implements TaskQuery {
+ addClassificationNameToSelectClauseForOrdering
+ ", addAttachmentClassificationNameToSelectClauseForOrdering="
+ addAttachmentClassificationNameToSelectClauseForOrdering
+ ", wildcardSearchFieldsIn="
+ wildcardSearchFieldsIn
+ ", wildcardSearchValueLike="
+ wildcardSearchValueLike
+ "]";
}
}

View File

@ -133,6 +133,7 @@ public interface TaskQueryMapper {
+ "<if test='attachmentReferenceIn != null'>AND a.REF_VALUE IN(<foreach item='item' collection='attachmentReferenceIn' separator=',' >#{item}</foreach>)</if> "
+ "<if test='attachmentReferenceLike != null'>AND (<foreach item='item' collection='attachmentReferenceLike' separator=' OR '>UPPER(a.REF_VALUE) LIKE #{item}</foreach>)</if> "
+ "<if test='attachmentReceivedIn !=null'> AND ( <foreach item='item' collection='attachmentReceivedIn' separator=' OR ' > ( <if test='item.begin!=null'> a.RECEIVED &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND </if><if test='item.end!=null'> a.RECEIVED &lt;=#{item.end} </if>)</foreach>)</if> "
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldsIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldsIn' separator=' OR '>t.${item} LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ "</where>"
+ "<if test='!orderBy.isEmpty()'>ORDER BY <foreach item='item' collection='orderBy' separator=',' >${item}</foreach></if> "
+ "</script>")
@ -319,6 +320,7 @@ public interface TaskQueryMapper {
+ "<if test='attachmentReferenceIn != null'>AND a.REF_VALUE IN(<foreach item='item' collection='attachmentReferenceIn' separator=',' >#{item}</foreach>)</if> "
+ "<if test='attachmentReferenceLike != null'>AND (<foreach item='item' collection='attachmentReferenceLike' separator=' OR '>UPPER(a.REF_VALUE) LIKE #{item}</foreach>)</if> "
+ "<if test='attachmentReceivedIn !=null'> AND ( <foreach item='item' collection='attachmentReceivedIn' separator=' OR ' > ( <if test='item.begin!=null'> a.RECEIVED &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND </if><if test='item.end!=null'> a.RECEIVED &lt;=#{item.end} </if>)</foreach>)</if> "
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldsIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldsIn' separator=' OR '>t.${item} LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ "</where> "
+ "), Y (ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ " CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, "

View File

@ -642,6 +642,8 @@ class QueryTasksAccTest extends AbstractAccTest {
void testQueryForOrderByWorkbasketIdDesc() {
List<TaskSummary> results =
taskService.createTaskQuery().orderByWorkbasketId(DESCENDING).list();
.orderByCustomAttribute("4", DESCENDING)
assertEquals("99rty", results.get(0).getCustomAttribute("4"));
assertThat(results)
.hasSizeGreaterThan(2)

View File

@ -0,0 +1,72 @@
package acceptance.task;
import static org.assertj.core.api.Assertions.assertThat;
import acceptance.AbstractAccTest;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.common.api.BaseQuery.SortDirection;
import pro.taskana.security.JaasExtension;
import pro.taskana.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.WildcardSearchFields;
import pro.taskana.task.api.models.TaskSummary;
@ExtendWith(JaasExtension.class)
public class QueryTasksByWildcardSearchAccTest extends AbstractAccTest {
@WithAccessId(
userName = "teamlead_1",
groupNames = {"group_1", "group_2"})
@Test
void should_ReturnAllTasksByWildcardSearch_For_ProvidedSearchValue() {
TaskService taskService = taskanaEngine.getTaskService();
WildcardSearchFields[] wildcards = {
WildcardSearchFields.CUSTOM_3, WildcardSearchFields.CUSTOM_4, WildcardSearchFields.NAME
};
List<TaskSummary> foundTasks =
taskService
.createTaskQuery()
.wildcardSearchFieldsIn(wildcards)
.wildcardSearchValueLike("%99%")
.orderByName(SortDirection.ASCENDING)
.list();
assertThat(foundTasks).hasSize(4);
}
@WithAccessId(
userName = "teamlead_1",
groupNames = {"group_1", "group_2"})
@Test
void should_ReturnAllTasks_When_ProvidingNoSearchFieldsOrValue() {
TaskService taskService = taskanaEngine.getTaskService();
WildcardSearchFields[] wildcards = {
WildcardSearchFields.CUSTOM_3, WildcardSearchFields.CUSTOM_4, WildcardSearchFields.NAME
};
List<TaskSummary> foundTasks =
taskService
.createTaskQuery()
.wildcardSearchFieldsIn(wildcards)
.orderByName(SortDirection.ASCENDING)
.list();
assertThat(foundTasks).hasSize(83);
foundTasks =
taskService
.createTaskQuery()
.wildcardSearchValueLike("%99%")
.orderByName(SortDirection.ASCENDING)
.list();
assertThat(foundTasks).hasSize(83);
}
}

View File

@ -8,8 +8,8 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000005', 'ETI:0000000
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000006', 'ETI:000000000000000000000000000000000006', RELATIVE_DATE(-5) , null , null , RELATIVE_DATE(0) , RELATIVE_DATE(-5) , RELATIVE_DATE(0) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000006' , 'DOC_0000000000000000006' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000007', 'ETI:000000000000000000000000000000000007', RELATIVE_DATE(-6) , null , null , RELATIVE_DATE(0) , RELATIVE_DATE(-6) , RELATIVE_DATE(0) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000007' , 'DOC_0000000000000000007' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , 'NONE' , null , null , null , 'ffg' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000008', 'ETI:000000000000000000000000000000000008', RELATIVE_DATE(-6) , null , null , RELATIVE_DATE(0) , RELATIVE_DATE(-6) , RELATIVE_DATE(0) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000008' , 'DOC_0000000000000000008' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', 'ETI:000000000000000000000000000000000009', RELATIVE_DATE(-7) , null , null , RELATIVE_DATE(0) , RELATIVE_DATE(-7) , RELATIVE_DATE(-4) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', 'ETI:000000000000000000000000000000000010', RELATIVE_DATE(-8) , null , null , RELATIVE_DATE(-2) , RELATIVE_DATE(-8) , RELATIVE_DATE(-2) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , 'rty' , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', 'ETI:000000000000000000000000000000000009', RELATIVE_DATE(-7) , null , null , RELATIVE_DATE(0) , RELATIVE_DATE(-7) , RELATIVE_DATE(-4) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , 'rty99' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', 'ETI:000000000000000000000000000000000010', RELATIVE_DATE(-8) , null , null , RELATIVE_DATE(-2) , RELATIVE_DATE(-8) , RELATIVE_DATE(-2) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , '99rty' , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000011', 'ETI:000000000000000000000000000000000011', RELATIVE_DATE(-8) , null , null , RELATIVE_DATE(-2) , RELATIVE_DATE(-8) , RELATIVE_DATE(2) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000011' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000012', 'ETI:000000000000000000000000000000000012', RELATIVE_DATE(-8) , null , null , RELATIVE_DATE(-2) , RELATIVE_DATE(-7) , RELATIVE_DATE(10) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000012' , 'DOC_0000000000000000012' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000013', 'ETI:000000000000000000000000000000000013', RELATIVE_DATE(-8) , null , null , RELATIVE_DATE(-2) , RELATIVE_DATE(-7) , RELATIVE_DATE(10) , 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000013' , 'DOC_0000000000000000013' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , 'rty' , null , null , null , null , null , null , null , null , 'abc' , null , null );

View File

@ -8,8 +8,8 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000005', 'ETI:0000000
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000006', 'ETI:000000000000000000000000000000000006', '2018-01-29 15:55:06', null , '2018-01-30 16:55:06', '2018-01-29 15:55:06', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000006' , 'DOC_0000000000000000006' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000007', 'ETI:000000000000000000000000000000000007', '2018-01-29 15:55:07', null , null , '2018-01-29 15:55:07', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000007' , 'DOC_0000000000000000007' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , 'NONE' , null , null , null , 'ffg' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000008', 'ETI:000000000000000000000000000000000008', '2018-01-29 15:55:08', null , null , '2018-01-29 15:55:08', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000008' , 'DOC_0000000000000000008' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', 'ETI:000000000000000000000000000000000009', '2018-01-29 15:55:09', null , null , '2018-01-29 15:55:09', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', 'ETI:000000000000000000000000000000000010', '2018-01-29 15:55:10', null , null , '2018-01-29 15:55:10', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , 'rty' , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', 'ETI:000000000000000000000000000000000009', '2018-01-29 15:55:09', null , null , '2018-01-29 15:55:09', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , 'rty99' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', 'ETI:000000000000000000000000000000000010', '2018-01-29 15:55:10', null , null , '2018-01-29 15:55:10', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , '99rty' , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000011', 'ETI:000000000000000000000000000000000011', '2018-01-29 15:55:11', null , null , '2018-01-29 15:55:11', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000011' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000012', 'ETI:000000000000000000000000000000000012', '2018-01-29 15:55:12', null , null , '2018-01-29 15:55:12', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000012' , 'DOC_0000000000000000012' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000013', 'ETI:000000000000000000000000000000000013', '2018-01-29 15:55:13', null , null , '2018-01-29 15:55:13', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000013' , 'DOC_0000000000000000013' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , 'NONE' , null , null , null , null , null , 'rty' , null , null , null , null , null , null , null , null , 'abc' , null , null );

View File

@ -3,6 +3,8 @@ package pro.taskana.rest;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.hateoas.config.EnableHypermediaSupport;
@ -35,6 +37,7 @@ import pro.taskana.rest.resource.TaskSummaryResourceAssembler;
import pro.taskana.task.api.TaskQuery;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.WildcardSearchFields;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidOwnerException;
import pro.taskana.task.api.exceptions.InvalidStateException;
@ -77,6 +80,8 @@ public class TaskController extends AbstractPagingController {
private static final String PLANNED_UNTIL = "planned-until";
private static final String PLANNED_FROM = "planned-from";
private static final String EXTERNAL_ID = "external-id";
private static final String WILDCARD_SEARCH_VALUE = "wildcard-search-value";
private static final String WILDCARD_SEARCH_FIELDS = "wildcard-search-fields";
private static final String SORT_BY = "sort-by";
private static final String SORT_DIRECTION = "order";
@ -295,6 +300,7 @@ public class TaskController extends AbstractPagingController {
params.remove(PRIORITY);
}
if (params.containsKey(STATE)) {
TaskState[] states = extractStates(params);
taskQuery.stateIn(states);
params.remove(STATE);
@ -382,6 +388,18 @@ public class TaskController extends AbstractPagingController {
updateTaskQueryWithIndefiniteTimeInterval(taskQuery, params, DUE_TO, timeInterval);
}
if (params.containsKey(WILDCARD_SEARCH_FIELDS) && params.containsKey(WILDCARD_SEARCH_VALUE)) {
String[] requestedWildcardSearchFields =
extractCommaSeparatedFields(params.get(WILDCARD_SEARCH_FIELDS));
taskQuery.wildcardSearchFieldsIn(createWildcardSearchFields(requestedWildcardSearchFields));
taskQuery.wildcardSearchValueLike(params.getFirst(WILDCARD_SEARCH_VALUE));
params.remove(WILDCARD_SEARCH_FIELDS);
params.remove(WILDCARD_SEARCH_VALUE);
}
if (params.containsKey(EXTERNAL_ID)) {
String[] externalIds = extractCommaSeparatedFields(params.get(EXTERNAL_ID));
taskQuery.externalIdIn(externalIds);
@ -395,6 +413,14 @@ public class TaskController extends AbstractPagingController {
return taskQuery;
}
private WildcardSearchFields[] createWildcardSearchFields(String[] wildcardFields) {
return Stream.of(wildcardFields)
.map(WildcardSearchFields::fromString)
.filter(Objects::nonNull)
.toArray(WildcardSearchFields[]::new);
}
private void updateTaskQueryWithWorkbasketKey(
TaskQuery taskQuery, MultiValueMap<String, String> params) throws InvalidArgumentException {
@ -442,6 +468,22 @@ public class TaskController extends AbstractPagingController {
+ PLANNED_UNTIL
+ "\"");
}
if (params.containsKey(WILDCARD_SEARCH_FIELDS) && !params.containsKey(WILDCARD_SEARCH_VALUE)
|| !params.containsKey(WILDCARD_SEARCH_FIELDS)
&& params.containsKey(WILDCARD_SEARCH_VALUE)) {
throw new IllegalArgumentException(
"It is prohibited to use the params "
+ "\""
+ WILDCARD_SEARCH_FIELDS
+ "\""
+ " or "
+ "\""
+ WILDCARD_SEARCH_VALUE
+ "\""
+ " without one another. If one is provided you must provide the other one as well");
}
}
private void updateTaskQueryWithIndefiniteTimeInterval(

View File

@ -210,6 +210,53 @@ class TaskControllerIntTest {
assertThat(response.getBody().getContent()).hasSize(6);
}
@Test
void should_ReturnAllTasksByWildcardSearch_For_ProvidedSearchValue() {
ResponseEntity<TaskSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?wildcard-search-value=%99%"
+ "&wildcard-search-fields=NAME,custom_3,CuStOM_4",
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeadersAdmin()),
ParameterizedTypeReference.forType(TaskSummaryListResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getContent()).hasSize(4);
}
@Test
void should_ThrowException_When_ProvidingInvalidWildcardSearchParameters() {
ThrowingCallable httpCall =
() -> {
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS) + "?wildcard-search-value=%rt%",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class));
};
assertThatThrownBy(httpCall)
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("400")
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);
ThrowingCallable httpCall2 =
() -> {
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS)
+ "?wildcard-search-fields=NAME,CUSTOM_3,CUSTOM_4",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(TaskSummaryListResource.class));
};
assertThatThrownBy(httpCall2)
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("400")
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
void testGetAllTasksByWorkbasketIdWithinSingleDueTimeInterval() {

View File

@ -122,7 +122,16 @@ The list generated in the response can be filtered using following parameters in
name | priority | state | classification.key | workbasket-id | {workbasket-key , domain} | +
owner | por.company | por.system | por.instance | por.type | por.value +
planned | planned-from | planned-until | due | due-from | due-until | +
external-id
external-id | wildcard-search-value | wildcard-search-fields
When filtering a wildcard search you must provide both paremters +
(wildcard-search-value and wildcard-search-fields). Valid wildcard-search-fields are: +
-name +
-description +
-custom_1 to custom_16 +
These fields are case insensitive! +
If it is sufficient to filter the list with a single time interval, use the parameters +
planned-from/due-from and planned-until/due-until. +