-
Notifications
You must be signed in to change notification settings - Fork 7
/
CodeListLookupTable.java
168 lines (140 loc) · 6.37 KB
/
CodeListLookupTable.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - [email protected]
*/
package sirius.biz.codelists;
import sirius.kernel.cache.Cache;
import sirius.kernel.cache.CacheManager;
import sirius.kernel.commons.Limit;
import sirius.kernel.commons.Strings;
import sirius.kernel.commons.Value;
import sirius.kernel.di.std.Part;
import sirius.kernel.nls.NLS;
import sirius.kernel.settings.Extension;
import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.stream.Stream;
/**
* Provides an implementation for {@link LookupTable} based on {@link CodeLists}.
*/
class CodeListLookupTable extends LookupTable {
@Part
private static CodeLists<?, ?, ?> codeLists;
private static final Cache<String, String> REVERSE_LOOKUP_CACHE =
CacheManager.createCoherentCache("codelists-reverse-lookup");
private final String codeList;
CodeListLookupTable(Extension extension, String codeList) {
super(extension);
this.codeList = codeList;
}
@Override
protected boolean performContains(@Nonnull String code) {
return codeLists.hasValue(codeList, code);
}
@Override
protected Optional<String> performResolveName(String code, String language) {
return Optional.ofNullable(codeLists.getTranslatedValue(codeList, code, language));
}
@Override
protected Optional<String> performResolveDescription(@Nonnull String code, String language) {
// Descriptions are not supported by code lists...
return Optional.empty();
}
@Override
protected Value performFetchField(String code, String targetField) {
return Value.of(codeLists.getValues(codeList, code).getSecond());
}
@Override
protected Optional<String> performFetchTranslatedField(String code, String targetField, String language) {
return Optional.ofNullable(codeLists.getTranslatedValues(codeList, code, language).getSecond());
}
@Override
protected Optional<String> performNormalize(String code) {
if (codeLists.hasValue(codeList, code)) {
return Optional.of(code);
} else {
return Optional.empty();
}
}
@Override
protected Optional<String> performNormalizeWithMapping(@Nonnull String code, String mapping) {
// This isn't supported by code lists...
return Optional.empty();
}
/**
* Flushes the internal cache which is used for reverse (value to code) lookups.
*/
public static void flushReverseLookupCache() {
REVERSE_LOOKUP_CACHE.clear();
}
@Override
protected Optional<String> performReverseLookup(String name) {
return Optional.ofNullable(REVERSE_LOOKUP_CACHE.get(codeList + "-" + fetchCodeListTenantId() + "-" + name,
ignored -> performReverseLookupScan(name)));
}
private String fetchCodeListTenantId() {
return codeLists.getRequiredTenant(codeList).getIdAsString();
}
private String performReverseLookupScan(String name) {
return scan(NLS.getCurrentLanguage(), Limit.UNLIMITED, true).filter(pair -> Strings.equalIgnoreCase(name,
pair.getName()))
.findFirst()
.map(LookupTableEntry::getCode)
.orElse(null);
}
@Override
protected <T> Optional<T> performFetchObject(Class<T> type, String code, boolean useCache) {
return Optional.empty();
}
@Override
protected Stream<LookupTableEntry> performSuggest(Limit limit,
String searchTerm,
String language,
boolean considerDeprecatedValues) {
return codeLists.getEntries(codeList)
.stream()
.filter(entry -> filter(entry, searchTerm, language))
.map(entry -> extractEntryData(entry, language))
.skip(limit.getItemsToSkip())
.limit(limit.getMaxItems() == 0 ? Long.MAX_VALUE : limit.getMaxItems());
}
@Override
protected Stream<LookupTableEntry> performSearch(String searchTerm, Limit limit, String language) {
// Plain code lists do not support deprecations or source data. Therefore, the suggest method can be reused.
return performSuggest(limit, searchTerm, language, true);
}
private LookupTableEntry extractEntryData(CodeListEntry<?, ?> entry, String language) {
return new LookupTableEntry(entry.getCodeListEntryData().getCode(),
entry.getCodeListEntryData().getTranslatedValue(language),
entry.getCodeListEntryData().getDescription());
}
private boolean filter(CodeListEntry<?, ?> entry, String searchTerm, String language) {
if (Strings.isEmpty(searchTerm)) {
return true;
}
String effectiveSearchTerm = searchTerm.toLowerCase();
return Value.of(entry.getCodeListEntryData().getCode()).toLowerCase().contains(effectiveSearchTerm) || Value.of(
entry.getCodeListEntryData().getTranslatedValue(language)).toLowerCase().contains(effectiveSearchTerm);
}
@Override
public Stream<LookupTableEntry> scan(String language, Limit limit, boolean considerDeprecatedValues) {
return codeLists.getEntries(codeList)
.stream()
.skip(limit.getItemsToSkip())
.limit(limit.getMaxItems() == 0 ? Long.MAX_VALUE : limit.getMaxItems())
.map(entry -> extractEntryData(entry, language));
}
@Override
protected Stream<LookupTableEntry> performQuery(String language, String lookupPath, String lookupValue) {
// This would need a complex caching strategy as always fetching the DB would be too expensive.
// Could be implemented when needed.
throw new UnsupportedOperationException();
}
@Override
public int count() {
return codeLists.getEntries(codeList).size();
}
}