TSK-1837: Add custom-int-x-from and custom-int-x-to to rest

This commit is contained in:
ryzheboka 2022-07-19 13:49:40 +02:00 committed by Mustapha Zorgati
parent 803b4b20a2
commit 70c64dd66e
14 changed files with 1757 additions and 1320 deletions

View File

@ -8,8 +8,8 @@ import java.util.Objects;
*/
public class IntInterval {
private Integer begin;
private Integer end;
private final Integer begin;
private final Integer end;
public IntInterval(Integer begin, Integer end) {
this.begin = begin;
@ -28,18 +28,10 @@ public class IntInterval {
return begin;
}
public void setBegin(Integer begin) {
this.begin = begin;
}
public Integer getEnd() {
return end;
}
public void setEnd(Integer end) {
this.end = end;
}
@Override
public int hashCode() {
return Objects.hash(begin, end);

View File

@ -9,8 +9,8 @@ import java.util.Objects;
*/
public class TimeInterval {
private Instant begin;
private Instant end;
private final Instant begin;
private final Instant end;
public TimeInterval(Instant begin, Instant end) {
this.begin = begin;
@ -38,18 +38,10 @@ public class TimeInterval {
return begin;
}
public void setBegin(Instant begin) {
this.begin = begin;
}
public Instant getEnd() {
return end;
}
public void setEnd(Instant end) {
this.end = end;
}
@Override
public int hashCode() {
return Objects.hash(begin, end);

View File

@ -24,7 +24,7 @@ public class SqlProviderUtil {
.append("</when>")
.append("<otherwise>0=1</otherwise>")
.append("</choose>");
if (column.contains("t.CUSTOM_") && !column.contains("INT")) {
if (column.matches("t.CUSTOM_\\d+")) {
sb.append("<if test='" + collection + "ContainsNull'> OR " + column + " IS NULL </if>");
}
return sb.append(")</if> ");
@ -47,7 +47,7 @@ public class SqlProviderUtil {
.append("</when>")
.append("<otherwise>1=1</otherwise>")
.append("</choose>");
if (column.contains("t.CUSTOM_") && !column.contains("INT")) {
if (column.matches("t.CUSTOM_\\d+")) {
sb.append("<if test='" + collection + "ContainsNull'> AND " + column + " IS NOT NULL </if>");
sb.append("<if test='!" + collection + "ContainsNull'> OR " + column + " IS NULL </if>");
}

View File

@ -30,8 +30,6 @@ import pro.taskana.common.api.KeyDomain;
import pro.taskana.common.api.TimeInterval;
import pro.taskana.common.api.security.CurrentUserContext;
import pro.taskana.common.internal.util.Pair;
import pro.taskana.common.internal.util.Quadruple;
import pro.taskana.common.internal.util.Triplet;
import pro.taskana.task.api.CallbackState;
import pro.taskana.task.api.TaskCustomField;
import pro.taskana.task.api.TaskCustomIntField;
@ -3301,240 +3299,186 @@ class TaskQueryImplAccTest {
@WithAccessId(user = "user-1-1")
@TestFactory
Stream<DynamicTest> should_ThrowException_When_QueryingForCustomIntWithinInvalidInterval() {
List<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> testCases =
List<Pair<TaskCustomIntField, IntInterval[]>> testCases =
List.of(
Quadruple.of(
"CustomInt1",
TaskCustomIntField.CUSTOM_INT_1,
new IntInterval(4, 1),
new IntInterval(-10, -8)),
Quadruple.of(
"CustomInt2",
Pair.of(TaskCustomIntField.CUSTOM_INT_1, new IntInterval[] {new IntInterval(4, 1)}),
// Only first interval invalid
Pair.of(
TaskCustomIntField.CUSTOM_INT_2,
new IntInterval(null, null),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt3",
new IntInterval[] {new IntInterval(null, null), new IntInterval(0, null)}),
// Only second interval invalid
Pair.of(
TaskCustomIntField.CUSTOM_INT_3,
new IntInterval(-1, 5),
new IntInterval(null, null)),
Quadruple.of(
"CustomInt4",
new IntInterval[] {new IntInterval(-1, 5), new IntInterval(null, null)}),
// Both intervals invalid
Pair.of(
TaskCustomIntField.CUSTOM_INT_4,
new IntInterval(0, -5),
new IntInterval(-2, -10)),
Quadruple.of(
"CustomInt5",
new IntInterval[] {new IntInterval(0, -5), new IntInterval(-2, -10)}),
// One interval invalid
Pair.of(
TaskCustomIntField.CUSTOM_INT_5,
new IntInterval(null, null),
new IntInterval(0, -50)),
Quadruple.of(
"CustomInt6",
TaskCustomIntField.CUSTOM_INT_6,
new IntInterval(4, 9),
new IntInterval(0, -5)),
Quadruple.of(
"CustomInt7",
new IntInterval[] {new IntInterval(null, null)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_6, new IntInterval[] {new IntInterval(0, -5)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_7,
new IntInterval(null, null),
new IntInterval(null, null)),
Quadruple.of(
"CustomInt8",
new IntInterval[] {new IntInterval(null, null), new IntInterval(null, null)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_8,
new IntInterval(123, 122),
new IntInterval(1, 0)));
new IntInterval[] {new IntInterval(123, 122)}));
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
q -> {
ThrowingConsumer<Pair<TaskCustomIntField, IntInterval[]>> test =
p -> {
ThrowingCallable result =
() ->
taskService
.createTaskQuery()
.workbasketIdIn(wb.getId())
.customIntAttributeWithin(q.getSecond(), q.getThird(), q.getFourth())
.customIntAttributeWithin(p.getLeft(), p.getRight())
.list();
assertThatThrownBy(result)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("IntInterval");
};
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
}
@WithAccessId(user = "user-1-1")
@TestFactory
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntIn() {
List<Triplet<String, Integer, TaskCustomIntField>> testCases =
List<Pair<TaskCustomIntField, Integer>> testCases =
List.of(
Triplet.of("CustomInt1", 1, TaskCustomIntField.CUSTOM_INT_1),
Triplet.of("CustomInt2", 2, TaskCustomIntField.CUSTOM_INT_2),
Triplet.of("CustomInt3", 3, TaskCustomIntField.CUSTOM_INT_3),
Triplet.of("CustomInt4", 4, TaskCustomIntField.CUSTOM_INT_4),
Triplet.of("CustomInt5", 5, TaskCustomIntField.CUSTOM_INT_5),
Triplet.of("CustomInt6", 6, TaskCustomIntField.CUSTOM_INT_6),
Triplet.of("CustomInt7", 7, TaskCustomIntField.CUSTOM_INT_7),
Triplet.of("CustomInt8", 8, TaskCustomIntField.CUSTOM_INT_8));
Pair.of(TaskCustomIntField.CUSTOM_INT_1, 1),
Pair.of(TaskCustomIntField.CUSTOM_INT_2, 2),
Pair.of(TaskCustomIntField.CUSTOM_INT_3, 3),
Pair.of(TaskCustomIntField.CUSTOM_INT_4, 4),
Pair.of(TaskCustomIntField.CUSTOM_INT_5, 5),
Pair.of(TaskCustomIntField.CUSTOM_INT_6, 6),
Pair.of(TaskCustomIntField.CUSTOM_INT_7, 7),
Pair.of(TaskCustomIntField.CUSTOM_INT_8, 8));
ThrowingConsumer<Triplet<String, Integer, TaskCustomIntField>> test =
t -> {
ThrowingConsumer<Pair<TaskCustomIntField, Integer>> test =
p -> {
List<TaskSummary> result =
taskService
.createTaskQuery()
.workbasketIdIn(wb.getId())
.customIntAttributeIn(t.getRight(), t.getMiddle())
.customIntAttributeIn(p.getLeft(), p.getRight())
.list();
assertThat(result).containsExactly(taskSummary1);
};
return DynamicTest.stream(testCases.iterator(), Triplet::getLeft, test);
return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
}
@WithAccessId(user = "user-1-1")
@TestFactory
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntNotIn() {
List<Triplet<String, Integer, TaskCustomIntField>> testCases =
List<Pair<TaskCustomIntField, Integer>> testCases =
List.of(
Triplet.of("CustomInt1", 1, TaskCustomIntField.CUSTOM_INT_1),
Triplet.of("CustomInt2", 2, TaskCustomIntField.CUSTOM_INT_2),
Triplet.of("CustomInt3", 3, TaskCustomIntField.CUSTOM_INT_3),
Triplet.of("CustomInt4", 4, TaskCustomIntField.CUSTOM_INT_4),
Triplet.of("CustomInt5", 5, TaskCustomIntField.CUSTOM_INT_5),
Triplet.of("CustomInt6", 6, TaskCustomIntField.CUSTOM_INT_6),
Triplet.of("CustomInt7", 7, TaskCustomIntField.CUSTOM_INT_7),
Triplet.of("CustomInt8", 8, TaskCustomIntField.CUSTOM_INT_8));
Pair.of(TaskCustomIntField.CUSTOM_INT_1, 1),
Pair.of(TaskCustomIntField.CUSTOM_INT_2, 2),
Pair.of(TaskCustomIntField.CUSTOM_INT_3, 3),
Pair.of(TaskCustomIntField.CUSTOM_INT_4, 4),
Pair.of(TaskCustomIntField.CUSTOM_INT_5, 5),
Pair.of(TaskCustomIntField.CUSTOM_INT_6, 6),
Pair.of(TaskCustomIntField.CUSTOM_INT_7, 7),
Pair.of(TaskCustomIntField.CUSTOM_INT_8, 8));
ThrowingConsumer<Triplet<String, Integer, TaskCustomIntField>> test =
t -> {
ThrowingConsumer<Pair<TaskCustomIntField, Integer>> test =
p -> {
List<TaskSummary> result =
taskService
.createTaskQuery()
.workbasketIdIn(wb.getId())
.customIntAttributeNotIn(t.getRight(), t.getMiddle())
.customIntAttributeNotIn(p.getLeft(), p.getRight())
.list();
assertThat(result).containsExactlyInAnyOrder(taskSummary2);
};
return DynamicTest.stream(testCases.iterator(), Triplet::getLeft, test);
return DynamicTest.stream(testCases.iterator(), t -> t.getLeft().name(), test);
}
@WithAccessId(user = "user-1-1")
@TestFactory
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntWithin() {
List<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> testCases =
List<Pair<TaskCustomIntField, IntInterval[]>> testCases =
List.of(
Quadruple.of(
"CustomInt1",
TaskCustomIntField.CUSTOM_INT_1,
new IntInterval(1, 1),
new IntInterval(-10, -8)),
Quadruple.of(
"CustomInt2",
TaskCustomIntField.CUSTOM_INT_2,
new IntInterval(0, null),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt3",
Pair.of(TaskCustomIntField.CUSTOM_INT_1, new IntInterval[] {new IntInterval(1, 1)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_2, new IntInterval[] {new IntInterval(0, null)}),
// The value lies within both specified intervals
Pair.of(
TaskCustomIntField.CUSTOM_INT_3,
new IntInterval(-1, 5),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt4",
new IntInterval[] {new IntInterval(-1, 5), new IntInterval(0, null)}),
// The value lies only within the second interval
Pair.of(
TaskCustomIntField.CUSTOM_INT_4,
new IntInterval(0, 1),
new IntInterval(-2, 22)),
Quadruple.of(
"CustomInt5",
new IntInterval[] {new IntInterval(0, 1), new IntInterval(-2, 22)}),
// The value lies only within the first interval
Pair.of(
TaskCustomIntField.CUSTOM_INT_5,
new IntInterval(3, 9),
new IntInterval(-1000, -50)),
Quadruple.of(
"CustomInt6",
TaskCustomIntField.CUSTOM_INT_6,
new IntInterval(4, 9),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt7",
TaskCustomIntField.CUSTOM_INT_7,
new IntInterval(4, 9),
new IntInterval(11, 22)),
Quadruple.of(
"CustomInt8",
TaskCustomIntField.CUSTOM_INT_8,
new IntInterval(123, 124),
new IntInterval(1, null)));
new IntInterval[] {new IntInterval(3, 9), new IntInterval(-1000, -50)}),
Pair.of(TaskCustomIntField.CUSTOM_INT_6, new IntInterval[] {new IntInterval(4, 9)}),
Pair.of(TaskCustomIntField.CUSTOM_INT_7, new IntInterval[] {new IntInterval(4, 9)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_8, new IntInterval[] {new IntInterval(1, null)}));
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
q -> {
ThrowingConsumer<Pair<TaskCustomIntField, IntInterval[]>> test =
p -> {
List<TaskSummary> result =
taskService
.createTaskQuery()
.workbasketIdIn(wb.getId())
.customIntAttributeWithin(q.getSecond(), q.getThird(), q.getFourth())
.customIntAttributeWithin(p.getLeft(), p.getRight())
.list();
assertThat(result).containsExactly(taskSummary1);
};
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
}
@WithAccessId(user = "user-1-1")
@TestFactory
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntNotWithin() {
List<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> testCases =
List<Pair<TaskCustomIntField, IntInterval[]>> testCases =
List.of(
Quadruple.of(
"CustomInt1",
Pair.of(
TaskCustomIntField.CUSTOM_INT_1,
new IntInterval(1, 1),
new IntInterval(0, 10)),
Quadruple.of(
"CustomInt2",
new IntInterval[] {new IntInterval(1, 1), new IntInterval(0, 10)}),
// Test specifying same interval multiple times
Pair.of(
TaskCustomIntField.CUSTOM_INT_2,
new IntInterval(0, null),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt3",
TaskCustomIntField.CUSTOM_INT_3,
new IntInterval(-1, 5),
new IntInterval(2, 25)),
Quadruple.of(
"CustomInt4",
new IntInterval[] {new IntInterval(0, null), new IntInterval(0, null)}),
// Test single interval
Pair.of(
TaskCustomIntField.CUSTOM_INT_3, new IntInterval[] {new IntInterval(-1, 5)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_4,
new IntInterval(-3, 9),
new IntInterval(-2, 22)),
Quadruple.of(
"CustomInt5",
TaskCustomIntField.CUSTOM_INT_5,
new IntInterval(3, 9),
new IntInterval(-1000, 1000)),
Quadruple.of(
"CustomInt6",
TaskCustomIntField.CUSTOM_INT_6,
new IntInterval(4, 9),
new IntInterval(0, null)),
Quadruple.of(
"CustomInt7",
TaskCustomIntField.CUSTOM_INT_7,
new IntInterval(4, 9),
new IntInterval(null, 22)),
Quadruple.of(
"CustomInt8",
TaskCustomIntField.CUSTOM_INT_8,
new IntInterval(0, 124),
new IntInterval(1, null)));
new IntInterval[] {
new IntInterval(-3, 9),
}),
Pair.of(TaskCustomIntField.CUSTOM_INT_5, new IntInterval[] {new IntInterval(3, 9)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_6, new IntInterval[] {new IntInterval(0, null)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_7, new IntInterval[] {new IntInterval(7, null)}),
Pair.of(
TaskCustomIntField.CUSTOM_INT_8, new IntInterval[] {new IntInterval(0, 124)}));
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
q -> {
ThrowingConsumer<Pair<TaskCustomIntField, IntInterval[]>> test =
p -> {
List<TaskSummary> result =
taskService
.createTaskQuery()
.workbasketIdIn(wb.getId())
.customIntAttributeNotWithin(q.getSecond(), q.getThird(), q.getFourth())
.customIntAttributeNotWithin(p.getLeft(), p.getRight())
.list();
assertThat(result).containsExactly(taskSummary2);
};
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
return DynamicTest.stream(testCases.iterator(), p -> p.getLeft().name(), test);
}
}

View File

@ -1620,6 +1620,7 @@ public interface TaskQuery extends BaseQuery<TaskSummary, TaskQueryColumnName> {
*/
TaskQuery sorValueLike(String... valueLike);
// endregion
// region customAttributes
/**
@ -1715,10 +1716,8 @@ public interface TaskQuery extends BaseQuery<TaskSummary, TaskQueryColumnName> {
* @param customIntField identifies which {@linkplain TaskCustomIntField} is affected
* @param values identify the intervals that are used for filtering
* @return the query
* @throws InvalidArgumentException if searchArguments are not given
*/
TaskQuery customIntAttributeWithin(TaskCustomIntField customIntField, IntInterval... values)
throws InvalidArgumentException;
TaskQuery customIntAttributeWithin(TaskCustomIntField customIntField, IntInterval... values);
/**
* Exclude the values of specified {@linkplain TaskCustomIntField} inside the given range from
@ -1745,6 +1744,7 @@ public interface TaskQuery extends BaseQuery<TaskSummary, TaskQueryColumnName> {
*/
TaskQuery orderByCustomIntAttribute(
TaskCustomIntField customIntField, SortDirection sortDirection);
// endregion
// region callbackState

View File

@ -6,14 +6,15 @@ import static pro.taskana.common.internal.util.SqlProviderUtil.DB2_WITH_UR;
import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_SCRIPT_TAG;
import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_WHERE_TAG;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereIn;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereInInterval;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereLike;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotIn;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotInInterval;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotLike;
import java.util.Arrays;
import java.util.stream.Collectors;
import pro.taskana.common.internal.util.SqlProviderUtil;
import pro.taskana.task.api.TaskCommentQueryColumnName;
public class TaskCommentQuerySqlProvider {
@ -94,10 +95,10 @@ public class TaskCommentQuerySqlProvider {
whereNotIn("creatorNotIn", "tc.CREATOR", sb);
whereLike("creatorLike", "tc.CREATOR", sb);
whereNotLike("creatorNotLike", "tc.CREATOR", sb);
SqlProviderUtil.whereInInterval("createdIn", "tc.CREATED", sb);
SqlProviderUtil.whereNotInInterval("createdNotIn", "tc.CREATED", sb);
SqlProviderUtil.whereInInterval("modifiedIn", "tc.MODIFIED", sb);
SqlProviderUtil.whereNotInInterval("modifiedNotIn", "tc.MODIFIED", sb);
whereInInterval("createdIn", "tc.CREATED", sb);
whereNotInInterval("createdNotIn", "tc.CREATED", sb);
whereInInterval("modifiedIn", "tc.MODIFIED", sb);
whereNotInInterval("modifiedNotIn", "tc.MODIFIED", sb);
return sb.toString();
}

View File

@ -287,8 +287,6 @@ public class TaskQueryImpl implements TaskQuery {
private boolean custom16NotInContainsNull;
private String[] custom16Like;
private String[] custom16NotLike;
// endregion
// region customIntAttributes
private Integer[] customInt1In;
private Integer[] customInt1NotIn;
private IntInterval[] customInt1Within;
@ -1688,35 +1686,30 @@ public class TaskQueryImpl implements TaskQuery {
throw new InvalidArgumentException(
"At least one Integer has to be provided as a search parameter");
}
List<Integer> conditionList = new ArrayList<>(Arrays.asList(values));
boolean containsNull = conditionList.contains(null);
if (containsNull) {
conditionList.remove(null);
}
switch (customIntField) {
case CUSTOM_INT_1:
this.customInt1NotIn = conditionList.toArray(new Integer[0]);
this.customInt1NotIn = values;
break;
case CUSTOM_INT_2:
this.customInt2NotIn = conditionList.toArray(new Integer[0]);
this.customInt2NotIn = values;
break;
case CUSTOM_INT_3:
this.customInt3NotIn = conditionList.toArray(new Integer[0]);
this.customInt3NotIn = values;
break;
case CUSTOM_INT_4:
this.customInt4NotIn = conditionList.toArray(new Integer[0]);
this.customInt4NotIn = values;
break;
case CUSTOM_INT_5:
this.customInt5NotIn = conditionList.toArray(new Integer[0]);
this.customInt5NotIn = values;
break;
case CUSTOM_INT_6:
this.customInt6NotIn = conditionList.toArray(new Integer[0]);
this.customInt6NotIn = values;
break;
case CUSTOM_INT_7:
this.customInt7NotIn = conditionList.toArray(new Integer[0]);
this.customInt7NotIn = values;
break;
case CUSTOM_INT_8:
this.customInt8NotIn = conditionList.toArray(new Integer[0]);
this.customInt8NotIn = values;
break;
default:
throw new SystemException("Unknown custom int field '" + customIntField + "'");
@ -1732,36 +1725,30 @@ public class TaskQueryImpl implements TaskQuery {
"At least one Integer has to be provided as a search parameter");
}
List<Integer> conditionList = new ArrayList<>(Arrays.asList(values));
boolean containsNull = conditionList.contains(null);
if (containsNull) {
conditionList.remove(null);
}
switch (customIntField) {
case CUSTOM_INT_1:
this.customInt1In = conditionList.toArray(new Integer[0]);
this.customInt1In = values;
break;
case CUSTOM_INT_2:
this.customInt2In = conditionList.toArray(new Integer[0]);
this.customInt2In = values;
break;
case CUSTOM_INT_3:
this.customInt3In = conditionList.toArray(new Integer[0]);
this.customInt3In = values;
break;
case CUSTOM_INT_4:
this.customInt4In = conditionList.toArray(new Integer[0]);
this.customInt4In = values;
break;
case CUSTOM_INT_5:
this.customInt5In = conditionList.toArray(new Integer[0]);
this.customInt5In = values;
break;
case CUSTOM_INT_6:
this.customInt6In = conditionList.toArray(new Integer[0]);
this.customInt6In = values;
break;
case CUSTOM_INT_7:
this.customInt7In = conditionList.toArray(new Integer[0]);
this.customInt7In = values;
break;
case CUSTOM_INT_8:
this.customInt8In = conditionList.toArray(new Integer[0]);
this.customInt8In = values;
break;
default:
throw new SystemException("Unknown custom int attribute '" + customIntField + "'");

View File

@ -8,14 +8,15 @@ import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_WHERE_TAG
import static pro.taskana.common.internal.util.SqlProviderUtil.whereCustomIntStatements;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereCustomStatements;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereIn;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereInInterval;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereLike;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotIn;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotInInterval;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotLike;
import java.util.Arrays;
import java.util.stream.Collectors;
import pro.taskana.common.internal.util.SqlProviderUtil;
import pro.taskana.task.api.TaskQueryColumnName;
public class TaskQuerySqlProvider {
@ -283,21 +284,23 @@ public class TaskQuerySqlProvider {
private static String db2selectFields() {
// needs to be the same order as the commonSelectFields (TaskQueryColumnValue)
return "ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, RECEIVED, DUE, NAME,"
+ " CREATOR, DESCRIPTION, NOTE, PRIORITY, MANUAL_PRIORITY, STATE,"
+ " CLASSIFICATION_CATEGORY, TCLASSIFICATION_KEY, CLASSIFICATION_ID, WORKBASKET_ID,"
+ " WORKBASKET_KEY, DOMAIN, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER,"
+ " POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ,"
+ " IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6,"
+ " CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13,"
+ " CUSTOM_14, CUSTOM_15, CUSTOM_16, CUSTOM_INT_1, CUSTOM_INT_2, CUSTOM_INT_3,"
+ " CUSTOM_INT_4, CUSTOM_INT_5, CUSTOM_INT_6, CUSTOM_INT_7, CUSTOM_INT_8 <if"
+ " test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME</if><if"
+ " test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">,"
+ " ACNAME</if><if test=\"addAttachmentColumnsToSelectClauseForOrdering\">,"
+ " ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, ARECEIVED</if><if"
+ " test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME</if><if"
+ " test=\"joinWithUserInfo\">, ULONG_NAME </if>";
return "ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, RECEIVED, DUE, NAME, "
+ "CREATOR, DESCRIPTION, NOTE, PRIORITY, MANUAL_PRIORITY, STATE, CLASSIFICATION_CATEGORY, "
+ "TCLASSIFICATION_KEY, CLASSIFICATION_ID, "
+ "WORKBASKET_ID, WORKBASKET_KEY, DOMAIN, "
+ "BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, "
+ "POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, "
+ "CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, "
+ "CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16, "
+ "CUSTOM_INT_1, CUSTOM_INT_2, CUSTOM_INT_3, CUSTOM_INT_4, CUSTOM_INT_5, "
+ "CUSTOM_INT_6, CUSTOM_INT_7, CUSTOM_INT_8"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ACNAME</if>"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, ARECEIVED"
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME</if>"
+ "<if test=\"joinWithUserInfo\">, ULONG_NAME </if>";
}
private static String checkForAuthorization() {
@ -421,22 +424,22 @@ public class TaskQuerySqlProvider {
whereLike("noteLike", "t.NOTE", sb);
whereNotLike("noteNotLike", "t.NOTE", sb);
SqlProviderUtil.whereInInterval("attachmentReceivedWithin", "a.RECEIVED", sb);
SqlProviderUtil.whereNotInInterval("attachmentReceivedNotWithin", "a.RECEIVED", sb);
SqlProviderUtil.whereInInterval("claimedWithin", "t.CLAIMED", sb);
SqlProviderUtil.whereNotInInterval("claimedNotWithin", "t.CLAIMED", sb);
SqlProviderUtil.whereInInterval("completedWithin", "t.COMPLETED", sb);
SqlProviderUtil.whereNotInInterval("completedNotWithin", "t.COMPLETED", sb);
SqlProviderUtil.whereInInterval("createdWithin", "t.CREATED", sb);
SqlProviderUtil.whereNotInInterval("createdNotWithin", "t.CREATED", sb);
SqlProviderUtil.whereInInterval("dueWithin", "t.DUE", sb);
SqlProviderUtil.whereNotInInterval("dueNotWithin", "t.DUE", sb);
SqlProviderUtil.whereInInterval("modifiedWithin", "t.MODIFIED", sb);
SqlProviderUtil.whereNotInInterval("modifiedNotWithin", "t.MODIFIED", sb);
SqlProviderUtil.whereInInterval("plannedWithin", "t.PLANNED", sb);
SqlProviderUtil.whereNotInInterval("plannedNotWithin", "t.PLANNED", sb);
SqlProviderUtil.whereInInterval("receivedWithin", "t.RECEIVED", sb);
SqlProviderUtil.whereNotInInterval("receivedNotWithin", "t.RECEIVED", sb);
whereInInterval("attachmentReceivedWithin", "a.RECEIVED", sb);
whereNotInInterval("attachmentReceivedNotWithin", "a.RECEIVED", sb);
whereInInterval("claimedWithin", "t.CLAIMED", sb);
whereNotInInterval("claimedNotWithin", "t.CLAIMED", sb);
whereInInterval("completedWithin", "t.COMPLETED", sb);
whereNotInInterval("completedNotWithin", "t.COMPLETED", sb);
whereInInterval("createdWithin", "t.CREATED", sb);
whereNotInInterval("createdNotWithin", "t.CREATED", sb);
whereInInterval("dueWithin", "t.DUE", sb);
whereNotInInterval("dueNotWithin", "t.DUE", sb);
whereInInterval("modifiedWithin", "t.MODIFIED", sb);
whereNotInInterval("modifiedNotWithin", "t.MODIFIED", sb);
whereInInterval("plannedWithin", "t.PLANNED", sb);
whereNotInInterval("plannedNotWithin", "t.PLANNED", sb);
whereInInterval("receivedWithin", "t.RECEIVED", sb);
whereNotInInterval("receivedNotWithin", "t.RECEIVED", sb);
whereLike("ownerLongNameLike", "u.LONG_NAME", sb);
whereNotLike("ownerLongNameNotLike", "u.LONG_NAME", sb);

View File

@ -534,7 +534,7 @@ class QueryTasksWithSortingAccTest extends AbstractAccTest {
.hasSizeGreaterThan(2)
.extracting(t -> t.getCustomIntField(s))
.filteredOn(Objects::nonNull)
.isSortedAccordingTo(Integer::compareTo);
.isSorted();
});
}
@ -552,7 +552,7 @@ class QueryTasksWithSortingAccTest extends AbstractAccTest {
taskanaEngine
.getTaskService()
.createTaskQuery()
.orderByCustomIntAttribute(s, ASCENDING)
.orderByCustomIntAttribute(s, DESCENDING)
.list();
assertThat(results)

View File

@ -78,6 +78,8 @@ public class TaskController {
* @title Get a list of all Tasks
* @param request the HTTP request
* @param filterParameter the filter parameters
* @param filterCustomFields the filter parameters regarding TaskCustomFields
* @param filterCustomIntFields the filter parameters regarding TaskCustomIntFields
* @param sortParameter the sort parameters
* @param pagingParameter the paging parameters
* @return the Tasks with the given filter, sort and paging options.
@ -87,16 +89,22 @@ public class TaskController {
public ResponseEntity<TaskSummaryPagedRepresentationModel> getTasks(
HttpServletRequest request,
TaskQueryFilterParameter filterParameter,
TaskQueryFilterCustomFields filterCustomFields,
TaskQueryFilterCustomIntFields filterCustomIntFields,
TaskQuerySortParameter sortParameter,
QueryPagingParameter<TaskSummary, TaskQuery> pagingParameter) {
QueryParamsValidator.validateParams(
request,
TaskQueryFilterParameter.class,
TaskQueryFilterCustomFields.class,
TaskQueryFilterCustomIntFields.class,
QuerySortParameter.class,
QueryPagingParameter.class);
TaskQuery query = taskService.createTaskQuery();
filterParameter.apply(query);
filterCustomFields.apply(query);
filterCustomIntFields.apply(query);
sortParameter.apply(query);
List<TaskSummary> taskSummaries = pagingParameter.apply(query);
@ -112,8 +120,10 @@ public class TaskController {
* applied.
*
* @title Delete multiple Tasks
* @param filterParameter the filter parameters.
* @return the deleted task summaries.
* @param filterParameter the filter parameters
* @param filterCustomFields the filter parameters regarding TaskCustomFields
* @param filterCustomIntFields the filter parameters regarding TaskCustomIntFields
* @return the deleted task summaries
* @throws InvalidArgumentException TODO: this is never thrown
* @throws NotAuthorizedException if the current user is not authorized to delete the requested
* Tasks.
@ -121,10 +131,14 @@ public class TaskController {
@DeleteMapping(path = RestEndpoints.URL_TASKS)
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<TaskSummaryCollectionRepresentationModel> deleteTasks(
TaskQueryFilterParameter filterParameter)
TaskQueryFilterParameter filterParameter,
TaskQueryFilterCustomFields filterCustomFields,
TaskQueryFilterCustomIntFields filterCustomIntFields)
throws InvalidArgumentException, NotAuthorizedException {
TaskQuery query = taskService.createTaskQuery();
filterParameter.apply(query);
filterCustomFields.apply(query);
filterCustomIntFields.apply(query);
List<TaskSummary> taskSummaries = query.list();
@ -192,6 +206,8 @@ public class TaskController {
* This endpoint selects the first Task returned by the Task Query and claims it.
*
* @param filterParameter the filter parameters
* @param filterCustomFields the filter parameters regarding TaskCustomFields
* @param filterCustomIntFields the filter parameters regarding TaskCustomIntFields
* @param sortParameter the sort parameters
* @return the claimed Task
* @throws InvalidOwnerException if the Task is already claimed by someone else
@ -202,11 +218,16 @@ public class TaskController {
@PostMapping(path = RestEndpoints.URL_TASKS_ID_SELECT_AND_CLAIM)
@Transactional(rollbackFor = Exception.class)
public ResponseEntity<TaskRepresentationModel> selectAndClaimTask(
TaskQueryFilterParameter filterParameter, TaskQuerySortParameter sortParameter)
TaskQueryFilterParameter filterParameter,
TaskQueryFilterCustomFields filterCustomFields,
TaskQueryFilterCustomIntFields filterCustomIntFields,
TaskQuerySortParameter sortParameter)
throws InvalidOwnerException, NotAuthorizedException {
TaskQuery query = taskService.createTaskQuery();
filterParameter.apply(query);
filterCustomFields.apply(query);
filterCustomIntFields.apply(query);
sortParameter.apply(query);
Task selectedAndClaimedTask = taskService.selectAndClaim(query);

View File

@ -0,0 +1,646 @@
package pro.taskana.task.rest;
import static pro.taskana.common.internal.util.CheckedConsumer.wrap;
import static pro.taskana.common.internal.util.Quadruple.of;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_1;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_10;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_11;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_12;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_13;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_14;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_15;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_16;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_2;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_3;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_4;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_5;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_6;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_7;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_8;
import static pro.taskana.task.api.TaskCustomField.CUSTOM_9;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.beans.ConstructorProperties;
import java.util.Optional;
import java.util.stream.Stream;
import pro.taskana.common.internal.util.Pair;
import pro.taskana.common.rest.QueryParameter;
import pro.taskana.task.api.TaskQuery;
public class TaskQueryFilterCustomFields implements QueryParameter<TaskQuery, Void> {
/** Filter by the value of the field custom1 of the Task. This is an exact match. */
@JsonProperty("custom-1")
private final String[] custom1In;
/** Exclude values of the field custom1 of the Task. */
@JsonProperty("custom-1-not")
private final String[] custom1NotIn;
/**
* Filter by the custom1 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-1-like")
private final String[] custom1Like;
/**
* Filter by what the custom1 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-1-not-like")
private final String[] custom1NotLike;
/** Filter by the value of the field custom2 of the Task. This is an exact match. */
@JsonProperty("custom-2")
private final String[] custom2In;
/** Filter out by values of the field custom2 of the Task. This is an exact match. */
@JsonProperty("custom-2-not")
private final String[] custom2NotIn;
/**
* Filter by the custom2 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-2-like")
private final String[] custom2Like;
/**
* Filter by what the custom2 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-2-not-like")
private final String[] custom2NotLike;
/** Filter by the value of the field custom3 of the Task. This is an exact match. */
@JsonProperty("custom-3")
private final String[] custom3In;
/** Filter out by values of the field custom3 of the Task. This is an exact match. */
@JsonProperty("custom-3-not")
private final String[] custom3NotIn;
/**
* Filter by the custom3 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-3-like")
private final String[] custom3Like;
/**
* Filter by what the custom3 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-3-not-like")
private final String[] custom3NotLike;
/** Filter by the value of the field custom4 of the Task. This is an exact match. */
@JsonProperty("custom-4")
private final String[] custom4In;
/** Filter out by values of the field custom4 of the Task. This is an exact match. */
@JsonProperty("custom-4-not")
private final String[] custom4NotIn;
/**
* Filter by the custom4 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-4-like")
private final String[] custom4Like;
/**
* Filter by what the custom4 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-4-not-like")
private final String[] custom4NotLike;
/** Filter by the value of the field custom5 of the Task. This is an exact match. */
@JsonProperty("custom-5")
private final String[] custom5In;
/** Filter out by values of the field custom5 of the Task. This is an exact match. */
@JsonProperty("custom-5-not")
private final String[] custom5NotIn;
/**
* Filter by the custom5 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-5-like")
private final String[] custom5Like;
/**
* Filter by what the custom5 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-5-not-like")
private final String[] custom5NotLike;
/** Filter by the value of the field custom6 of the Task. This is an exact match. */
@JsonProperty("custom-6")
private final String[] custom6In;
/** Filter out by values of the field custom6 of the Task. This is an exact match. */
@JsonProperty("custom-6-not")
private final String[] custom6NotIn;
/**
* Filter by the custom6 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-6-like")
private final String[] custom6Like;
/**
* Filter by what the custom6 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-6-not-like")
private final String[] custom6NotLike;
/** Filter by the value of the field custom7 of the Task. This is an exact match. */
@JsonProperty("custom-7")
private final String[] custom7In;
/** Filter out by values of the field custom7 of the Task. This is an exact match. */
@JsonProperty("custom-7-not")
private final String[] custom7NotIn;
/**
* Filter by the custom7 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-7-like")
private final String[] custom7Like;
/**
* Filter by what the custom7 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-7-not-like")
private final String[] custom7NotLike;
/** Filter by the value of the field custom8 of the Task. This is an exact match. */
@JsonProperty("custom-8")
private final String[] custom8In;
/** Filter out by values of the field custom8 of the Task. This is an exact match. */
@JsonProperty("custom-8-not")
private final String[] custom8NotIn;
/**
* Filter by the custom8 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-8-like")
private final String[] custom8Like;
/**
* Filter by what the custom8 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-8-not-like")
private final String[] custom8NotLike;
/** Filter by the value of the field custom9 of the Task. This is an exact match. */
@JsonProperty("custom-9")
private final String[] custom9In;
/** Filter out by values of the field custom9 of the Task. This is an exact match. */
@JsonProperty("custom-9-not")
private final String[] custom9NotIn;
/**
* Filter by the custom9 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-9-like")
private final String[] custom9Like;
/**
* Filter by what the custom9 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-9-not-like")
private final String[] custom9NotLike;
/** Filter by the value of the field custom10 of the Task. This is an exact match. */
@JsonProperty("custom-10")
private final String[] custom10In;
/** Filter out by values of the field custom10 of the Task. This is an exact match. */
@JsonProperty("custom-10-not")
private final String[] custom10NotIn;
/**
* Filter by the custom10 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-10-like")
private final String[] custom10Like;
/**
* Filter by what the custom10 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-10-not-like")
private final String[] custom10NotLike;
/** Filter by the value of the field custom11 of the Task. This is an exact match. */
@JsonProperty("custom-11")
private final String[] custom11In;
/** Filter out by values of the field custom11 of the Task. This is an exact match. */
@JsonProperty("custom-11-not")
private final String[] custom11NotIn;
/**
* Filter by the custom11 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-11-like")
private final String[] custom11Like;
/**
* Filter by what the custom11 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-11-not-like")
private final String[] custom11NotLike;
/** Filter by the value of the field custom12 of the Task. This is an exact match. */
@JsonProperty("custom-12")
private final String[] custom12In;
/** Filter out by values of the field custom12 of the Task. This is an exact match. */
@JsonProperty("custom-12-not")
private final String[] custom12NotIn;
/**
* Filter by the custom12 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-12-like")
private final String[] custom12Like;
/**
* Filter by what the custom12 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-12-not-like")
private final String[] custom12NotLike;
/** Filter by the value of the field custom13 of the Task. This is an exact match. */
@JsonProperty("custom-13")
private final String[] custom13In;
/** Filter out by values of the field custom13 of the Task. This is an exact match. */
@JsonProperty("custom-13-not")
private final String[] custom13NotIn;
/**
* Filter by the custom13 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-13-like")
private final String[] custom13Like;
/**
* Filter by what the custom13 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-13-not-like")
private final String[] custom13NotLike;
/** Filter by the value of the field custom14 of the Task. This is an exact match. */
@JsonProperty("custom-14")
private final String[] custom14In;
/** Filter out by values of the field custom14 of the Task. This is an exact match. */
@JsonProperty("custom-14-not")
private final String[] custom14NotIn;
/**
* Filter by the custom14 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-14-like")
private final String[] custom14Like;
/**
* Filter by what the custom14 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-14-not-like")
private final String[] custom14NotLike;
/** Filter by the value of the field custom15 of the Task. This is an exact match. */
@JsonProperty("custom-15")
private final String[] custom15In;
/** Filter out by values of the field custom15 of the Task. This is an exact match. */
@JsonProperty("custom-15-not")
private final String[] custom15NotIn;
/**
* Filter by the custom15 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-15-like")
private final String[] custom15Like;
/**
* Filter by what the custom15 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-15-not-like")
private final String[] custom15NotLike;
/** Filter by the value of the field custom16 of the Task. This is an exact match. */
@JsonProperty("custom-16")
private final String[] custom16In;
/** Filter out by values of the field custom16 of the Task. This is an exact match. */
@JsonProperty("custom-16-not")
private final String[] custom16NotIn;
/**
* Filter by the custom16 field of the Task. This results in a substring search (% is appended to
* the front and end of the requested value). Further SQL "LIKE" wildcard characters will be
* resolved correctly.
*/
@JsonProperty("custom-16-like")
private final String[] custom16Like;
/**
* Filter by what the custom16 field of the Task shouldn't be. This results in a substring search
* (% is appended to the front and end of the requested value). Further SQL "LIKE" wildcard
* characters will be resolved correctly.
*/
@JsonProperty("custom-16-not-like")
private final String[] custom16NotLike;
@ConstructorProperties({
"custom-1",
"custom-1-not",
"custom-1-like",
"custom-1-not-like",
"custom-2",
"custom-2-not",
"custom-2-like",
"custom-2-not-like",
"custom-3",
"custom-3-not",
"custom-3-like",
"custom-3-not-like",
"custom-4",
"custom-4-not",
"custom-4-like",
"custom-4-not-like",
"custom-5",
"custom-5-not",
"custom-5-like",
"custom-5-not-like",
"custom-6",
"custom-6-not",
"custom-6-like",
"custom-6-not-like",
"custom-7",
"custom-7-not",
"custom-7-like",
"custom-7-not-like",
"custom-8",
"custom-8-not",
"custom-8-like",
"custom-8-not-like",
"custom-9",
"custom-9-not",
"custom-9-like",
"custom-9-not-like",
"custom-10",
"custom-10-not",
"custom-10-like",
"custom-10-not-like",
"custom-11",
"custom-11-not",
"custom-11-like",
"custom-11-not-like",
"custom-12",
"custom-12-not",
"custom-12-like",
"custom-12-not-like",
"custom-13",
"custom-13-not",
"custom-13-like",
"custom-13-not-like",
"custom-14",
"custom-14-not",
"custom-14-like",
"custom-14-not-like",
"custom-15",
"custom-15-not",
"custom-15-like",
"custom-15-not-like",
"custom-16",
"custom-16-not",
"custom-16-like",
"custom-16-not-like"
})
public TaskQueryFilterCustomFields(
String[] custom1In,
String[] custom1NotIn,
String[] custom1Like,
String[] custom1NotLike,
String[] custom2In,
String[] custom2NotIn,
String[] custom2Like,
String[] custom2NotLike,
String[] custom3In,
String[] custom3NotIn,
String[] custom3Like,
String[] custom3NotLike,
String[] custom4In,
String[] custom4NotIn,
String[] custom4Like,
String[] custom4NotLike,
String[] custom5In,
String[] custom5NotIn,
String[] custom5Like,
String[] custom5NotLike,
String[] custom6In,
String[] custom6NotIn,
String[] custom6Like,
String[] custom6NotLike,
String[] custom7In,
String[] custom7NotIn,
String[] custom7Like,
String[] custom7NotLike,
String[] custom8In,
String[] custom8NotIn,
String[] custom8Like,
String[] custom8NotLike,
String[] custom9In,
String[] custom9NotIn,
String[] custom9Like,
String[] custom9NotLike,
String[] custom10In,
String[] custom10NotIn,
String[] custom10Like,
String[] custom10NotLike,
String[] custom11In,
String[] custom11NotIn,
String[] custom11Like,
String[] custom11NotLike,
String[] custom12In,
String[] custom12NotIn,
String[] custom12Like,
String[] custom12NotLike,
String[] custom13In,
String[] custom13NotIn,
String[] custom13Like,
String[] custom13NotLike,
String[] custom14In,
String[] custom14NotIn,
String[] custom14Like,
String[] custom14NotLike,
String[] custom15In,
String[] custom15NotIn,
String[] custom15Like,
String[] custom15NotLike,
String[] custom16In,
String[] custom16NotIn,
String[] custom16Like,
String[] custom16NotLike) {
this.custom1In = custom1In;
this.custom1NotIn = custom1NotIn;
this.custom1Like = custom1Like;
this.custom1NotLike = custom1NotLike;
this.custom2In = custom2In;
this.custom2NotIn = custom2NotIn;
this.custom2Like = custom2Like;
this.custom2NotLike = custom2NotLike;
this.custom3In = custom3In;
this.custom3NotIn = custom3NotIn;
this.custom3Like = custom3Like;
this.custom3NotLike = custom3NotLike;
this.custom4In = custom4In;
this.custom4NotIn = custom4NotIn;
this.custom4Like = custom4Like;
this.custom4NotLike = custom4NotLike;
this.custom5In = custom5In;
this.custom5NotIn = custom5NotIn;
this.custom5Like = custom5Like;
this.custom5NotLike = custom5NotLike;
this.custom6In = custom6In;
this.custom6NotIn = custom6NotIn;
this.custom6Like = custom6Like;
this.custom6NotLike = custom6NotLike;
this.custom7In = custom7In;
this.custom7NotIn = custom7NotIn;
this.custom7Like = custom7Like;
this.custom7NotLike = custom7NotLike;
this.custom8In = custom8In;
this.custom8NotIn = custom8NotIn;
this.custom8Like = custom8Like;
this.custom8NotLike = custom8NotLike;
this.custom9In = custom9In;
this.custom9NotIn = custom9NotIn;
this.custom9Like = custom9Like;
this.custom9NotLike = custom9NotLike;
this.custom10In = custom10In;
this.custom10NotIn = custom10NotIn;
this.custom10Like = custom10Like;
this.custom10NotLike = custom10NotLike;
this.custom11In = custom11In;
this.custom11NotIn = custom11NotIn;
this.custom11Like = custom11Like;
this.custom11NotLike = custom11NotLike;
this.custom12In = custom12In;
this.custom12NotIn = custom12NotIn;
this.custom12Like = custom12Like;
this.custom12NotLike = custom12NotLike;
this.custom13In = custom13In;
this.custom13NotIn = custom13NotIn;
this.custom13Like = custom13Like;
this.custom13NotLike = custom13NotLike;
this.custom14In = custom14In;
this.custom14NotIn = custom14NotIn;
this.custom14Like = custom14Like;
this.custom14NotLike = custom14NotLike;
this.custom15In = custom15In;
this.custom15NotIn = custom15NotIn;
this.custom15Like = custom15Like;
this.custom15NotLike = custom15NotLike;
this.custom16In = custom16In;
this.custom16NotIn = custom16NotIn;
this.custom16Like = custom16Like;
this.custom16NotLike = custom16NotLike;
}
@Override
public Void apply(TaskQuery query) {
Stream.of(
Pair.of(CUSTOM_1, of(custom1In, custom1NotIn, custom1Like, custom1NotLike)),
Pair.of(CUSTOM_2, of(custom2In, custom2NotIn, custom2Like, custom2NotLike)),
Pair.of(CUSTOM_3, of(custom3In, custom3NotIn, custom3Like, custom3NotLike)),
Pair.of(CUSTOM_4, of(custom4In, custom4NotIn, custom4Like, custom4NotLike)),
Pair.of(CUSTOM_5, of(custom5In, custom5NotIn, custom5Like, custom5NotLike)),
Pair.of(CUSTOM_6, of(custom6In, custom6NotIn, custom6Like, custom6NotLike)),
Pair.of(CUSTOM_7, of(custom7In, custom7NotIn, custom7Like, custom7NotLike)),
Pair.of(CUSTOM_8, of(custom8In, custom8NotIn, custom8Like, custom8NotLike)),
Pair.of(CUSTOM_9, of(custom9In, custom9NotIn, custom9Like, custom9NotLike)),
Pair.of(CUSTOM_10, of(custom10In, custom10NotIn, custom10Like, custom10NotLike)),
Pair.of(CUSTOM_11, of(custom11In, custom11NotIn, custom11Like, custom11NotLike)),
Pair.of(CUSTOM_12, of(custom12In, custom12NotIn, custom12Like, custom12NotLike)),
Pair.of(CUSTOM_13, of(custom13In, custom13NotIn, custom13Like, custom13NotLike)),
Pair.of(CUSTOM_14, of(custom14In, custom14NotIn, custom14Like, custom14NotLike)),
Pair.of(CUSTOM_15, of(custom15In, custom15NotIn, custom15Like, custom15NotLike)),
Pair.of(CUSTOM_16, of(custom16In, custom16NotIn, custom16Like, custom16NotLike)))
.forEach(
pair -> {
Optional.ofNullable(pair.getRight().getFirst())
.ifPresent(wrap(l -> query.customAttributeIn(pair.getLeft(), l)));
Optional.ofNullable(pair.getRight().getSecond())
.ifPresent(wrap(l -> query.customAttributeNotIn(pair.getLeft(), l)));
Optional.ofNullable(pair.getRight().getThird())
.map(this::wrapElementsInLikeStatement)
.ifPresent(wrap(l -> query.customAttributeLike(pair.getLeft(), l)));
Optional.ofNullable(pair.getRight().getFourth())
.map(this::wrapElementsInLikeStatement)
.ifPresent(wrap(l -> query.customAttributeNotLike(pair.getLeft(), l)));
});
return null;
}
}

View File

@ -0,0 +1,837 @@
package pro.taskana.task.rest;
import static pro.taskana.common.internal.util.CheckedConsumer.wrap;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.beans.ConstructorProperties;
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
import java.util.stream.Stream;
import pro.taskana.common.api.IntInterval;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.Quadruple;
import pro.taskana.common.internal.util.Triplet;
import pro.taskana.common.rest.QueryParameter;
import pro.taskana.task.api.TaskCustomIntField;
import pro.taskana.task.api.TaskQuery;
public class TaskQueryFilterCustomIntFields implements QueryParameter<TaskQuery, Void> {
/** Filter by the value of the field customInt1 of the Task. This is an exact match. */
@JsonProperty("custom-int-1")
private final Integer[] customInt1In;
/** Exclude values of the field customInt1 of the Task. */
@JsonProperty("custom-int-1-not")
private final Integer[] customInt1NotIn;
/** Filter by the range of value of the field customInt1 of the Task. */
@JsonProperty("custom-int-1-within")
private final Integer[] customInt1Within;
/** Exclude range of values of the field customInt1 of the Task. */
@JsonProperty("custom-int-1-not-within")
private final Integer[] customInt1NotWithin;
/**
* Filter by lower bound of customInt1.
*
* <p>This parameter can't be used together with 'custom-int-1-within'.
*/
@JsonProperty("custom-int-1-from")
private final Integer customInt1From;
/** Exclude values from a lower bound of the field customInt1 of the Task. */
@JsonProperty("custom-int-1-from-not")
private final Integer customInt1FromNot;
/**
* Filter by upper bound of customInt1.
*
* <p>This parameter can't be used together with 'custom-int-1-within'.
*/
@JsonProperty("custom-int-1-to")
private final Integer customInt1To;
/** Exclude values to an upper bound of the field customInt1 of the Task. */
@JsonProperty("custom-int-1-to-not")
private final Integer customInt1ToNot;
/** Filter by the value of the field customInt2 of the Task. This is an exact match. */
@JsonProperty("custom-int-2")
private final Integer[] customInt2In;
/** Exclude values of the field customInt2 of the Task. */
@JsonProperty("custom-int-2-not")
private final Integer[] customInt2NotIn;
/** Filter by the range of value of the field customInt2 of the Task. */
@JsonProperty("custom-int-2-within")
private final Integer[] customInt2Within;
/** Exclude range of values of the field customInt2 of the Task. */
@JsonProperty("custom-int-2-not-within")
private final Integer[] customInt2NotWithin;
/**
* Filter by lower bound of customInt2.
*
* <p>This parameter can't be used together with 'custom-int-2-within'.
*/
@JsonProperty("custom-int-2-from")
private final Integer customInt2From;
/** Exclude values from a lower bound of the field customInt2 of the Task. */
@JsonProperty("custom-int-2-from-not")
private final Integer customInt2FromNot;
/**
* Filter by upper bound of customInt2.
*
* <p>This parameter can't be used together with 'custom-int-2-within'.
*/
@JsonProperty("custom-int-2-to")
private final Integer customInt2To;
/** Exclude values to an upper bound of the field customInt2 of the Task. */
@JsonProperty("custom-int-2-to-not")
private final Integer customInt2ToNot;
/** Filter by the value of the field customInt3 of the Task. This is an exact match. */
@JsonProperty("custom-int-3")
private final Integer[] customInt3In;
/** Exclude values of the field customInt3 of the Task. */
@JsonProperty("custom-int-3-not")
private final Integer[] customInt3NotIn;
/** Filter by the range of value of the field customInt3 of the Task. */
@JsonProperty("custom-int-3-within")
private final Integer[] customInt3Within;
/** Exclude range of values of the field customInt3 of the Task. */
@JsonProperty("custom-int-3-not-within")
private final Integer[] customInt3NotWithin;
/**
* Filter by lower bound of customInt3.
*
* <p>This parameter can't be used together with 'custom-int-3-within'.
*/
@JsonProperty("custom-int-3-from")
private final Integer customInt3From;
/** Exclude values from a lower bound of the field customInt3 of the Task. */
@JsonProperty("custom-int-3-from-not")
private final Integer customInt3FromNot;
/**
* Filter by upper bound of customInt3.
*
* <p>This parameter can't be used together with 'custom-int-3-within'.
*/
@JsonProperty("custom-int-3-to")
private final Integer customInt3To;
/** Exclude values to an upper bound of the field customInt3 of the Task. */
@JsonProperty("custom-int-3-to-not")
private final Integer customInt3ToNot;
/** Filter by the value of the field customInt4 of the Task. This is an exact match. */
@JsonProperty("custom-int-4")
private final Integer[] customInt4In;
/** Exclude values of the field customInt4 of the Task. */
@JsonProperty("custom-int-4-not")
private final Integer[] customInt4NotIn;
/** Filter by the range of value of the field customInt4 of the Task. */
@JsonProperty("custom-int-4-within")
private final Integer[] customInt4Within;
/** Exclude range of values of the field customInt4 of the Task. */
@JsonProperty("custom-int-4-not-within")
private final Integer[] customInt4NotWithin;
/**
* Filter by lower bound of customInt4.
*
* <p>This parameter can't be used together with 'custom-int-4-within'.
*/
@JsonProperty("custom-int-4-from")
private final Integer customInt4From;
/** Exclude values from a lower bound of the field customInt4 of the Task. */
@JsonProperty("custom-int-4-from-not")
private final Integer customInt4FromNot;
/**
* Filter by upper bound of customInt4.
*
* <p>This parameter can't be used together with 'custom-int-4-within'.
*/
@JsonProperty("custom-int-4-to")
private final Integer customInt4To;
/** Exclude values to an upper bound of the field customInt4 of the Task. */
@JsonProperty("custom-int-4-to-not")
private final Integer customInt4ToNot;
/** Filter by the value of the field customInt5 of the Task. This is an exact match. */
@JsonProperty("custom-int-5")
private final Integer[] customInt5In;
/** Exclude values of the field customInt5 of the Task. */
@JsonProperty("custom-int-5-not")
private final Integer[] customInt5NotIn;
/** Filter by the range of value of the field customInt5 of the Task. */
@JsonProperty("custom-int-5-within")
private final Integer[] customInt5Within;
/** Exclude range of values of the field customInt5 of the Task. */
@JsonProperty("custom-int-5-not-within")
private final Integer[] customInt5NotWithin;
/**
* Filter by lower bound of customInt5.
*
* <p>This parameter can't be used together with 'custom-int-5-within'.
*/
@JsonProperty("custom-int-5-from")
private final Integer customInt5From;
/** Exclude values from a lower bound of the field customInt5 of the Task. */
@JsonProperty("custom-int-5-from-not")
private final Integer customInt5FromNot;
/**
* Filter by upper bound of customInt5.
*
* <p>This parameter can't be used together with 'custom-int-5-within'.
*/
@JsonProperty("custom-int-5-to")
private final Integer customInt5To;
/** Exclude values to an upper bound of the field customInt5 of the Task. */
@JsonProperty("custom-int-5-to-not")
private final Integer customInt5ToNot;
/** Filter by the value of the field customInt6 of the Task. This is an exact match. */
@JsonProperty("custom-int-6")
private final Integer[] customInt6In;
/** Exclude values of the field customInt6 of the Task. */
@JsonProperty("custom-int-6-not")
private final Integer[] customInt6NotIn;
/** Filter by the range of value of the field customInt6 of the Task. */
@JsonProperty("custom-int-6-within")
private final Integer[] customInt6Within;
/** Exclude range of values of the field customInt6 of the Task. */
@JsonProperty("custom-int-6-not-within")
private final Integer[] customInt6NotWithin;
/**
* Filter by lower bound of customInt6.
*
* <p>This parameter can't be used together with 'custom-int-6-within'.
*/
@JsonProperty("custom-int-6-from")
private final Integer customInt6From;
/** Exclude values from a lower bound of the field customInt6 of the Task. */
@JsonProperty("custom-int-6-from-not")
private final Integer customInt6FromNot;
/**
* Filter by upper bound of customInt6.
*
* <p>This parameter can't be used together with 'custom-int-6-within'.
*/
@JsonProperty("custom-int-6-to")
private final Integer customInt6To;
/** Exclude values to an upper bound of the field customInt6 of the Task. */
@JsonProperty("custom-int-6-to-not")
private final Integer customInt6ToNot;
/** Filter by the value of the field customInt7 of the Task. This is an exact match. */
@JsonProperty("custom-int-7")
private final Integer[] customInt7In;
/** Exclude values of the field customInt7 of the Task. */
@JsonProperty("custom-int-7-not")
private final Integer[] customInt7NotIn;
/** Filter by the range of value of the field customInt7 of the Task. */
@JsonProperty("custom-int-7-within")
private final Integer[] customInt7Within;
/** Exclude range of values of the field customInt7 of the Task. */
@JsonProperty("custom-int-7-not-within")
private final Integer[] customInt7NotWithin;
/**
* Filter by lower bound of customInt7.
*
* <p>This parameter can't be used together with 'custom-int-7-within'.
*/
@JsonProperty("custom-int-7-from")
private final Integer customInt7From;
/** Exclude values from a lower bound of the field customInt7 of the Task. */
@JsonProperty("custom-int-7-from-not")
private final Integer customInt7FromNot;
/**
* Filter by upper bound of customInt7.
*
* <p>This parameter can't be used together with 'custom-int-7-within'.
*/
@JsonProperty("custom-int-7-to")
private final Integer customInt7To;
/** Exclude values to an upper bound of the field customInt7 of the Task. */
@JsonProperty("custom-int-7-to-not")
private final Integer customInt7ToNot;
/** Filter by the value of the field customInt8 of the Task. This is an exact match. */
@JsonProperty("custom-int-8")
private final Integer[] customInt8In;
/** Exclude values of the field customInt8 of the Task. */
@JsonProperty("custom-int-8-not")
private final Integer[] customInt8NotIn;
/** Filter by the range of value of the field customInt8 of the Task. */
@JsonProperty("custom-int-8-within")
private final Integer[] customInt8Within;
/** Exclude range of values of the field customInt8 of the Task. */
@JsonProperty("custom-int-8-not-within")
private final Integer[] customInt8NotWithin;
/**
* Filter by lower bound of customInt8.
*
* <p>This parameter can't be used together with 'custom-int-8-within'.
*/
@JsonProperty("custom-int-8-from")
private final Integer customInt8From;
/** Exclude values from a lower bound of the field customInt8 of the Task. */
@JsonProperty("custom-int-8-from-not")
private final Integer customInt8FromNot;
/**
* Filter by upper bound of customInt8.
*
* <p>This parameter can't be used together with 'custom-int-8-within'.
*/
@JsonProperty("custom-int-8-to")
private final Integer customInt8To;
/** Exclude values to an upper bound of the field customInt8 of the Task. */
@JsonProperty("custom-int-8-to-not")
private final Integer customInt8ToNot;
@ConstructorProperties({
"custom-int-1",
"custom-int-1-not",
"custom-int-1-within",
"custom-int-1-not-within",
"custom-int-1-from",
"custom-int-1-from-not",
"custom-int-1-to",
"custom-int-1-to-not",
"custom-int-2",
"custom-int-2-not",
"custom-int-2-within",
"custom-int-2-not-within",
"custom-int-2-from",
"custom-int-2-from-not",
"custom-int-2-to",
"custom-int-2-to-not",
"custom-int-3",
"custom-int-3-not",
"custom-int-3-within",
"custom-int-3-not-within",
"custom-int-3-from",
"custom-int-3-from-not",
"custom-int-3-to",
"custom-int-3-to-not",
"custom-int-4",
"custom-int-4-not",
"custom-int-4-within",
"custom-int-4-not-within",
"custom-int-4-from",
"custom-int-4-from-not",
"custom-int-4-to",
"custom-int-4-to-not",
"custom-int-5",
"custom-int-5-not",
"custom-int-5-within",
"custom-int-5-not-within",
"custom-int-5-from",
"custom-int-5-from-not",
"custom-int-5-to",
"custom-int-5-to-not",
"custom-int-6",
"custom-int-6-not",
"custom-int-6-within",
"custom-int-6-not-within",
"custom-int-6-from",
"custom-int-6-from-not",
"custom-int-6-to",
"custom-int-6-to-not",
"custom-int-7",
"custom-int-7-not",
"custom-int-7-within",
"custom-int-7-not-within",
"custom-int-7-from",
"custom-int-7-from-not",
"custom-int-7-to",
"custom-int-7-to-not",
"custom-int-8",
"custom-int-8-not",
"custom-int-8-within",
"custom-int-8-not-within",
"custom-int-8-from",
"custom-int-8-from-not",
"custom-int-8-to",
"custom-int-8-to-not"
})
public TaskQueryFilterCustomIntFields(
Integer[] customInt1In,
Integer[] customInt1NotIn,
Integer[] customInt1Within,
Integer[] customInt1NotWithin,
Integer customInt1From,
Integer customInt1FromNot,
Integer customInt1To,
Integer customInt1ToNot,
Integer[] customInt2In,
Integer[] customInt2NotIn,
Integer[] customInt2Within,
Integer[] customInt2NotWithin,
Integer customInt2From,
Integer customInt2FromNot,
Integer customInt2To,
Integer customInt2ToNot,
Integer[] customInt3In,
Integer[] customInt3NotIn,
Integer[] customInt3Within,
Integer[] customInt3NotWithin,
Integer customInt3From,
Integer customInt3FromNot,
Integer customInt3To,
Integer customInt3ToNot,
Integer[] customInt4In,
Integer[] customInt4NotIn,
Integer[] customInt4Within,
Integer[] customInt4NotWithin,
Integer customInt4From,
Integer customInt4FromNot,
Integer customInt4To,
Integer customInt4ToNot,
Integer[] customInt5In,
Integer[] customInt5NotIn,
Integer[] customInt5Within,
Integer[] customInt5NotWithin,
Integer customInt5From,
Integer customInt5FromNot,
Integer customInt5To,
Integer customInt5ToNot,
Integer[] customInt6In,
Integer[] customInt6NotIn,
Integer[] customInt6Within,
Integer[] customInt6NotWithin,
Integer customInt6From,
Integer customInt6FromNot,
Integer customInt6To,
Integer customInt6ToNot,
Integer[] customInt7In,
Integer[] customInt7NotIn,
Integer[] customInt7Within,
Integer[] customInt7NotWithin,
Integer customInt7From,
Integer customInt7FromNot,
Integer customInt7To,
Integer customInt7ToNot,
Integer[] customInt8In,
Integer[] customInt8NotIn,
Integer[] customInt8Within,
Integer[] customInt8NotWithin,
Integer customInt8From,
Integer customInt8FromNot,
Integer customInt8To,
Integer customInt8ToNot)
throws InvalidArgumentException {
this.customInt1In = customInt1In;
this.customInt1NotIn = customInt1NotIn;
this.customInt1Within = customInt1Within;
this.customInt1NotWithin = customInt1NotWithin;
this.customInt1From = customInt1From;
this.customInt1FromNot = customInt1FromNot;
this.customInt1To = customInt1To;
this.customInt1ToNot = customInt1ToNot;
this.customInt2In = customInt2In;
this.customInt2NotIn = customInt2NotIn;
this.customInt2Within = customInt2Within;
this.customInt2NotWithin = customInt2NotWithin;
this.customInt2From = customInt2From;
this.customInt2FromNot = customInt2FromNot;
this.customInt2To = customInt2To;
this.customInt2ToNot = customInt2ToNot;
this.customInt3In = customInt3In;
this.customInt3NotIn = customInt3NotIn;
this.customInt3Within = customInt3Within;
this.customInt3NotWithin = customInt3NotWithin;
this.customInt3From = customInt3From;
this.customInt3FromNot = customInt3FromNot;
this.customInt3To = customInt3To;
this.customInt3ToNot = customInt3ToNot;
this.customInt4In = customInt4In;
this.customInt4NotIn = customInt4NotIn;
this.customInt4Within = customInt4Within;
this.customInt4NotWithin = customInt4NotWithin;
this.customInt4From = customInt4From;
this.customInt4FromNot = customInt4FromNot;
this.customInt4To = customInt4To;
this.customInt4ToNot = customInt4ToNot;
this.customInt5In = customInt5In;
this.customInt5NotIn = customInt5NotIn;
this.customInt5Within = customInt5Within;
this.customInt5NotWithin = customInt5NotWithin;
this.customInt5From = customInt5From;
this.customInt5FromNot = customInt5FromNot;
this.customInt5To = customInt5To;
this.customInt5ToNot = customInt5ToNot;
this.customInt6In = customInt6In;
this.customInt6NotIn = customInt6NotIn;
this.customInt6Within = customInt6Within;
this.customInt6NotWithin = customInt6NotWithin;
this.customInt6From = customInt6From;
this.customInt6FromNot = customInt6FromNot;
this.customInt6To = customInt6To;
this.customInt6ToNot = customInt6ToNot;
this.customInt7In = customInt7In;
this.customInt7NotIn = customInt7NotIn;
this.customInt7Within = customInt7Within;
this.customInt7NotWithin = customInt7NotWithin;
this.customInt7From = customInt7From;
this.customInt7FromNot = customInt7FromNot;
this.customInt7To = customInt7To;
this.customInt7ToNot = customInt7ToNot;
this.customInt8In = customInt8In;
this.customInt8NotIn = customInt8NotIn;
this.customInt8Within = customInt8Within;
this.customInt8NotWithin = customInt8NotWithin;
this.customInt8From = customInt8From;
this.customInt8FromNot = customInt8FromNot;
this.customInt8To = customInt8To;
this.customInt8ToNot = customInt8ToNot;
validateFilterParameters();
}
@Override
public Void apply(TaskQuery query) {
Stream.of(
Triplet.of(
TaskCustomIntField.CUSTOM_INT_1,
Quadruple.of(customInt1In, customInt1NotIn, customInt1Within, customInt1NotWithin),
Quadruple.of(customInt1From, customInt1FromNot, customInt1To, customInt1ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_2,
Quadruple.of(customInt2In, customInt2NotIn, customInt2Within, customInt2NotWithin),
Quadruple.of(customInt2From, customInt2FromNot, customInt2To, customInt2ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_3,
Quadruple.of(customInt3In, customInt3NotIn, customInt3Within, customInt3NotWithin),
Quadruple.of(customInt3From, customInt3FromNot, customInt3To, customInt3ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_4,
Quadruple.of(customInt4In, customInt4NotIn, customInt4Within, customInt4NotWithin),
Quadruple.of(customInt4From, customInt4FromNot, customInt4To, customInt4ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_5,
Quadruple.of(customInt5In, customInt5NotIn, customInt5Within, customInt5NotWithin),
Quadruple.of(customInt5From, customInt5FromNot, customInt5To, customInt5ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_6,
Quadruple.of(customInt6In, customInt6NotIn, customInt6Within, customInt6NotWithin),
Quadruple.of(customInt6From, customInt6FromNot, customInt6To, customInt6ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_7,
Quadruple.of(customInt7In, customInt7NotIn, customInt7Within, customInt7NotWithin),
Quadruple.of(customInt7From, customInt7FromNot, customInt7To, customInt7ToNot)),
Triplet.of(
TaskCustomIntField.CUSTOM_INT_8,
Quadruple.of(customInt8In, customInt8NotIn, customInt8Within, customInt8NotWithin),
Quadruple.of(customInt8From, customInt8FromNot, customInt8To, customInt8ToNot)))
.forEach(
triplet -> {
TaskCustomIntField customField = triplet.getLeft();
Optional.ofNullable(triplet.getMiddle().getFirst())
.ifPresent(wrap(l -> query.customIntAttributeIn(customField, l)));
Optional.ofNullable(triplet.getMiddle().getSecond())
.ifPresent(wrap(l -> query.customIntAttributeNotIn(customField, l)));
Optional.ofNullable(triplet.getMiddle().getThird())
.map(this::extractIntIntervals)
.ifPresent(wrap(l -> query.customIntAttributeWithin(customField, l)));
Optional.ofNullable(triplet.getMiddle().getFourth())
.map(this::extractIntIntervals)
.ifPresent(wrap(l -> query.customIntAttributeNotWithin(customField, l)));
Integer from = triplet.getRight().getFirst();
Integer to = triplet.getRight().getThird();
if (from != null || to != null) {
query.customIntAttributeWithin(customField, new IntInterval(from, to));
}
Integer fromNot = triplet.getRight().getSecond();
Integer toNot = triplet.getRight().getFourth();
if (fromNot != null || toNot != null) {
query.customIntAttributeWithin(customField, new IntInterval(fromNot, toNot));
}
});
return null;
}
private void validateFilterParameters() throws InvalidArgumentException {
if (customInt1Within != null && customInt1Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-1-within' is not dividable by 2");
}
if (customInt1Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt1Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-1-within' shouldn't consist of two 'null' values");
}
if (customInt2Within != null && customInt2Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-2-within' is not dividable by 2");
}
if (customInt2Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt2Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-2-within' shouldn't consist of two 'null' values");
}
if (customInt3Within != null && customInt3Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-3-within' is not dividable by 2");
}
if (customInt3Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt3Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-3-within' shouldn't consist of two 'null' values");
}
if (customInt4Within != null && customInt4Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-4-within' is not dividable by 2");
}
if (customInt4Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt4Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-4-within' shouldn't consist of two 'null' values");
}
if (customInt5Within != null && customInt5Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-5-within' is not dividable by 2");
}
if (customInt5Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt5Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-5-within' shouldn't consist of two 'null' values");
}
if (customInt6Within != null && customInt6Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-6-within' is not dividable by 2");
}
if (customInt6Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt6Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-6-within' shouldn't consist of two 'null' values");
}
if (customInt7Within != null && customInt7Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-7-within' is not dividable by 2");
}
if (customInt7Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt7Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-7-within' shouldn't consist of two 'null' values");
}
if (customInt8Within != null && customInt8Within.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-8-within' is not dividable by 2");
}
if (customInt8Within != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt8Within), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-8-within' shouldn't consist of two 'null' values");
}
if (customInt1NotWithin != null && customInt1NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-1-not-within' is not dividable by 2");
}
if (customInt1NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt1NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-1-not-within' shouldn't consist of two 'null' values");
}
if (customInt2NotWithin != null && customInt2NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-2-not-within' is not dividable by 2");
}
if (customInt2NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt2NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-2-not-within' shouldn't consist of two 'null' values");
}
if (customInt3NotWithin != null && customInt3NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-3-not-within' is not dividable by 2");
}
if (customInt3NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt3NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-3-not-within' shouldn't consist of two 'null' values");
}
if (customInt4NotWithin != null && customInt4NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-4-not-within' is not dividable by 2");
}
if (customInt4NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt4NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-4-not-within' shouldn't consist of two 'null' values");
}
if (customInt5NotWithin != null && customInt5NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-5-not-within' is not dividable by 2");
}
if (customInt5NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt5NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-5-not-within' shouldn't consist of two 'null' values");
}
if (customInt6NotWithin != null && customInt6NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-6-not-within' is not dividable by 2");
}
if (customInt6NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt6NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-6-not-within' shouldn't consist of two 'null' values");
}
if (customInt7NotWithin != null && customInt7NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-7-not-within' is not dividable by 2");
}
if (customInt7NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt7NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-7-not-within' shouldn't consist of two 'null' values");
}
if (customInt8NotWithin != null && customInt8NotWithin.length % 2 != 0) {
throw new InvalidArgumentException(
"provided length of the property 'custom-int-8-not-within' is not dividable by 2");
}
if (customInt8NotWithin != null
&& (Collections.indexOfSubList(
Arrays.asList(customInt8NotWithin), Collections.nCopies(2, (Integer) null))
% 2
== 0)) {
throw new InvalidArgumentException(
"Each interval in 'custom-int-8-not-within' shouldn't consist of two 'null' values");
}
if (customInt1Within != null && (customInt1From != null || customInt1To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-1-within' in combination "
+ "with the params 'custom-int-1-from' and / or 'custom-int-1-to'");
}
if (customInt1NotWithin != null && (customInt1FromNot != null || customInt1ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-1-not-within' in combination "
+ "with the params 'custom-int-1-from-not' and / or 'custom-int-1-to-not'");
}
if (customInt2Within != null && (customInt2From != null || customInt2To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-2-within' in combination "
+ "with the params 'custom-int-2-from' and / or 'custom-int-2-to'");
}
if (customInt2NotWithin != null && (customInt2FromNot != null || customInt2ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-2-not-within' in combination "
+ "with the params 'custom-int-2-from-not' and / or 'custom-int-2-to-not'");
}
if (customInt3Within != null && (customInt3From != null || customInt3To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-3-within' in combination "
+ "with the params 'custom-int-3-from' and / or 'custom-int-3-to'");
}
if (customInt3NotWithin != null && (customInt3FromNot != null || customInt3ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-3-not-within' in combination "
+ "with the params 'custom-int-3-from-not' and / or 'custom-int-3-to-not'");
}
if (customInt4Within != null && (customInt4From != null || customInt4To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-4-within' in combination "
+ "with the params 'custom-int-4-from' and / or 'custom-int-4-to'");
}
if (customInt4NotWithin != null && (customInt4FromNot != null || customInt4ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-4-not-within' in combination "
+ "with the params 'custom-int-4-from-not' and / or 'custom-int-4-to-not'");
}
if (customInt5Within != null && (customInt5From != null || customInt5To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-5-within' in combination "
+ "with the params 'custom-int-5-from' and / or 'custom-int-5-to'");
}
if (customInt5NotWithin != null && (customInt5FromNot != null || customInt5ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-5-not-within' in combination "
+ "with the params 'custom-int-5-from-not' and / or 'custom-int-5-to-not'");
}
if (customInt6Within != null && (customInt6From != null || customInt6To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-6-within' in combination "
+ "with the params 'custom-int-6-from' and / or 'custom-int-6-to'");
}
if (customInt6NotWithin != null && (customInt6FromNot != null || customInt6ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-6-not-within' in combination "
+ "with the params 'custom-int-6-from-not' and / or 'custom-int-6-to-not'");
}
if (customInt7Within != null && (customInt7From != null || customInt7To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-7-within' in combination "
+ "with the params 'custom-int-7-from' and / or 'custom-int-7-to'");
}
if (customInt7NotWithin != null && (customInt7FromNot != null || customInt7ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-7-not-within' in combination "
+ "with the params 'custom-int-7-from-not' and / or 'custom-int-7-to-not'");
}
if (customInt8Within != null && (customInt8From != null || customInt8To != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-8-within' in combination "
+ "with the params 'custom-int-8-from' and / or 'custom-int-8-to'");
}
if (customInt8NotWithin != null && (customInt8FromNot != null || customInt8ToNot != null)) {
throw new InvalidArgumentException(
"It is prohibited to use the param 'custom-int-8-not-within' in combination "
+ "with the params 'custom-int-8-from-not' and / or 'custom-int-8-to-not'");
}
}
}

View File

@ -181,6 +181,81 @@ class TaskControllerIntTest {
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
}
@TestFactory
Stream<DynamicTest> should_GetAllTasks_For_SpecifiedWorkbasketIdAndCustomIntFieldFrom() {
List<Integer> customIntValues = List.of(1, 2, 3, 4, 5, 6, 7, 8);
ThrowingConsumer<Integer> test =
i -> {
String url =
restHelper.toUrl(RestEndpoints.URL_TASKS)
+ String.format(
"?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&custom-int-%s-from=%s",
i, i);
HttpEntity<Object> auth =
new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
ResponseEntity<TaskSummaryPagedRepresentationModel> response =
TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_SUMMARY_PAGE_MODEL_TYPE);
assertThat(response.getBody()).isNotNull();
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
assertThat(response.getBody().getContent()).hasSize(22);
};
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
}
@TestFactory
Stream<DynamicTest> should_GetAllTasks_For_SpecifiedWorkbasketIdAndCustomIntFieldFromAndTo() {
List<Integer> customIntValues = List.of(1, 2, 3, 4, 5, 6, 7, 8);
ThrowingConsumer<Integer> test =
i -> {
String url =
restHelper.toUrl(RestEndpoints.URL_TASKS)
+ String.format(
"?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&custom-int-%s-from=-1&custom-int-%s-to=123",
i, i);
HttpEntity<Object> auth =
new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
ResponseEntity<TaskSummaryPagedRepresentationModel> response =
TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_SUMMARY_PAGE_MODEL_TYPE);
assertThat(response.getBody()).isNotNull();
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
assertThat(response.getBody().getContent()).hasSize(22);
};
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
}
@TestFactory
Stream<DynamicTest> should_GetAllTasks_For_SpecifiedWorkbasketIdAndCustomIntFieldTo() {
List<Integer> customIntValues = List.of(1, 2, 3, 4, 5, 6, 7, 8);
ThrowingConsumer<Integer> test =
i -> {
String url =
restHelper.toUrl(RestEndpoints.URL_TASKS)
+ String.format(
"?workbasket-id=WBI:100000000000000000000000000000000001"
+ "&custom-int-%s-to=%s",
i, i);
HttpEntity<Object> auth =
new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
ResponseEntity<TaskSummaryPagedRepresentationModel> response =
TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_SUMMARY_PAGE_MODEL_TYPE);
assertThat(response.getBody()).isNotNull();
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
assertThat(response.getBody().getContent()).hasSize(22);
};
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
}
@TestFactory
Stream<DynamicTest> should_GetAllTasks_For_SpecifiedWorkbasketIdAndCustomIntFieldNotIn() {
List<Integer> customIntValues = List.of(1, 2, 3, 4, 5, 6, 7, 8);
@ -229,9 +304,10 @@ class TaskControllerIntTest {
assertThatThrownBy(httpCall)
.isInstanceOf(HttpStatusCodeException.class)
.hasMessageContaining(
"provided length of the property 'custom-int-"
+ i
+ "-within' is not dividable by 2")
String.format(
"provided length of the property 'custom-int-%s-within' is not dividable by"
+ " 2",
i))
.extracting(HttpStatusCodeException.class::cast)
.extracting(HttpStatusCodeException::getStatusCode)
.isEqualTo(HttpStatus.BAD_REQUEST);
@ -262,9 +338,11 @@ class TaskControllerIntTest {
assertThatThrownBy(httpCall)
.isInstanceOf(HttpStatusCodeException.class)
.hasMessageContaining(
"Each interval in 'custom-int-"
+ i
+ "-within' shouldn't consist of two 'null' values")
String.format(
"Each interval in 'custom-int-"
+ i
+ "-within' shouldn't consist of two 'null' values",
i))
.extracting(HttpStatusCodeException.class::cast)
.extracting(HttpStatusCodeException::getStatusCode)
.isEqualTo(HttpStatus.BAD_REQUEST);