This repository has been archived by the owner on Dec 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InMemoryItemsQueryService.java
123 lines (100 loc) · 3.95 KB
/
InMemoryItemsQueryService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package de.chrgroth.generictypesystem.persistence.query.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.chrgroth.generictypesystem.model.GenericItem;
import de.chrgroth.generictypesystem.persistence.query.ItemFilterData;
import de.chrgroth.generictypesystem.persistence.query.ItemPagingData;
import de.chrgroth.generictypesystem.persistence.query.ItemQueryResult;
import de.chrgroth.generictypesystem.persistence.query.ItemSortData;
/**
* A naive filter, sort and paging implementation independent from persistence layer.
*
* @author Christian Groth
*/
public class InMemoryItemsQueryService {
private static final Logger LOG = LoggerFactory.getLogger(InMemoryItemsQueryService.class);
private final long defaultPageSize;
public InMemoryItemsQueryService(long defaultPageSize) {
if (defaultPageSize < 1) {
throw new IllegalArgumentException("default page size must be greater zero!!");
}
this.defaultPageSize = defaultPageSize;
}
/**
* Executes the given filter, sorts and paging operation based on given items.
*
* @param allItems
* items to be processed
* @param filter
* filter operations, or null
* @param sorts
* sorting operation, or null
* @param paging
* paging operation, or null
* @return result, never null
*/
public ItemQueryResult query(Set<GenericItem> allItems, ItemFilterData filter, List<ItemSortData> sorts, ItemPagingData paging) {
// get items
if (allItems == null || allItems.isEmpty()) {
return new ItemQueryResult(Collections.emptyList(), false);
}
// add all
List<GenericItem> items = new ArrayList<>(allItems);
// filter
if (filter != null) {
// TODO implement filtering
LOG.warn("filtering not implemented yet!!");
}
// sorting
Collections.sort(items, new CascadingAttributeComparator(sorts));
if (LOG.isDebugEnabled()) {
LOG.debug("sorted items " + items);
}
// paging
boolean moreAvailable;
if (paging != null) {
// validate paging parameters
long page = paging.getPage();
if (page < 0) {
LOG.error("illegal page number: " + page + "!! Setting page to 0.");
page = 0;
}
Long pageSize = paging.getPageSize();
if (pageSize == null || pageSize.longValue() < 1) {
LOG.error("illegal page size: " + pageSize + "!! Falling back to configured default: " + defaultPageSize + ".");
pageSize = defaultPageSize;
}
// compute beginning
long firstIdx = 0;
if (page > 0) {
firstIdx = pageSize.longValue() * (page - 1);
}
// compute end
long lastIdx = firstIdx + pageSize.longValue();
// slice
if (LOG.isDebugEnabled()) {
LOG.debug("slicing items to [" + firstIdx + "," + lastIdx + ")");
}
if (items.size() >= firstIdx + 1) {
// compute if more than the actual page is available
moreAvailable = items.size() > lastIdx;
// slive to actual page
items = items.subList((int) firstIdx, items.size() > lastIdx ? (int) lastIdx : items.size());
} else {
// return empty result
LOG.error("query page is out of bounds: " + page + "x" + pageSize + "!!");
moreAvailable = false;
items.clear();
}
} else {
// no paging - all items served, nothing more available
moreAvailable = false;
}
// done
return new ItemQueryResult(items, moreAvailable);
}
}