source: vlo/branches/vlo-3.0/vlo-web-app/src/main/java/eu/clarin/cmdi/vlo/wicket/provider/FacetFieldValuesProvider.java @ 4666

Last change on this file since 4666 was 4666, checked in by Twan Goosen, 10 years ago

added filtering of values in all values panel

File size: 6.1 KB
Line 
1/*
2 * Copyright (C) 2014 CLARIN
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17package eu.clarin.cmdi.vlo.wicket.provider;
18
19import com.google.common.base.Predicate;
20import com.google.common.collect.ImmutableList;
21import com.google.common.collect.Iterables;
22import com.google.common.collect.Ordering;
23import eu.clarin.cmdi.vlo.pojo.FieldValuesOrder;
24import java.util.Iterator;
25import java.util.List;
26import org.apache.solr.client.solrj.response.FacetField;
27import org.apache.solr.client.solrj.response.FacetField.Count;
28import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
29import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
30import org.apache.wicket.model.IModel;
31import org.apache.wicket.model.Model;
32
33/**
34 * Provides facet values and counts (both through the {@link Count} object of
35 * SOLR) present on a {@link FacetField}, sortable by either count or name
36 *
37 * @see FieldValuesOrder
38 * @author twagoo
39 */
40public class FacetFieldValuesProvider extends SortableDataProvider<FacetField.Count, FieldValuesOrder> {
41
42    private final IModel<FacetField> model;
43    private final int maxNumberOfItems;
44
45    /**
46     * Creates a provider without a maximum number of values. Bound to
47     * {@link Integer#MAX_VALUE}.
48     *
49     * @param model FacetField model to get values and counts for
50     */
51    public FacetFieldValuesProvider(IModel<FacetField> model) {
52        this(model, Integer.MAX_VALUE);
53    }
54
55    public FacetFieldValuesProvider(IModel<FacetField> model, int max) {
56        this(model, max, new SortParam<FieldValuesOrder>(FieldValuesOrder.COUNT, false));
57    }
58
59    /**
60     * Creates a provider with a set maximum number of values
61     *
62     * @param model FacetField model to get values and counts for
63     * @param max maximum number of values to show
64     * @param sort initial sort property and order
65     */
66    public FacetFieldValuesProvider(IModel<FacetField> model, int max, SortParam<FieldValuesOrder> sort) {
67        this.model = model;
68        this.maxNumberOfItems = max;
69        setSort(sort);
70    }
71
72    /**
73     * override to achieve filtering
74     *
75     * @return model of string items should begin with
76     */
77    protected IModel<String> getFilterModel() {
78        return null;
79    }
80
81    @Override
82    public Iterator<? extends FacetField.Count> iterator(long first, long count) {
83        // get all the values
84        final List<FacetField.Count> values = model.getObject().getValues();
85        // filter results
86        final Iterable<Count> filtered = filter(values);
87        // sort what remains
88        final ImmutableList sorted = getOrdering().immutableSortedCopy(filtered);
89        // return iterator starting at specified offset
90        return sorted.listIterator((int) first);
91    }
92
93    @Override
94    public long size() {
95        if (hasFilter()) {
96            final List<FacetField.Count> values = model.getObject().getValues();
97            return Iterables.size(filter(values));
98        } else {
99            // Use value count from Solr, faster.
100            //
101            // Actual value count might be higher than what we want to show
102            // so get minimum.
103            return Math.min(maxNumberOfItems, model.getObject().getValueCount());
104        }
105    }
106
107    @Override
108    public IModel<FacetField.Count> model(FacetField.Count object) {
109        return new Model(object);
110    }
111
112    @Override
113    public void detach() {
114        model.detach();
115    }
116
117    private Iterable<FacetField.Count> filter(List<FacetField.Count> list) {
118        if (hasFilter()) {
119            final String filterValue = getFilterModel().getObject().toLowerCase();
120            return Iterables.filter(list, new Predicate<FacetField.Count>() {
121                @Override
122                public boolean apply(Count input) {
123                    return input.getName().toLowerCase().startsWith(filterValue);
124                }
125            });
126        } else {
127            return list;
128        }
129    }
130
131    private boolean hasFilter() {
132        return !(getFilterModel() == null || getFilterModel().getObject() == null || getFilterModel().getObject().isEmpty());
133    }
134
135    private Ordering getOrdering() {
136        final Ordering ordering;
137        if (getSort().getProperty() == FieldValuesOrder.COUNT) {
138            ordering = COUNT_ORDERING;
139        } else if (getSort().getProperty() == FieldValuesOrder.NAME) {
140            ordering = NAME_ORDERING;
141        } else {
142            ordering = Ordering.natural();
143        }
144
145        if (getSort().isAscending()) {
146            return ordering;
147        } else {
148            return ordering.reverse();
149        }
150    }
151
152    private static Ordering<FacetField.Count> COUNT_ORDERING = new Ordering<FacetField.Count>() {
153
154        @Override
155        public int compare(Count arg0, Count arg1) {
156            // TODO: From old VLO:
157            // IGNORABLE_VALUES (like "unknown") are move to the back of the list and should only be shown when you click "more...", unless the list is too small then whe can just show them.
158            return Long.compare(arg0.getCount(), arg1.getCount());
159        }
160    };
161
162    private static Ordering<FacetField.Count> NAME_ORDERING = new Ordering<FacetField.Count>() {
163
164        @Override
165        public int compare(Count arg0, Count arg1) {
166            // TODO: From old VLO:
167            // IGNORABLE_VALUES (like "unknown") are move to the back of the list and should only be shown when you click "more...", unless the list is too small then whe can just show them.
168            return arg0.getName().compareTo(arg1.getName());
169        }
170    };
171
172}
Note: See TracBrowser for help on using the repository browser.