Skip to content

Commit b01e5c3

Browse files
committed
TSK-989 Filter Tasks by planned TimeIntervals (REST)
-Added planned, planned-from and planned-until params in filter list -Added due, due-from and due-until params in filter list -Implemented needed methods -Added Test -Updated rest-api.doc -Refactored TaskControllerIntTests to use AssertJ
1 parent 99e2caa commit b01e5c3

File tree

3 files changed

+493
-106
lines changed

3 files changed

+493
-106
lines changed

rest/taskana-rest-spring/src/main/java/pro/taskana/rest/TaskController.java

Lines changed: 193 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package pro.taskana.rest;
22

3+
import java.time.Instant;
34
import java.util.ArrayList;
45
import java.util.List;
56
import org.slf4j.Logger;
@@ -27,6 +28,7 @@
2728
import pro.taskana.TaskService;
2829
import pro.taskana.TaskState;
2930
import pro.taskana.TaskSummary;
31+
import pro.taskana.TimeInterval;
3032
import pro.taskana.exceptions.AttachmentPersistenceException;
3133
import pro.taskana.exceptions.ClassificationNotFoundException;
3234
import pro.taskana.exceptions.ConcurrencyException;
@@ -70,11 +72,17 @@ public class TaskController extends AbstractPagingController {
7072
private static final String POR_SYSTEM = "por.system";
7173
private static final String POR_COMPANY = "por.company";
7274
private static final String DUE = "due";
75+
private static final String DUE_TO = "due-until";
76+
private static final String DUE_FROM = "due-from";
7377
private static final String PLANNED = "planned";
78+
private static final String PLANNED_TO = "planned-until";
79+
private static final String PLANNED_FROM = "planned-from";
7480

7581
private static final String SORT_BY = "sort-by";
7682
private static final String SORT_DIRECTION = "order";
7783

84+
private static final String INDEFINITE = "";
85+
7886
private TaskService taskService;
7987

8088
private TaskResourceAssembler taskResourceAssembler;
@@ -248,6 +256,8 @@ private TaskQuery applyFilterParams(TaskQuery taskQuery, MultiValueMap<String, S
248256
LOGGER.debug("Entry to applyFilterParams(taskQuery= {}, params= {})", taskQuery, params);
249257
}
250258

259+
checkForIllegalParamCombinations(params);
260+
251261
// apply filters
252262
if (params.containsKey(NAME)) {
253263
String[] names = extractCommaSeparatedFields(params.get(NAME));
@@ -280,22 +290,7 @@ private TaskQuery applyFilterParams(TaskQuery taskQuery, MultiValueMap<String, S
280290
params.remove(WORKBASKET_ID);
281291
}
282292
if (params.containsKey(WORKBASKET_KEY)) {
283-
String[] domains = null;
284-
if (params.get(DOMAIN) != null) {
285-
domains = extractCommaSeparatedFields(params.get(DOMAIN));
286-
}
287-
if (domains == null || domains.length != 1) {
288-
throw new InvalidArgumentException(
289-
"workbasket-key requires excactly one domain as second parameter.");
290-
}
291-
String[] workbasketKeys = extractCommaSeparatedFields(params.get(WORKBASKET_KEY));
292-
KeyDomain[] keyDomains = new KeyDomain[workbasketKeys.length];
293-
for (int i = 0; i < workbasketKeys.length; i++) {
294-
keyDomains[i] = new KeyDomain(workbasketKeys[i], domains[0]);
295-
}
296-
taskQuery.workbasketKeyDomainIn(keyDomains);
297-
params.remove(WORKBASKET_KEY);
298-
params.remove(DOMAIN);
293+
updateTaskQueryWithWorkbasketKey(taskQuery,params);
299294
}
300295
if (params.containsKey(OWNER)) {
301296
String[] owners = extractCommaSeparatedFields(params.get(OWNER));
@@ -330,13 +325,195 @@ private TaskQuery applyFilterParams(TaskQuery taskQuery, MultiValueMap<String, S
330325
params.remove(POR_VALUE);
331326
}
332327

328+
if (params.containsKey(PLANNED)) {
329+
updateTaskQueryWithPlannedOrDueTimeIntervals(taskQuery, params, PLANNED);
330+
}
331+
332+
if (params.containsKey(DUE)) {
333+
updateTaskQueryWithPlannedOrDueTimeIntervals(taskQuery, params, DUE);
334+
}
335+
336+
if (params.containsKey(PLANNED_FROM) && params.containsKey(PLANNED_TO)) {
337+
updateTaskQueryWithPlannedOrDueTimeInterval(taskQuery, params, PLANNED_FROM, PLANNED_TO);
338+
339+
} else if (params.containsKey(PLANNED_FROM) && !params.containsKey(PLANNED_TO)) {
340+
341+
TimeInterval timeInterval = createIndefiniteTimeIntervalFromParam(params, PLANNED_FROM);
342+
updateTaskQueryWithIndefiniteTimeInterval(taskQuery, params, PLANNED_FROM, timeInterval);
343+
344+
} else if (!params.containsKey(PLANNED_FROM) && params.containsKey(PLANNED_TO)) {
345+
346+
TimeInterval timeInterval = createIndefiniteTimeIntervalFromParam(params, PLANNED_TO);
347+
updateTaskQueryWithIndefiniteTimeInterval(taskQuery, params, PLANNED_TO, timeInterval);
348+
}
349+
350+
if (params.containsKey(DUE_FROM) && params.containsKey(DUE_TO)) {
351+
updateTaskQueryWithPlannedOrDueTimeInterval(taskQuery, params, DUE_FROM, DUE_TO);
352+
353+
} else if (params.containsKey(DUE_FROM) && !params.containsKey(DUE_TO)) {
354+
355+
TimeInterval indefiniteTimeInterval = createIndefiniteTimeIntervalFromParam(params, DUE_FROM);
356+
updateTaskQueryWithIndefiniteTimeInterval(
357+
taskQuery, params, DUE_FROM, indefiniteTimeInterval);
358+
359+
} else if (!params.containsKey(DUE_FROM) && params.containsKey(DUE_TO)) {
360+
361+
TimeInterval timeInterval = createIndefiniteTimeIntervalFromParam(params, DUE_TO);
362+
updateTaskQueryWithIndefiniteTimeInterval(taskQuery, params, DUE_TO, timeInterval);
363+
}
364+
333365
if (LOGGER.isDebugEnabled()) {
334366
LOGGER.debug("Exit from applyFilterParams(), returning {}", taskQuery);
335367
}
336368

337369
return taskQuery;
338370
}
339371

372+
private void updateTaskQueryWithWorkbasketKey(TaskQuery taskQuery,
373+
MultiValueMap<String, String> params)
374+
throws InvalidArgumentException {
375+
376+
String[] domains = null;
377+
if (params.get(DOMAIN) != null) {
378+
domains = extractCommaSeparatedFields(params.get(DOMAIN));
379+
}
380+
if (domains == null || domains.length != 1) {
381+
throw new InvalidArgumentException(
382+
"workbasket-key requires excactly one domain as second parameter.");
383+
}
384+
String[] workbasketKeys = extractCommaSeparatedFields(params.get(WORKBASKET_KEY));
385+
KeyDomain[] keyDomains = new KeyDomain[workbasketKeys.length];
386+
for (int i = 0; i < workbasketKeys.length; i++) {
387+
keyDomains[i] = new KeyDomain(workbasketKeys[i], domains[0]);
388+
}
389+
taskQuery.workbasketKeyDomainIn(keyDomains);
390+
params.remove(WORKBASKET_KEY);
391+
params.remove(DOMAIN);
392+
393+
}
394+
395+
private void checkForIllegalParamCombinations(MultiValueMap<String, String> params) {
396+
397+
if (params.containsKey(PLANNED)
398+
&& (params.containsKey(PLANNED_FROM) || params.containsKey(PLANNED_TO))) {
399+
400+
throw new IllegalArgumentException(
401+
"It is prohibited to use the param \""
402+
+ PLANNED
403+
+ "\" in combination with the params \""
404+
+ PLANNED_FROM
405+
+ "\" and / or \""
406+
+ PLANNED_TO
407+
+ "\"");
408+
}
409+
410+
if (params.containsKey(DUE) && (params.containsKey(DUE_FROM) || params.containsKey(DUE_TO))) {
411+
412+
throw new IllegalArgumentException(
413+
"It is prohibited to use the param \""
414+
+ DUE
415+
+ "\" in combination with the params \""
416+
+ PLANNED_FROM
417+
+ "\" and / or \""
418+
+ PLANNED_TO
419+
+ "\"");
420+
}
421+
}
422+
423+
private void updateTaskQueryWithIndefiniteTimeInterval(
424+
TaskQuery taskQuery,
425+
MultiValueMap<String, String> params,
426+
String param,
427+
TimeInterval timeInterval) {
428+
429+
if (param.equals(PLANNED_FROM) || param.equals(PLANNED_TO)) {
430+
taskQuery.plannedWithin(timeInterval);
431+
432+
} else {
433+
taskQuery.dueWithin(timeInterval);
434+
}
435+
params.remove(param);
436+
}
437+
438+
private TimeInterval createIndefiniteTimeIntervalFromParam(
439+
MultiValueMap<String, String> params, String param) {
440+
441+
if (param.equals(PLANNED_FROM) || param.equals(DUE_FROM)) {
442+
443+
return new TimeInterval(Instant.parse(params.get(param).get(0)), null);
444+
445+
} else {
446+
447+
return new TimeInterval(null, Instant.parse(params.get(param).get(0)));
448+
}
449+
}
450+
451+
private void updateTaskQueryWithPlannedOrDueTimeInterval(
452+
TaskQuery taskQuery,
453+
MultiValueMap<String, String> params,
454+
String plannedFromOrDueFrom,
455+
String plannedToOrDueTo) {
456+
457+
TimeInterval timeInterval =
458+
new TimeInterval(
459+
Instant.parse(params.get(plannedFromOrDueFrom).get(0)),
460+
Instant.parse(params.get(plannedToOrDueTo).get(0)));
461+
462+
taskQuery.plannedWithin(timeInterval);
463+
464+
params.remove(plannedToOrDueTo);
465+
params.remove(plannedFromOrDueFrom);
466+
}
467+
468+
private void updateTaskQueryWithPlannedOrDueTimeIntervals(
469+
TaskQuery taskQuery, MultiValueMap<String, String> params, String plannedOrDue) {
470+
471+
String[] instants = extractCommaSeparatedFields(params.get(plannedOrDue));
472+
473+
TimeInterval[] timeIntervals = extractTimeIntervals(instants);
474+
475+
taskQuery.plannedWithin(timeIntervals);
476+
477+
params.remove(plannedOrDue);
478+
}
479+
480+
private TimeInterval[] extractTimeIntervals(String[] instants) {
481+
482+
List<TimeInterval> timeIntervalsList = new ArrayList<>();
483+
484+
for (int i = 0; i < instants.length - 1; i += 2) {
485+
486+
TimeInterval timeInterval = determineTimeInterval(instants, i);
487+
488+
if (timeInterval != null) {
489+
490+
timeIntervalsList.add(timeInterval);
491+
}
492+
}
493+
494+
TimeInterval[] timeIntervalArray = new TimeInterval[timeIntervalsList.size()];
495+
496+
return timeIntervalsList.toArray(timeIntervalArray);
497+
}
498+
499+
private TimeInterval determineTimeInterval(String[] instants, int i) {
500+
501+
if (!instants[i].equals(INDEFINITE) && !instants[i + 1].equals(INDEFINITE)) {
502+
503+
return new TimeInterval(Instant.parse(instants[i]), Instant.parse(instants[i + 1]));
504+
505+
} else if (instants[i].equals(INDEFINITE) && !instants[i + 1].equals(INDEFINITE)) {
506+
507+
return new TimeInterval(null, Instant.parse(instants[i + 1]));
508+
509+
} else if (!instants[i].equals(INDEFINITE) && instants[i + 1].equals(INDEFINITE)) {
510+
511+
return new TimeInterval(Instant.parse(instants[i]), null);
512+
}
513+
514+
return null;
515+
}
516+
340517
private TaskQuery applySortingParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
341518
throws InvalidArgumentException {
342519
if (LOGGER.isDebugEnabled()) {

0 commit comments

Comments
 (0)