TSK-1837: Add within and notWithin filter criteria
This commit is contained in:
parent
18ee26ba80
commit
803b4b20a2
|
@ -0,0 +1,64 @@
|
|||
package pro.taskana.common.api;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* IntInterval captures an Integer interval. A fixed interval has defined begin and end. An open
|
||||
* ended interval has either begin == null or end ==null.
|
||||
*/
|
||||
public class IntInterval {
|
||||
|
||||
private Integer begin;
|
||||
private Integer end;
|
||||
|
||||
public IntInterval(Integer begin, Integer end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
boolean isValid = begin != null || end != null;
|
||||
if (begin != null && end != null && begin > end) {
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
public Integer getBegin() {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof IntInterval)) {
|
||||
return false;
|
||||
}
|
||||
IntInterval other = (IntInterval) obj;
|
||||
return Objects.equals(begin, other.begin) && Objects.equals(end, other.end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IntInterval [" + "begin=" + this.begin + ", end=" + this.end + "]";
|
||||
}
|
||||
}
|
|
@ -59,7 +59,7 @@ public class SqlProviderUtil {
|
|||
return whereNotIn(collection, column, new StringBuilder());
|
||||
}
|
||||
|
||||
public static StringBuilder whereInTime(String collection, String column, StringBuilder sb) {
|
||||
public static StringBuilder whereInInterval(String collection, String column, StringBuilder sb) {
|
||||
return sb.append("<if test='")
|
||||
.append(collection)
|
||||
.append(" !=null'> AND (<foreach item='item' collection='")
|
||||
|
@ -73,11 +73,12 @@ public class SqlProviderUtil {
|
|||
.append(" <=#{item.end} </if>)</foreach>)</if> ");
|
||||
}
|
||||
|
||||
public static StringBuilder whereInTime(String collection, String column) {
|
||||
return whereInTime(collection, column, new StringBuilder());
|
||||
public static StringBuilder whereInInterval(String collection, String column) {
|
||||
return whereInInterval(collection, column, new StringBuilder());
|
||||
}
|
||||
|
||||
public static StringBuilder whereNotInTime(String collection, String column, StringBuilder sb) {
|
||||
public static StringBuilder whereNotInInterval(
|
||||
String collection, String column, StringBuilder sb) {
|
||||
return sb.append("<if test='")
|
||||
.append(collection)
|
||||
.append(" !=null'> AND (<foreach item='item' collection='")
|
||||
|
@ -91,8 +92,8 @@ public class SqlProviderUtil {
|
|||
.append(" > #{item.end} </if>)</foreach>)</if> ");
|
||||
}
|
||||
|
||||
public static StringBuilder whereNotInTime(String collection, String column) {
|
||||
return whereNotInTime(collection, column, new StringBuilder());
|
||||
public static StringBuilder whereNotInInterval(String collection, String column) {
|
||||
return whereNotInInterval(collection, column, new StringBuilder());
|
||||
}
|
||||
|
||||
public static StringBuilder whereLike(String collection, String column, StringBuilder sb) {
|
||||
|
@ -150,6 +151,8 @@ public class SqlProviderUtil {
|
|||
String column = baseColumn + "_" + x;
|
||||
whereIn(baseCollection + x + "In", column, sb);
|
||||
whereNotIn(baseCollection + x + "NotIn", column, sb);
|
||||
whereInInterval(baseCollection + x + "Within", column, sb);
|
||||
whereNotInInterval(baseCollection + x + "NotWithin", column, sb);
|
||||
});
|
||||
return sb;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
|
@ -24,10 +25,12 @@ import org.junit.jupiter.api.function.ThrowingConsumer;
|
|||
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.models.ClassificationSummary;
|
||||
import pro.taskana.common.api.IntInterval;
|
||||
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;
|
||||
|
@ -235,7 +238,7 @@ class TaskQueryImplAccTest {
|
|||
.customAttribute(TaskCustomField.CUSTOM_14, "custom14")
|
||||
.customAttribute(TaskCustomField.CUSTOM_15, "custom15")
|
||||
.customAttribute(TaskCustomField.CUSTOM_16, "custom16")
|
||||
.customIntField(TaskCustomIntField.CUSTOM_INT_1, (Integer) 1)
|
||||
.customIntField(TaskCustomIntField.CUSTOM_INT_1, 1)
|
||||
.customIntField(TaskCustomIntField.CUSTOM_INT_2, 2)
|
||||
.customIntField(TaskCustomIntField.CUSTOM_INT_3, 3)
|
||||
.customIntField(TaskCustomIntField.CUSTOM_INT_4, 4)
|
||||
|
@ -3295,6 +3298,69 @@ class TaskQueryImplAccTest {
|
|||
taskSummary3 = taskInWorkbasket(wb).buildAndStoreAsSummary(taskService);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_ThrowException_When_QueryingForCustomIntWithinInvalidInterval() {
|
||||
List<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> testCases =
|
||||
List.of(
|
||||
Quadruple.of(
|
||||
"CustomInt1",
|
||||
TaskCustomIntField.CUSTOM_INT_1,
|
||||
new IntInterval(4, 1),
|
||||
new IntInterval(-10, -8)),
|
||||
Quadruple.of(
|
||||
"CustomInt2",
|
||||
TaskCustomIntField.CUSTOM_INT_2,
|
||||
new IntInterval(null, null),
|
||||
new IntInterval(0, null)),
|
||||
Quadruple.of(
|
||||
"CustomInt3",
|
||||
TaskCustomIntField.CUSTOM_INT_3,
|
||||
new IntInterval(-1, 5),
|
||||
new IntInterval(null, null)),
|
||||
Quadruple.of(
|
||||
"CustomInt4",
|
||||
TaskCustomIntField.CUSTOM_INT_4,
|
||||
new IntInterval(0, -5),
|
||||
new IntInterval(-2, -10)),
|
||||
Quadruple.of(
|
||||
"CustomInt5",
|
||||
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",
|
||||
TaskCustomIntField.CUSTOM_INT_7,
|
||||
new IntInterval(null, null),
|
||||
new IntInterval(null, null)),
|
||||
Quadruple.of(
|
||||
"CustomInt8",
|
||||
TaskCustomIntField.CUSTOM_INT_8,
|
||||
new IntInterval(123, 122),
|
||||
new IntInterval(1, 0)));
|
||||
|
||||
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
|
||||
q -> {
|
||||
ThrowingCallable result =
|
||||
() ->
|
||||
taskService
|
||||
.createTaskQuery()
|
||||
.workbasketIdIn(wb.getId())
|
||||
.customIntAttributeWithin(q.getSecond(), q.getThird(), q.getFourth())
|
||||
.list();
|
||||
assertThatThrownBy(result)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("IntInterval");
|
||||
};
|
||||
|
||||
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntIn() {
|
||||
|
@ -3350,6 +3416,126 @@ class TaskQueryImplAccTest {
|
|||
|
||||
return DynamicTest.stream(testCases.iterator(), Triplet::getLeft, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntWithin() {
|
||||
List<Quadruple<String, TaskCustomIntField, IntInterval, 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",
|
||||
TaskCustomIntField.CUSTOM_INT_3,
|
||||
new IntInterval(-1, 5),
|
||||
new IntInterval(0, null)),
|
||||
Quadruple.of(
|
||||
"CustomInt4",
|
||||
TaskCustomIntField.CUSTOM_INT_4,
|
||||
new IntInterval(0, 1),
|
||||
new IntInterval(-2, 22)),
|
||||
Quadruple.of(
|
||||
"CustomInt5",
|
||||
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)));
|
||||
|
||||
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
|
||||
q -> {
|
||||
List<TaskSummary> result =
|
||||
taskService
|
||||
.createTaskQuery()
|
||||
.workbasketIdIn(wb.getId())
|
||||
.customIntAttributeWithin(q.getSecond(), q.getThird(), q.getFourth())
|
||||
.list();
|
||||
assertThat(result).containsExactly(taskSummary1);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_ApplyFilter_When_QueryingForCustomIntNotWithin() {
|
||||
List<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> testCases =
|
||||
List.of(
|
||||
Quadruple.of(
|
||||
"CustomInt1",
|
||||
TaskCustomIntField.CUSTOM_INT_1,
|
||||
new IntInterval(1, 1),
|
||||
new IntInterval(0, 10)),
|
||||
Quadruple.of(
|
||||
"CustomInt2",
|
||||
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",
|
||||
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)));
|
||||
|
||||
ThrowingConsumer<Quadruple<String, TaskCustomIntField, IntInterval, IntInterval>> test =
|
||||
q -> {
|
||||
List<TaskSummary> result =
|
||||
taskService
|
||||
.createTaskQuery()
|
||||
.workbasketIdIn(wb.getId())
|
||||
.customIntAttributeNotWithin(q.getSecond(), q.getThird(), q.getFourth())
|
||||
.list();
|
||||
assertThat(result).containsExactly(taskSummary2);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(testCases.iterator(), Quadruple::getFirst, test);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package pro.taskana.task.api;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery;
|
||||
import pro.taskana.common.api.IntInterval;
|
||||
import pro.taskana.common.api.KeyDomain;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
|
@ -1706,6 +1707,33 @@ public interface TaskQuery extends BaseQuery<TaskSummary, TaskQueryColumnName> {
|
|||
TaskQuery customIntAttributeNotIn(TaskCustomIntField customIntField, Integer... searchArguments)
|
||||
throws InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Add the values of specified {@linkplain TaskCustomIntField} for a range matching to your query.
|
||||
* If the lower bound is NULL, then all values smaller than the upper bound will be accepted. If
|
||||
* the upper bound is NULL, then all values greater than the lower bound will be accepted.
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Exclude the values of specified {@linkplain TaskCustomIntField} inside the given range from
|
||||
* your query. If the lower bound is NULL, then all values smaller than the upper bound will be
|
||||
* excluded. If the upper bound is NULL, then all values greater than the lower bound will be
|
||||
* excluded.
|
||||
*
|
||||
* @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 customIntAttributeNotWithin(TaskCustomIntField customIntField, IntInterval... values)
|
||||
throws InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* This method sorts the query result according to the value of the specified {@linkplain
|
||||
* TaskCustomIntField}.
|
||||
|
|
|
@ -6,15 +6,14 @@ 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.whereInTime;
|
||||
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.whereNotInTime;
|
||||
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 {
|
||||
|
@ -95,10 +94,10 @@ public class TaskCommentQuerySqlProvider {
|
|||
whereNotIn("creatorNotIn", "tc.CREATOR", sb);
|
||||
whereLike("creatorLike", "tc.CREATOR", sb);
|
||||
whereNotLike("creatorNotLike", "tc.CREATOR", sb);
|
||||
whereInTime("createdIn", "tc.CREATED", sb);
|
||||
whereNotInTime("createdNotIn", "tc.CREATED", sb);
|
||||
whereInTime("modifiedIn", "tc.MODIFIED", sb);
|
||||
whereNotInTime("modifiedNotIn", "tc.MODIFIED", 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);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.apache.ibatis.session.RowBounds;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pro.taskana.common.api.IntInterval;
|
||||
import pro.taskana.common.api.KeyDomain;
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
|
@ -290,20 +291,36 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
// region customIntAttributes
|
||||
private Integer[] customInt1In;
|
||||
private Integer[] customInt1NotIn;
|
||||
private IntInterval[] customInt1Within;
|
||||
private IntInterval[] customInt1NotWithin;
|
||||
private Integer[] customInt2In;
|
||||
private Integer[] customInt2NotIn;
|
||||
private IntInterval[] customInt2Within;
|
||||
private IntInterval[] customInt2NotWithin;
|
||||
private Integer[] customInt3In;
|
||||
private Integer[] customInt3NotIn;
|
||||
private IntInterval[] customInt3Within;
|
||||
private IntInterval[] customInt3NotWithin;
|
||||
private Integer[] customInt4In;
|
||||
private Integer[] customInt4NotIn;
|
||||
private IntInterval[] customInt4Within;
|
||||
private IntInterval[] customInt4NotWithin;
|
||||
private Integer[] customInt5In;
|
||||
private Integer[] customInt5NotIn;
|
||||
private IntInterval[] customInt5Within;
|
||||
private IntInterval[] customInt5NotWithin;
|
||||
private Integer[] customInt6In;
|
||||
private Integer[] customInt6NotIn;
|
||||
private IntInterval[] customInt6Within;
|
||||
private IntInterval[] customInt6NotWithin;
|
||||
private Integer[] customInt7In;
|
||||
private Integer[] customInt7NotIn;
|
||||
private IntInterval[] customInt7Within;
|
||||
private IntInterval[] customInt7NotWithin;
|
||||
private Integer[] customInt8In;
|
||||
private Integer[] customInt8NotIn;
|
||||
private IntInterval[] customInt8Within;
|
||||
private IntInterval[] customInt8NotWithin;
|
||||
// endregion
|
||||
// region callbackState
|
||||
private CallbackState[] callbackStateIn;
|
||||
|
@ -351,14 +368,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery receivedWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.receivedWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery receivedNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.receivedNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -370,14 +387,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery createdWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.createdWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery createdNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.createdNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -389,14 +406,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery claimedWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.claimedWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery claimedNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.claimedNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -408,14 +425,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery modifiedWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.modifiedWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery modifiedNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.modifiedNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -427,14 +444,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery plannedWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.plannedWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery plannedNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.plannedNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -446,14 +463,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery dueWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.dueWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery dueNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.dueNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -465,14 +482,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery completedWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.completedWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery completedNotWithin(TimeInterval... intervals) {
|
||||
validateAllIntervals(intervals);
|
||||
validateAllTimeIntervals(intervals);
|
||||
this.completedNotWithin = intervals;
|
||||
return this;
|
||||
}
|
||||
|
@ -1182,7 +1199,7 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery attachmentReceivedWithin(TimeInterval... receivedIn) {
|
||||
validateAllIntervals(receivedIn);
|
||||
validateAllTimeIntervals(receivedIn);
|
||||
joinWithAttachments = true;
|
||||
this.attachmentReceivedWithin = receivedIn;
|
||||
return this;
|
||||
|
@ -1190,7 +1207,7 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
|
||||
@Override
|
||||
public TaskQuery attachmentNotReceivedWithin(TimeInterval... receivedNotIn) {
|
||||
validateAllIntervals(receivedNotIn);
|
||||
validateAllTimeIntervals(receivedNotIn);
|
||||
joinWithAttachments = true;
|
||||
this.attachmentReceivedNotWithin = receivedNotIn;
|
||||
return this;
|
||||
|
@ -1759,6 +1776,76 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
return addOrderCriteria(customIntField.name(), sortDirection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery customIntAttributeWithin(
|
||||
TaskCustomIntField customIntField, IntInterval... values) {
|
||||
validateAllIntIntervals(values);
|
||||
switch (customIntField) {
|
||||
case CUSTOM_INT_1:
|
||||
this.customInt1Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_2:
|
||||
this.customInt2Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_3:
|
||||
this.customInt3Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_4:
|
||||
this.customInt4Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_5:
|
||||
this.customInt5Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_6:
|
||||
this.customInt6Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_7:
|
||||
this.customInt7Within = values;
|
||||
break;
|
||||
case CUSTOM_INT_8:
|
||||
this.customInt8Within = values;
|
||||
break;
|
||||
default:
|
||||
throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery customIntAttributeNotWithin(
|
||||
TaskCustomIntField customIntField, IntInterval... values) {
|
||||
validateAllIntIntervals(values);
|
||||
switch (customIntField) {
|
||||
case CUSTOM_INT_1:
|
||||
this.customInt1NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_2:
|
||||
this.customInt2NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_3:
|
||||
this.customInt3NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_4:
|
||||
this.customInt4NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_5:
|
||||
this.customInt5NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_6:
|
||||
this.customInt6NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_7:
|
||||
this.customInt7NotWithin = values;
|
||||
break;
|
||||
case CUSTOM_INT_8:
|
||||
this.customInt8NotWithin = values;
|
||||
break;
|
||||
default:
|
||||
throw new SystemException("Unknown custom int attribute '" + customIntField + "'");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskQuery callbackStateIn(CallbackState... states) {
|
||||
this.callbackStateIn = states;
|
||||
|
@ -1956,7 +2043,7 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
return DB.isDb2(getDatabaseId()) ? LINK_TO_COUNTER_DB2 : LINK_TO_COUNTER;
|
||||
}
|
||||
|
||||
private void validateAllIntervals(TimeInterval[] intervals) {
|
||||
private void validateAllTimeIntervals(TimeInterval[] intervals) {
|
||||
for (TimeInterval ti : intervals) {
|
||||
if (!ti.isValid()) {
|
||||
throw new IllegalArgumentException("TimeInterval " + ti + " is invalid.");
|
||||
|
@ -1964,6 +2051,14 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateAllIntIntervals(IntInterval[] intervals) {
|
||||
for (IntInterval ti : intervals) {
|
||||
if (!ti.isValid()) {
|
||||
throw new IllegalArgumentException("IntInterval " + ti + " is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForIllegalParamCombinations() {
|
||||
if (wildcardSearchValueLike != null ^ wildcardSearchFieldIn != null) {
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -2522,38 +2617,66 @@ public class TaskQueryImpl implements TaskQuery {
|
|||
+ Arrays.toString(customInt1In)
|
||||
+ ", customInt1NotIn="
|
||||
+ Arrays.toString(customInt1NotIn)
|
||||
+ ", customInt1Within="
|
||||
+ Arrays.toString(customInt1Within)
|
||||
+ ", customInt1NotWithin="
|
||||
+ Arrays.toString(customInt1NotWithin)
|
||||
+ ", customInt2In="
|
||||
+ Arrays.toString(customInt2In)
|
||||
+ ", customInt2NotIn="
|
||||
+ Arrays.toString(customInt2NotIn)
|
||||
+ ", customInt2Within="
|
||||
+ Arrays.toString(customInt2Within)
|
||||
+ ", customInt2NotWithin="
|
||||
+ Arrays.toString(customInt2NotWithin)
|
||||
+ ", customInt3In="
|
||||
+ Arrays.toString(customInt3In)
|
||||
+ ", customInt3NotIn="
|
||||
+ Arrays.toString(customInt3NotIn)
|
||||
+ ", customInt3Within="
|
||||
+ Arrays.toString(customInt3Within)
|
||||
+ ", customInt3NotWithin="
|
||||
+ Arrays.toString(customInt3NotWithin)
|
||||
+ ", customInt4In="
|
||||
+ Arrays.toString(customInt4In)
|
||||
+ ", customInt4NotIn="
|
||||
+ Arrays.toString(customInt4NotIn)
|
||||
+ ", customInt4Within="
|
||||
+ Arrays.toString(customInt4Within)
|
||||
+ ", customInt4NotWithin="
|
||||
+ Arrays.toString(customInt4NotWithin)
|
||||
+ ", customInt5In="
|
||||
+ Arrays.toString(customInt5In)
|
||||
+ ", customInt5NotIn="
|
||||
+ Arrays.toString(customInt5NotIn)
|
||||
+ ", customInt5Within="
|
||||
+ Arrays.toString(customInt5Within)
|
||||
+ ", customInt5NotWithin="
|
||||
+ Arrays.toString(customInt5NotWithin)
|
||||
+ ", customInt6In="
|
||||
+ Arrays.toString(customInt6In)
|
||||
+ ", customInt6NotIn="
|
||||
+ Arrays.toString(customInt6NotIn)
|
||||
+ ", customInt6Within="
|
||||
+ Arrays.toString(customInt6Within)
|
||||
+ ", customInt6NotWithin="
|
||||
+ Arrays.toString(customInt6NotWithin)
|
||||
+ ", customInt7In="
|
||||
+ Arrays.toString(customInt7In)
|
||||
+ ", customInt7NotIn="
|
||||
+ Arrays.toString(custom7NotIn)
|
||||
+ ", custom7Like="
|
||||
+ Arrays.toString(custom7Like)
|
||||
+ ", custom7NotLike="
|
||||
+ Arrays.toString(custom7NotLike)
|
||||
+ ", custom8In="
|
||||
+ Arrays.toString(custom8In)
|
||||
+ ", custom8NotIn="
|
||||
+ Arrays.toString(custom8NotIn)
|
||||
+ Arrays.toString(customInt7NotIn)
|
||||
+ ", customInt7Within="
|
||||
+ Arrays.toString(customInt7Within)
|
||||
+ ", customInt7NotWithin="
|
||||
+ Arrays.toString(customInt7NotWithin)
|
||||
+ ", customInt8In="
|
||||
+ Arrays.toString(customInt8In)
|
||||
+ ", customInt8NotIn="
|
||||
+ Arrays.toString(customInt8NotIn)
|
||||
+ ", customInt8Within="
|
||||
+ Arrays.toString(customInt8Within)
|
||||
+ ", customInt8NotWithin="
|
||||
+ Arrays.toString(customInt8NotWithin)
|
||||
+ ", callbackStateIn="
|
||||
+ Arrays.toString(callbackStateIn)
|
||||
+ ", callbackStateNotIn="
|
||||
|
|
|
@ -8,15 +8,14 @@ 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.whereInTime;
|
||||
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.whereNotInTime;
|
||||
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 {
|
||||
|
@ -422,22 +421,22 @@ public class TaskQuerySqlProvider {
|
|||
whereLike("noteLike", "t.NOTE", sb);
|
||||
whereNotLike("noteNotLike", "t.NOTE", sb);
|
||||
|
||||
whereInTime("attachmentReceivedWithin", "a.RECEIVED", sb);
|
||||
whereNotInTime("attachmentReceivedNotWithin", "a.RECEIVED", sb);
|
||||
whereInTime("claimedWithin", "t.CLAIMED", sb);
|
||||
whereNotInTime("claimedNotWithin", "t.CLAIMED", sb);
|
||||
whereInTime("completedWithin", "t.COMPLETED", sb);
|
||||
whereNotInTime("completedNotWithin", "t.COMPLETED", sb);
|
||||
whereInTime("createdWithin", "t.CREATED", sb);
|
||||
whereNotInTime("createdNotWithin", "t.CREATED", sb);
|
||||
whereInTime("dueWithin", "t.DUE", sb);
|
||||
whereNotInTime("dueNotWithin", "t.DUE", sb);
|
||||
whereInTime("modifiedWithin", "t.MODIFIED", sb);
|
||||
whereNotInTime("modifiedNotWithin", "t.MODIFIED", sb);
|
||||
whereInTime("plannedWithin", "t.PLANNED", sb);
|
||||
whereNotInTime("plannedNotWithin", "t.PLANNED", sb);
|
||||
whereInTime("receivedWithin", "t.RECEIVED", sb);
|
||||
whereNotInTime("receivedNotWithin", "t.RECEIVED", 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);
|
||||
|
||||
whereLike("ownerLongNameLike", "u.LONG_NAME", sb);
|
||||
whereNotLike("ownerLongNameNotLike", "u.LONG_NAME", sb);
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import pro.taskana.common.api.IntInterval;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
|
||||
public interface QueryParameter<E, R> {
|
||||
|
@ -27,4 +28,16 @@ public interface QueryParameter<E, R> {
|
|||
|
||||
return timeIntervalsList.toArray(new TimeInterval[0]);
|
||||
}
|
||||
|
||||
default IntInterval[] extractIntIntervals(Integer[] boundaries) {
|
||||
List<IntInterval> intervalsList = new ArrayList<>();
|
||||
for (int i = 0; i < boundaries.length - 1; i += 2) {
|
||||
Integer left = boundaries[i];
|
||||
Integer right = boundaries[i + 1];
|
||||
if (left != null || right != null) {
|
||||
intervalsList.add(new IntInterval(left, right));
|
||||
}
|
||||
}
|
||||
return intervalsList.toArray(new IntInterval[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
import java.beans.ConstructorProperties;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -1493,6 +1494,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt2 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-2")
|
||||
private final Integer[] customInt2In;
|
||||
|
@ -1500,6 +1507,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt3 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-3")
|
||||
private final Integer[] customInt3In;
|
||||
|
@ -1507,6 +1520,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt4 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-4")
|
||||
private final Integer[] customInt4In;
|
||||
|
@ -1514,6 +1533,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt5 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-5")
|
||||
private final Integer[] customInt5In;
|
||||
|
@ -1521,6 +1546,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt6 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-6")
|
||||
private final Integer[] customInt6In;
|
||||
|
@ -1528,6 +1559,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt7 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-7")
|
||||
private final Integer[] customInt7In;
|
||||
|
@ -1535,6 +1572,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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 the value of the field customInt8 of the Task. This is an exact match. */
|
||||
@JsonProperty("custom-int-8")
|
||||
private final Integer[] customInt8In;
|
||||
|
@ -1542,6 +1585,12 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
/** 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;
|
||||
// endregion
|
||||
// region callbackState
|
||||
/** Filter by the callback state of the Task. This is an exact match. */
|
||||
|
@ -1779,20 +1828,36 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
"custom-16-not-like",
|
||||
"custom-int-1",
|
||||
"custom-int-1-not",
|
||||
"custom-int-1-within",
|
||||
"custom-int-1-not-within",
|
||||
"custom-int-2",
|
||||
"custom-int-2-not",
|
||||
"custom-int-2-within",
|
||||
"custom-int-2-not-within",
|
||||
"custom-int-3",
|
||||
"custom-int-3-not",
|
||||
"custom-int-3-within",
|
||||
"custom-int-3-not-within",
|
||||
"custom-int-4",
|
||||
"custom-int-4-not",
|
||||
"custom-int-4-within",
|
||||
"custom-int-4-not-within",
|
||||
"custom-int-5",
|
||||
"custom-int-5-not",
|
||||
"custom-int-5-within",
|
||||
"custom-int-5-not-within",
|
||||
"custom-int-6",
|
||||
"custom-int-6-not",
|
||||
"custom-int-6-within",
|
||||
"custom-int-6-not-within",
|
||||
"custom-int-7",
|
||||
"custom-int-7-not",
|
||||
"custom-int-7-within",
|
||||
"custom-int-7-not-within",
|
||||
"custom-int-8",
|
||||
"custom-int-8-not",
|
||||
"custom-int-8-within",
|
||||
"custom-int-8-not-within",
|
||||
"callback-state",
|
||||
"callback-state-not",
|
||||
"wildcard-search-fields",
|
||||
|
@ -2005,20 +2070,36 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
String[] custom16NotLike,
|
||||
Integer[] customInt1In,
|
||||
Integer[] customInt1NotIn,
|
||||
Integer[] customInt1Within,
|
||||
Integer[] customInt1NotWithin,
|
||||
Integer[] customInt2In,
|
||||
Integer[] customInt2NotIn,
|
||||
Integer[] customInt2Within,
|
||||
Integer[] customInt2NotWithin,
|
||||
Integer[] customInt3In,
|
||||
Integer[] customInt3NotIn,
|
||||
Integer[] customInt3Within,
|
||||
Integer[] customInt3NotWithin,
|
||||
Integer[] customInt4In,
|
||||
Integer[] customInt4NotIn,
|
||||
Integer[] customInt4Within,
|
||||
Integer[] customInt4NotWithin,
|
||||
Integer[] customInt5In,
|
||||
Integer[] customInt5NotIn,
|
||||
Integer[] customInt5Within,
|
||||
Integer[] customInt5NotWithin,
|
||||
Integer[] customInt6In,
|
||||
Integer[] customInt6NotIn,
|
||||
Integer[] customInt6Within,
|
||||
Integer[] customInt6NotWithin,
|
||||
Integer[] customInt7In,
|
||||
Integer[] customInt7NotIn,
|
||||
Integer[] customInt7Within,
|
||||
Integer[] customInt7NotWithin,
|
||||
Integer[] customInt8In,
|
||||
Integer[] customInt8NotIn,
|
||||
Integer[] customInt8Within,
|
||||
Integer[] customInt8NotWithin,
|
||||
CallbackState[] callbackStateIn,
|
||||
CallbackState[] callbackStateNotIn,
|
||||
WildcardSearchField[] wildcardSearchFieldIn,
|
||||
|
@ -2230,20 +2311,36 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
this.custom16NotLike = custom16NotLike;
|
||||
this.customInt1In = customInt1In;
|
||||
this.customInt1NotIn = customInt1NotIn;
|
||||
this.customInt1Within = customInt1Within;
|
||||
this.customInt1NotWithin = customInt1NotWithin;
|
||||
this.customInt2In = customInt2In;
|
||||
this.customInt2NotIn = customInt2NotIn;
|
||||
this.customInt2Within = customInt2Within;
|
||||
this.customInt2NotWithin = customInt2NotWithin;
|
||||
this.customInt3In = customInt3In;
|
||||
this.customInt3NotIn = customInt3NotIn;
|
||||
this.customInt3Within = customInt3Within;
|
||||
this.customInt3NotWithin = customInt3NotWithin;
|
||||
this.customInt4In = customInt4In;
|
||||
this.customInt4NotIn = customInt4NotIn;
|
||||
this.customInt4Within = customInt4Within;
|
||||
this.customInt4NotWithin = customInt4NotWithin;
|
||||
this.customInt5In = customInt5In;
|
||||
this.customInt5NotIn = customInt5NotIn;
|
||||
this.customInt5Within = customInt5Within;
|
||||
this.customInt5NotWithin = customInt5NotWithin;
|
||||
this.customInt6In = customInt6In;
|
||||
this.customInt6NotIn = customInt6NotIn;
|
||||
this.customInt6Within = customInt6Within;
|
||||
this.customInt6NotWithin = customInt6NotWithin;
|
||||
this.customInt7In = customInt7In;
|
||||
this.customInt7NotIn = customInt7NotIn;
|
||||
this.customInt7Within = customInt7Within;
|
||||
this.customInt7NotWithin = customInt7NotWithin;
|
||||
this.customInt8In = customInt8In;
|
||||
this.customInt8NotIn = customInt8NotIn;
|
||||
this.customInt8Within = customInt8Within;
|
||||
this.customInt8NotWithin = customInt8NotWithin;
|
||||
this.callbackStateIn = callbackStateIn;
|
||||
this.callbackStateNotIn = callbackStateNotIn;
|
||||
this.wildcardSearchFieldIn = wildcardSearchFieldIn;
|
||||
|
@ -2614,20 +2711,42 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
});
|
||||
|
||||
Stream.of(
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_1, Pair.of(customInt1In, customInt1NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_2, Pair.of(customInt2In, customInt2NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_3, Pair.of(customInt3In, customInt3NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_4, Pair.of(customInt4In, customInt4NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_5, Pair.of(customInt5In, customInt5NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_6, Pair.of(customInt6In, customInt6NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_7, Pair.of(customInt7In, customInt7NotIn)),
|
||||
Pair.of(TaskCustomIntField.CUSTOM_INT_8, Pair.of(customInt8In, customInt8NotIn)))
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_1,
|
||||
of(customInt1In, customInt1NotIn, customInt1Within, customInt1NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_2,
|
||||
of(customInt2In, customInt2NotIn, customInt2Within, customInt2NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_3,
|
||||
of(customInt3In, customInt3NotIn, customInt3Within, customInt3NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_4,
|
||||
of(customInt4In, customInt4NotIn, customInt4Within, customInt4NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_5,
|
||||
of(customInt5In, customInt5NotIn, customInt5Within, customInt5NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_6,
|
||||
of(customInt6In, customInt6NotIn, customInt6Within, customInt6NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_7,
|
||||
of(customInt7In, customInt7NotIn, customInt7Within, customInt7NotWithin)),
|
||||
Pair.of(
|
||||
TaskCustomIntField.CUSTOM_INT_8,
|
||||
of(customInt8In, customInt8NotIn, customInt8Within, customInt8NotWithin)))
|
||||
.forEach(
|
||||
pair -> {
|
||||
Optional.ofNullable(pair.getRight().getLeft())
|
||||
Optional.ofNullable(pair.getRight().getFirst())
|
||||
.ifPresent(wrap(l -> query.customIntAttributeIn(pair.getLeft(), l)));
|
||||
Optional.ofNullable(pair.getRight().getRight())
|
||||
Optional.ofNullable(pair.getRight().getSecond())
|
||||
.ifPresent(wrap(l -> query.customIntAttributeNotIn(pair.getLeft(), l)));
|
||||
Optional.ofNullable(pair.getRight().getThird())
|
||||
.map(this::extractIntIntervals)
|
||||
.ifPresent(wrap(l -> query.customIntAttributeWithin(pair.getLeft(), l)));
|
||||
Optional.ofNullable(pair.getRight().getFourth())
|
||||
.map(this::extractIntIntervals)
|
||||
.ifPresent(wrap(l -> query.customIntAttributeNotWithin(pair.getLeft(), l)));
|
||||
});
|
||||
|
||||
Optional.ofNullable(callbackStateIn).ifPresent(query::callbackStateIn);
|
||||
|
@ -2795,9 +2914,202 @@ public class TaskQueryFilterParameter implements QueryParameter<TaskQuery, Void>
|
|||
"provided length of the property 'claimed-not-in' is not dividable by 2");
|
||||
}
|
||||
|
||||
if (attachmentReceivedNotWithin != null && attachmentReceivedNotWithin.length % 2 != 0) {
|
||||
if (customInt1Within != null && customInt1Within.length % 2 != 0) {
|
||||
throw new InvalidArgumentException(
|
||||
"provided length of the property 'attachment-not-received' is not dividable by 2");
|
||||
"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 (withoutAttachment != null && !withoutAttachment) {
|
||||
|
|
|
@ -206,6 +206,73 @@ class TaskControllerIntTest {
|
|||
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest>
|
||||
should_ThrowException_For_SpecifiedWorkbasketIdAndCustomIntFieldWithinIncorrectInterval() {
|
||||
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-within=%s"
|
||||
+ "&custom-int-%s-within=23"
|
||||
+ "&custom-int-%s-within=15",
|
||||
i, i, i, i);
|
||||
HttpEntity<Object> auth =
|
||||
new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpStatusCodeException.class)
|
||||
.hasMessageContaining(
|
||||
"provided length of the property 'custom-int-"
|
||||
+ i
|
||||
+ "-within' is not dividable by 2")
|
||||
.extracting(HttpStatusCodeException.class::cast)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest>
|
||||
should_ThrowException_For_SpecifiedWorkbasketIdAndCustomIntFieldWithinNullInterval() {
|
||||
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-within="
|
||||
+ "&custom-int-%s-within=",
|
||||
i, i, i);
|
||||
HttpEntity<Object> auth =
|
||||
new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpStatusCodeException.class)
|
||||
.hasMessageContaining(
|
||||
"Each interval in 'custom-int-"
|
||||
+ i
|
||||
+ "-within' shouldn't consist of two 'null' values")
|
||||
.extracting(HttpStatusCodeException.class::cast)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(customIntValues.iterator(), c -> "customInt" + c, test);
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_GetAllTasks_For_SpecifiedWorkbasketIdAndCustomIntFieldWithin() {
|
||||
List<Integer> customIntValues = List.of(1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
|
Loading…
Reference in New Issue