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

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

Added CMDI view (obtained through XSLT transform) to record page

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 * TODO: Add option to hide values with only 1 record (as in VLO 2.x)
38 *
39 * @see FieldValuesOrder
40 * @author twagoo
41 */
42public class FacetFieldValuesProvider extends SortableDataProvider<FacetField.Count, FieldValuesOrder> {
43
44    private final IModel<FacetField> model;
45    private final int maxNumberOfItems;
46
47    /**
48     * Creates a provider without a maximum number of values. Bound to
49     * {@link Integer#MAX_VALUE}.
50     *
51     * @param model FacetField model to get values and counts for
52     */
53    public FacetFieldValuesProvider(IModel<FacetField> model) {
54        this(model, Integer.MAX_VALUE);
55    }
56
57    public FacetFieldValuesProvider(IModel<FacetField> model, int max) {
58        this(model, max, new SortParam<FieldValuesOrder>(FieldValuesOrder.COUNT, false));
59    }
60
61    /**
62     * Creates a provider with a set maximum number of values
63     *
64     * @param model FacetField model to get values and counts for
65     * @param max maximum number of values to show
66     * @param sort initial sort property and order
67     */
68    public FacetFieldValuesProvider(IModel<FacetField> model, int max, SortParam<FieldValuesOrder> sort) {
69        this.model = model;
70        this.maxNumberOfItems = max;
71        setSort(sort);
72    }
73
74    /**
75     * override to achieve filtering
76     *
77     * @return model of string items should begin with
78     */
79    protected IModel<String> getFilterModel() {
80        return null;
81    }
82
83    @Override
84    public Iterator<? extends FacetField.Count> iterator(long first, long count) {
85        // get all the values
86        final List<FacetField.Count> values = model.getObject().getValues();
87        // filter results
88        final Iterable<Count> filtered = filter(values);
89        // sort what remains
90        final ImmutableList sorted = getOrdering().immutableSortedCopy(filtered);
91        // return iterator starting at specified offset
92        return sorted.listIterator((int) first);
93    }
94
95    @Override
96    public long size() {
97        if (hasFilter()) {
98            final List<FacetField.Count> values = model.getObject().getValues();
99            return Iterables.size(filter(values));
100        } else {
101            // Use value count from Solr, faster.
102            //
103            // Actual value count might be higher than what we want to show
104            // so get minimum.
105            return Math.min(maxNumberOfItems, model.getObject().getValueCount());
106        }
107    }
108
109    @Override
110    public IModel<FacetField.Count> model(FacetField.Count object) {
111        return new Model(object);
112    }
113
114    @Override
115    public void detach() {
116        model.detach();
117    }
118
119    private Iterable<FacetField.Count> filter(List<FacetField.Count> list) {
120        if (hasFilter()) {
121            final String filterValue = getFilterModel().getObject().toLowerCase();
122            return Iterables.filter(list, new Predicate<FacetField.Count>() {
123                @Override
124                public boolean apply(Count input) {
125                    return input.getName().toLowerCase().startsWith(filterValue);
126                }
127            });
128        } else {
129            return list;
130        }
131    }
132
133    private boolean hasFilter() {
134        return !(getFilterModel() == null || getFilterModel().getObject() == null || getFilterModel().getObject().isEmpty());
135    }
136
137    private Ordering getOrdering() {
138        final Ordering ordering;
139        if (getSort().getProperty() == FieldValuesOrder.COUNT) {
140            ordering = COUNT_ORDERING;
141        } else if (getSort().getProperty() == FieldValuesOrder.NAME) {
142            ordering = NAME_ORDERING;
143        } else {
144            ordering = Ordering.natural();
145        }
146
147        if (getSort().isAscending()) {
148            return ordering;
149        } else {
150            return ordering.reverse();
151        }
152    }
153
154    private static Ordering<FacetField.Count> COUNT_ORDERING = new Ordering<FacetField.Count>() {
155
156        @Override
157        public int compare(Count arg0, Count arg1) {
158            // TODO: From old VLO:
159            // 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.
160            return Long.compare(arg0.getCount(), arg1.getCount());
161        }
162    };
163
164    private static Ordering<FacetField.Count> NAME_ORDERING = new Ordering<FacetField.Count>() {
165
166        @Override
167        public int compare(Count arg0, Count arg1) {
168            // TODO: From old VLO:
169            // 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.
170            return arg0.getName().compareTo(arg1.getName());
171        }
172    };
173
174}
Note: See TracBrowser for help on using the repository browser.