source: vlo/branches/to-wicket-1.6/vlo_web_app/src/main/java/eu/clarin/cmdi/vlo/pages/FacetedSearchPage.java @ 4208

Last change on this file since 4208 was 4208, checked in by keeloo, 10 years ago

Finished the upgrade. The web application still needs to be tested.

File size: 14.0 KB
Line 
1package eu.clarin.cmdi.vlo.pages;
2
3import eu.clarin.cmdi.vlo.FacetConstants;
4import eu.clarin.cmdi.vlo.Resources;
5import eu.clarin.cmdi.vlo.VloPageParameters;
6import eu.clarin.cmdi.vlo.config.VloConfig;
7import eu.clarin.cmdi.vlo.dao.AutoCompleteDao;
8import eu.clarin.cmdi.vlo.importer.FacetConceptMapping.FacetConcept;
9import eu.clarin.cmdi.vlo.importer.VLOMarshaller;
10import fiftyfive.wicket.basic.TruncatedLabel;
11import java.io.UnsupportedEncodingException;
12import java.net.URLEncoder;
13import java.util.ArrayList;
14import java.util.HashMap;
15import java.util.Iterator;
16import java.util.List;
17import java.util.Map;
18
19import org.apache.solr.client.solrj.SolrServerException;
20import org.apache.solr.client.solrj.response.FacetField;
21import org.apache.solr.common.SolrDocument;
22import org.apache.wicket.request.mapper.parameter.PageParameters;
23import org.apache.wicket.RequestCycle;
24import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
25import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
26import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
27import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
28import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
29import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
30import org.apache.wicket.markup.html.WebMarkupContainer;
31import org.apache.wicket.markup.html.basic.Label;
32import org.apache.wicket.markup.html.basic.MultiLineLabel;
33import org.apache.wicket.markup.html.form.Button;
34import org.apache.wicket.markup.html.form.Form;
35import org.apache.wicket.markup.html.link.BookmarkablePageLink;
36import org.apache.wicket.markup.html.link.ExternalLink;
37import org.apache.wicket.markup.repeater.Item;
38import org.apache.wicket.markup.repeater.data.GridView;
39import org.apache.wicket.markup.repeater.data.IDataProvider;
40import org.apache.wicket.model.CompoundPropertyModel;
41import org.apache.wicket.model.IModel;
42import org.apache.wicket.model.ResourceModel;
43import org.apache.wicket.protocol.http.RequestUtils;
44
45public class FacetedSearchPage extends BasePage {
46    private static final long serialVersionUID = 1L;
47
48    private final SearchPageQuery query;
49    private final static AutoCompleteDao autoCompleteDao = new AutoCompleteDao();
50    private final static String facetConceptsFile = VloConfig.getFacetConceptsFile();
51    private final static Map<String, FacetConcept> facetNameMap = VLOMarshaller.getFacetConceptMapping(facetConceptsFile).getFacetConceptMap();
52   
53    /**
54     * @param parameters Page parameters
55     * @throws SolrServerException
56     */
57    public FacetedSearchPage(final VloPageParameters parameters) {
58        super(parameters);
59        query = new SearchPageQuery(parameters);
60        addSearchBox();
61        addFacetColumns();
62        addSearchResults();
63        addSearchServiceForm();
64    }
65
66    @SuppressWarnings("serial")
67    private class SearchBoxForm extends Form<SearchPageQuery> {
68        private final AutoCompleteTextField<String> searchBox;
69       
70        /*
71         * Add multiline list of selected facet values
72         */
73        private void addFacetOverview() {
74
75            // get a map of the facets currently selected
76            Map<String, String> selectedFacets;
77            selectedFacets = query.getFilterQueryMap();
78
79            // create an interator for walking over the facets
80            Iterator<Map.Entry<String, String>> entries = 
81                    selectedFacets.entrySet().iterator();
82
83            /*
84             * Wicket label to be used to show the list of facets that have been
85             * selected.
86             */
87            MultiLineLabel facetOverview;
88
89            // walk over the facets
90            if (!entries.hasNext()) {
91                // not a single facet has been selected
92                facetOverview = new MultiLineLabel("facetOverview", 
93                        "No facets values selected");
94            } else {
95                // at least one facet has been selected
96
97                String string = "Selected facet values:  ";
98
99                // start building the the multiline label here
100                String[] facetFields;
101                int i = 0, lineLength = 0,
102                        maxLineLength = VloConfig.getFacetOverviewLength();
103                Boolean hasPrevious = false;
104
105                /*
106                 * Get the facet fields. We need them in order to display
107                 * the values in the overview in the same order as their
108                 * respective facets are listed in the boxes. Store multiple
109                 * lines in one string.
110                 */
111                facetFields = VloConfig.getFacetFields();
112
113                while (i < facetFields.length) {
114
115                    // check if facet field is in selected facets map
116                    if (selectedFacets.containsKey(facetFields[i])) {
117                        String value = selectedFacets.get(facetFields[i]);
118                        lineLength = lineLength + value.length();
119
120                        if (hasPrevious) {
121                            string = string.concat(", ");
122                        }
123
124                        if (lineLength > maxLineLength) {
125                            string = string.concat("\n");
126                            lineLength = 0;
127                            hasPrevious = false;
128                        }
129
130                        string = string.concat(value);
131                        hasPrevious = true;
132                    }
133                    i++;
134                }
135
136                // create a new wicket multi line label
137                facetOverview = new MultiLineLabel("facetOverview", string);
138            }
139
140            // finally, merge the label to the form
141            this.add(facetOverview);
142        }
143
144        public SearchBoxForm(String id, SearchPageQuery query) {
145            super(id, new CompoundPropertyModel<SearchPageQuery>(query));
146            add(new ExternalLink("vloHomeLink", VloConfig.getHomeUrl()));
147
148            searchBox = new AutoCompleteTextField<String>("searchQuery") {
149                @Override
150                protected Iterator<String> getChoices(String input) {
151                    return autoCompleteDao.getChoices(input).iterator();
152                }
153            };
154           
155            add(searchBox);
156            Button submit = new Button("searchSubmit");
157            add(submit);
158           
159            // merge link to help menu page
160            String helpUrl = VloConfig.getHelpUrl();           
161            ExternalLink helpLink = new ExternalLink("helpLink", helpUrl, "help");
162            add(helpLink);
163           
164            VloPageParameters param; 
165            param = new VloPageParameters (query.getPageParameters());
166           
167            String thisURL;
168            thisURL = RequestUtils.toAbsolutePath(
169                    RequestCycle.get().urlFor(ShowResultPage.class, param.convert()).toString(), null);
170            try {
171                thisURL = URLEncoder.encode(thisURL, "UTF-8");
172            } catch (UnsupportedEncodingException e) {
173            }
174           
175            String feedbackFormUrl = VloConfig.getFeedbackFromUrl() + thisURL;
176            ExternalLink feedbackLink = new ExternalLink("feedbackLink", feedbackFormUrl, "found an error?");
177            add(feedbackLink);
178           
179            addFacetOverview();
180        }
181
182        @Override
183        protected void onSubmit() {
184            SearchPageQuery query = getModelObject();
185            PageParameters param = query.getPageParameters();
186
187            VloPageParameters newParam = new VloPageParameters();
188           
189            setResponsePage(FacetedSearchPage.class, newParam);
190        }
191    }
192
193    private void addSearchBox() {
194        add(new SearchBoxForm("searchForm", query));
195    }
196   
197    @SuppressWarnings("serial")
198    private void addFacetColumns() {
199        GridView<FacetField> facetColumns = new GridView<FacetField>("facetColumns", (IDataProvider<FacetField>) new SolrFacetDataProvider(query.getSolrQuery()
200                .getCopy())) {
201            @Override
202            protected void populateItem(Item<FacetField> item) {
203                String facetName = ((FacetField)item.getDefaultModelObject()).getName();
204                String descriptionTooltip = "";
205                if(facetNameMap.containsKey(facetName))
206                        descriptionTooltip = facetNameMap.get(facetName).getDescription();
207                item.add(new FacetBoxPanel("facetBox", item.getModel(), descriptionTooltip).create(query));
208            }
209
210            @Override
211            protected void populateEmptyItem(Item<FacetField> item) {
212                item.add(new Label("facetBox", ""));
213            }
214        };
215        facetColumns.setColumns(2);
216        add(facetColumns);
217    }
218
219    @SuppressWarnings("serial")
220    private void addSearchResults() {
221        List<IColumn<SolrDocument, String>> columns;
222        columns = new ArrayList<IColumn<SolrDocument, String>>();
223        columns.add(new AbstractColumn<SolrDocument, String>(new ResourceModel(Resources.NAME)) {
224           
225            @Override
226            public void populateItem(Item<ICellPopulator<SolrDocument>> cellItem, String componentId, IModel<SolrDocument> rowModel) {
227                cellItem.add(new DocumentLinkPanel(componentId, rowModel, query));
228            }
229        });
230        columns.add(new AbstractColumn<SolrDocument, String>(new ResourceModel(Resources.DESCRIPTION)) {
231
232            @Override
233            public void populateItem(Item<ICellPopulator<SolrDocument>> cellItem, String componentId, IModel<SolrDocument> rowModel) {
234                String descriptionText = (String) rowModel.getObject().getFirstValue(FacetConstants.FIELD_DESCRIPTION);
235                cellItem.add(new TruncatedLabel(componentId, 100, descriptionText));
236               
237            }
238        });
239        AjaxFallbackDefaultDataTable<SolrDocument, String> searchResultList = new AjaxFallbackDefaultDataTable<SolrDocument, String>("searchResults", columns, (ISortableDataProvider<SolrDocument, String>) new SolrDocumentDataProvider(query.getSolrQuery().getCopy()), 30);
240
241        add(searchResultList);
242    }
243   
244    /**
245     * Add contentSearch form (FCS)
246     *
247     * @param solrDocument
248     */
249    private void addSearchServiceForm() {
250       
251        BookmarkablePageLink link;
252        link = new BookmarkablePageLink ("link", FacetedSearchPage.class);
253        link.add (new Label ("naar deze pagina"));
254       
255        // get values for cql endpoint substitution
256        String cqlEndpointFilter = VloConfig.getCqlEndpointFilter();
257        String cqlEndpointAlternative = VloConfig.getCqlEndpointAlternative();
258
259        final WebMarkupContainer contentSearchContainer = new WebMarkupContainer("contentSearch");
260        add(contentSearchContainer);
261
262        // get all documents with an entry for the FCS
263        SearchServiceDataProvider dataProvider = new SearchServiceDataProvider(query.getSolrQuery());
264        if (dataProvider.size() > 0 && dataProvider.size() <= 200) {    // at least one and not more than x records with FCS endpoint in result set?
265            try {
266                // building map (CQL endpoint -> List of resource IDs)
267                HashMap<String, List<String>> aggregationContextMap = new HashMap<String, List<String>>();
268
269                int offset = 0;
270                int fetchSize = 1000;
271                int totalResults = (int) dataProvider.size();
272                while (offset < totalResults) {
273                    Iterator<SolrDocument> iter = dataProvider.iterator(offset, fetchSize);
274                    while (iter.hasNext()) {
275                        SolrDocument document = iter.next();
276                        String id = document.getFirstValue(FacetConstants.FIELD_ID).toString();
277                        String fcsEndpoint = document.getFirstValue(FacetConstants.FIELD_SEARCH_SERVICE).toString();
278                        if (aggregationContextMap.containsKey(fcsEndpoint)) {
279                            aggregationContextMap.get(fcsEndpoint).add(id);
280                        } else {
281                            List<String> idArray = new ArrayList<String>();
282                            idArray.add(id);
283                           
284                            // substitute endpoint
285                            if (cqlEndpointFilter.length() == 0){
286                                // no substitution
287                            } else {
288                                // check for the need to substitute
289                            }
290                               
291                            if (cqlEndpointFilter.equals(cqlEndpointFilter)){
292                                // no substitution, take the value from the record
293                                aggregationContextMap.put(fcsEndpoint, idArray);
294                            } else {
295                                // substitution, take the alternative url
296                                aggregationContextMap.put(cqlEndpointAlternative, idArray);
297                            }
298                        }
299                    }
300
301                    offset += fetchSize;
302                }
303
304                // merge HTML form to container
305                String labelString;
306                if (totalResults == 1) {
307                    labelString = "Plain text search via Federated Content Search (supported by one resource in this result set)";
308                } else {
309                    labelString = "Plain text search via Federated Content Search (supported by " + totalResults
310                            + " resources in this result set)";
311                }
312                Label contentSearchLabel = new Label("contentSearchForm", HtmlFormCreator.getContentSearchForm(
313                        aggregationContextMap, labelString));
314                contentSearchLabel.setEscapeModelStrings(false);
315                contentSearchContainer.add(contentSearchLabel);
316                // contentSearchContainer.merge(link);
317            } catch (UnsupportedEncodingException uee) {
318                contentSearchContainer.setVisible(false);
319            }
320        } else {
321            contentSearchContainer.setVisible(false);
322        }
323    }
324}
Note: See TracBrowser for help on using the repository browser.