1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.example.demo;
21
22 import org.apache.commons.lang3.StringUtils;
23 import org.apache.myfaces.tobago.model.SelectItem;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import javax.annotation.PostConstruct;
28 import javax.enterprise.context.SessionScoped;
29 import javax.faces.component.UIComponent;
30 import javax.faces.context.FacesContext;
31 import javax.faces.convert.Converter;
32 import javax.faces.convert.ConverterException;
33 import javax.faces.event.AjaxBehaviorEvent;
34 import javax.inject.Inject;
35 import javax.inject.Named;
36 import java.io.Serializable;
37 import java.lang.invoke.MethodHandles;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Set;
41 import java.util.TreeSet;
42 import java.util.stream.Collectors;
43
44 @SessionScoped
45 @Named
46 public class SheetFilterController implements Serializable {
47
48 private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
49
50 @Inject
51 private AstroData astroData;
52
53 private List<SolarObject> filteredSolarList = new ArrayList<>();
54
55 private SelectItem[] distanceItems;
56 private SelectItem[] minYearItems;
57 private SelectItem[] maxYearItems;
58
59 private DistanceRangeConverter distanceRangeConverter;
60
61 private String name;
62 private String orbit;
63 private DistanceRange distance;
64 private String discoverer;
65 private Integer minYear;
66 private Integer maxYear;
67
68 private String nameSuggestionQuery;
69
70 @PostConstruct
71 private void init() {
72 distanceItems = new SelectItem[]{
73 new SelectItem(new DistanceRange(-1, Integer.MAX_VALUE), "any"),
74 new SelectItem(new DistanceRange(-1, 10), "≤ 10"),
75 new SelectItem(new DistanceRange(10, 100), "10 < x ≤ 100"),
76 new SelectItem(new DistanceRange(100, 1000), "100 < x ≤ 1000"),
77 new SelectItem(new DistanceRange(1000, 10000), "1000 < x ≤ 10000"),
78 new SelectItem(new DistanceRange(10000, 100000), "10000 < x ≤ 100000"),
79 new SelectItem(new DistanceRange(100000, 1000000), "100000 < x ≤ 1000000"),
80 new SelectItem(new DistanceRange(1000000, Integer.MAX_VALUE), "1000000 < x")
81 };
82
83 final Set<Integer> years = new TreeSet<>();
84
85 for (final SolarObject solarObject : astroData.findAll().collect(Collectors.toList())) {
86 if (solarObject.getDiscoverYear() != null) {
87 years.add(solarObject.getDiscoverYear());
88 }
89 }
90 minYearItems = new SelectItem[years.size() + 1];
91 maxYearItems = new SelectItem[years.size() + 1];
92 minYearItems[0] = new SelectItem(0, "min");
93 maxYearItems[0] = new SelectItem(Integer.MAX_VALUE, "max");
94 int i = 1;
95 for (final Integer year : years) {
96 final SelectItem selectItem = new SelectItem(year, String.valueOf(year));
97
98 minYearItems[i] = selectItem;
99 maxYearItems[i] = selectItem;
100
101 i++;
102 }
103
104 distanceRangeConverter = new DistanceRangeConverter();
105
106 filter();
107 }
108
109 public String filter() {
110 filteredSolarList.clear();
111 if (name == null) {
112 name = "";
113 }
114 if (orbit == null) {
115 orbit = "";
116 }
117 if (distance == null) {
118 distance = (DistanceRange) distanceItems[0].getValue();
119 }
120 if (discoverer == null) {
121 discoverer = "";
122 }
123 if (minYear == null) {
124 minYear = 0;
125 }
126 if (maxYear == null) {
127 maxYear = Integer.MAX_VALUE;
128 }
129
130 for (final SolarObject solarObject : astroData.findAll().collect(Collectors.toList())) {
131 int discoverYear = 0;
132 if (solarObject.getDiscoverYear() != null) {
133 discoverYear = solarObject.getDiscoverYear();
134 }
135 if (StringUtils.containsIgnoreCase(solarObject.getName(), name)
136 && StringUtils.containsIgnoreCase(solarObject.getOrbit(), orbit)
137 && distance.getMin() < solarObject.getDistance() && solarObject.getDistance() <= distance.getMax()
138 && StringUtils.containsIgnoreCase(solarObject.getDiscoverer(), discoverer)
139 && minYear <= discoverYear && discoverYear <= maxYear) {
140 filteredSolarList.add(solarObject);
141 }
142 }
143 return null;
144 }
145
146 public void filter(final AjaxBehaviorEvent event) {
147 filter();
148 }
149
150 public List<SolarObject> getFilteredSolarList() {
151 return filteredSolarList;
152 }
153
154 public SelectItem[] getDistanceItems() {
155 return distanceItems;
156 }
157
158 public SelectItem[] getMinYearItems() {
159 return minYearItems;
160 }
161
162 public SelectItem[] getMaxYearItems() {
163 return maxYearItems;
164 }
165
166 public DistanceRangeConverter getDistanceRangeConverter() {
167 return distanceRangeConverter;
168 }
169
170 public String getName() {
171 return name;
172 }
173
174 public void setName(final String name) {
175 this.name = name;
176 }
177
178 public String getOrbit() {
179 return orbit;
180 }
181
182 public void setOrbit(final String orbit) {
183 this.orbit = orbit;
184 }
185
186 public DistanceRange getDistance() {
187 return distance;
188 }
189
190 public void setDistance(final DistanceRange distance) {
191 this.distance = distance;
192 }
193
194 public String getDiscoverer() {
195 return discoverer;
196 }
197
198 public void setDiscoverer(final String discoverer) {
199 this.discoverer = discoverer;
200 }
201
202 public Integer getMinYear() {
203 return minYear;
204 }
205
206 public void setMinYear(final Integer minYear) {
207 this.minYear = minYear;
208 }
209
210 public Integer getMaxYear() {
211 return maxYear;
212 }
213
214 public void setMaxYear(final Integer maxYear) {
215 this.maxYear = maxYear;
216 }
217
218 public String getNameSuggestionQuery() {
219 return nameSuggestionQuery;
220 }
221
222 public void setNameSuggestionQuery(final String nameSuggestionQuery) {
223 this.nameSuggestionQuery = nameSuggestionQuery;
224 }
225
226 public List<String> getSuggestionSolarList() {
227 final String substring = nameSuggestionQuery != null ? nameSuggestionQuery : "";
228 LOG.info("Creating items for substring: '" + substring + "'");
229 final List<String> result = new ArrayList<>();
230
231 for (final SolarObject solarObject : astroData.findAll().collect(Collectors.toList())) {
232 final String solarObjectName = solarObject.getName();
233 if (StringUtils.containsIgnoreCase(solarObjectName, substring)) {
234 result.add(solarObjectName);
235 }
236 }
237 return result;
238 }
239
240 private class DistanceRange {
241
242 private int min;
243 private int max;
244 private final String label;
245
246 DistanceRange(final int min, final int max) {
247 this.min = min;
248 this.max = max;
249 label = String.valueOf(min) + " < x ≤ " + String.valueOf(max);
250 }
251
252 DistanceRange(final int min, final int max, final String label) {
253 this.min = min;
254 this.max = max;
255 this.label = label;
256 }
257
258 public int getMin() {
259 return min;
260 }
261
262 public int getMax() {
263 return max;
264 }
265
266 public String getLabel() {
267 return label;
268 }
269
270 @Override
271 public boolean equals(final Object object) {
272 if (this == object) {
273 return true;
274 }
275 if (object == null || getClass() != object.getClass()) {
276 return false;
277 }
278 final DistanceRange that = (DistanceRange) object;
279 return max == that.max && min == that.min;
280 }
281
282 @Override
283 public int hashCode() {
284 return 31 * min + max;
285 }
286 }
287
288 public class DistanceRangeConverter implements Converter {
289 @Override
290 public Object getAsObject(final FacesContext context, final UIComponent component, final String value)
291 throws ConverterException {
292 try {
293 for (final SelectItem distanceItem : distanceItems) {
294 if (distanceItem.getLabel().equals(value)) {
295 return distanceItem.getValue();
296 }
297 }
298 return distanceItems[0].getValue();
299 } catch (final RuntimeException e) {
300 LOG.warn("unknown value='" + value + "'", e);
301 return distanceItems[0].getValue();
302 }
303 }
304
305 @Override
306 public String getAsString(
307 final FacesContext context, final UIComponent component, final Object value) throws ConverterException {
308 if (value instanceof DistanceRange) {
309 for (final SelectItem distanceItem : distanceItems) {
310 if (distanceItem.getValue().equals(value)) {
311 return distanceItem.getLabel();
312 }
313 }
314 }
315 return distanceItems[0].getLabel();
316 }
317 }
318 }