View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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      // todo: use lambda
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     // todo: use lambda
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     // todo: use lambda
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 }