source: vlo/trunk/vlo_web_app/src/main/java/eu/clarin/cmdi/vlo/pages/FacetedSearchPage.java @ 4082

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

Repaired Federated Content Search form - when the facetboxes shrink, it does not jump to the left anymore.

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