/**
* $Id: BrowseFacet.java 5161 2010-07-02 11:34:56Z KevinVandeVelde $
* $URL: http://scm.dspace.org/svn/repo/modules/dspace-discovery/trunk/block/src/main/java/org/dspace/app/xmlui/aspect/discovery/BrowseFacet.java $
* *************************************************************************
* Copyright (c) 2002-2009, DuraSpace. All rights reserved
* Licensed under the DuraSpace License.
*
* A copy of the DuraSpace License has been included in this
* distribution and is available at: http://scm.dspace.org/svn/repo/licenses/LICENSE.txt
*/
package org.dspace.app.xmlui.aspect.discovery;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.utils.HandleUtil;
import org.dspace.app.xmlui.utils.DSpaceValidity;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.element.*;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Community;
import org.dspace.content.Collection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.util.HashUtil;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.excalibur.source.SourceValidity;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.FacetParams;
import org.apache.log4j.Logger;
import org.dspace.discovery.*;
import org.dspace.services.ConfigurationService;
import org.dspace.utils.DSpace;
import org.xml.sax.SAXException;
import java.io.Serializable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.net.URLEncoder;
import java.util.List;
//import org.dspace.sort.SortException;
//import org.dspace.sort.SortOption;
/**
* User: mdiggory
* Date: Sep 25, 2009
* Time: 11:54:11 PM
*/
public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableProcessingComponent {
private static final Logger log = Logger.getLogger(BrowseFacet.class);
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
private final static Message T_go = message("xmlui.general.go");
private final static Message T_update = message("xmlui.general.update");
private final static Message T_starts_with = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.starts_with");
private final static Message T_starts_with_help = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.starts_with_help");
// private final static Message T_choose_year = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.choose_year");
private final static Message T_jump_year = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.jump_year");
private final static Message T_jump_year_help = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.jump_year_help");
// private final static Message T_jump_select = message("xmlui.ArtifactBrowser.ConfigurableBrowse.general.jump_select");
private final static Message T_jump_century_head = message("xmlui.Discovery.BrowseFacet.browse_century_head");
private final static Message T_jump_century = message("xmlui.Discovery.BrowseFacet.browse_century");
// private static final Message T_sort_by_relevance = message("xmlui.ArtifactBrowser.AbstractSearch.sort_by.relevance");
// private final static Message T_sort_by = message("xmlui.ArtifactBrowser.AbstractSearch.sort_by");
private final static Message T_order = message("xmlui.ArtifactBrowser.AbstractSearch.order");
private final static Message T_order_asc = message("xmlui.ArtifactBrowser.AbstractSearch.order.asc");
private final static Message T_order_desc = message("xmlui.ArtifactBrowser.AbstractSearch.order.desc");
private final static Message T_rpp = message("xmlui.ArtifactBrowser.AbstractSearch.rpp");
private final static Message T_view = message("xmlui.ArtifactBrowser.AbstractSearch.view");
/**
* The options for results per page
*/
private static final int[] RESULTS_PER_PAGE_PROGRESSION = {10, 20, 50, 100};
/**
* The types of view
*/
private static final String[] VIEW_TYPES = {"list", "cloud"};
/**
* The cache of recently submitted items
*/
protected QueryResponse queryResults;
/**
* Cached validity object
*/
protected SourceValidity validity;
/**
* Cached query arguments
*/
protected SolrQuery queryArgs;
private int DEFAULT_PAGE_SIZE = 50;
//private String DEFAULT_ORDER = SortOption.ASCENDING;
private SolrQuery.ORDER DEFAULT_ORDER = SolrQuery.ORDER.asc;
private String DEFAULT_SORT_BY = "lex";
// public static final String OFFSET = "offset";
public static final String FACET_FIELD = "field";
final static String STARTS_WITH = "starts_with";
final static String PAGE = "page";
final static String ORDER = "order";
final static String RESULTS_PER_PAGE = "rpp";
final static String SORT_BY = "sort_by";
final static String VIEW = "view";
public static final String BROWSE_URL_BASE = "browse";
private ConfigurationService config = null;
private SearchService searchService = null;
public BrowseFacet() {
DSpace dspace = new DSpace();
config = dspace.getConfigurationService();
searchService = dspace.getServiceManager().getServiceByName(SearchService.class.getName(), SearchService.class);
}
/**
* Generate the unique caching key.
* This key must be unique inside the space of this component.
*/
@Override
public Serializable getKey() {
try {
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
if (dso == null) {
return "0";
}
return HashUtil.hash(dso.getHandle());
} catch (SQLException sqle) {
// Ignore all errors and just return that the component is not
// cachable.
return "0";
}
}
/**
* Generate the cache validity object.
* <p/>
* The validity object will include the collection being viewed and
* all recently submitted items. This does not include the community / collection
* hierarch, when this changes they will not be reflected in the cache.
*/
@Override
public SourceValidity getValidity() {
if (this.validity == null) {
try {
DSpaceValidity validity = new DSpaceValidity();
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
if (dso != null) {
// Add the actual collection;
validity.add(dso);
}
// add reciently submitted items, serialize solr query contents.
QueryResponse response = getQueryResponse(dso);
validity.add("numFound:" + response.getResults().getNumFound());
// for (SolrDocument doc : response.getResults()) {
// validity.add(doc.toString());
// }
for (SolrDocument doc : response.getResults()) {
validity.add(doc.toString());
}
for (FacetField field : response.getFacetFields()) {
validity.add(field.getName());
for (FacetField.Count count : field.getValues()) {
validity.add(count.getName() + "#" + count.getCount());
}
}
this.validity = validity.complete();
} catch (Exception e) {
// Just ignore all errors and return an invalid cache.
}
//TODO: dependent on tags as well :)
}
return this.validity;
}
/**
* Get the recently submitted items for the given community or collection.
*
* @param scope The collection.
*/
protected QueryResponse getQueryResponse(DSpaceObject scope) {
Request request = ObjectModelHelper.getRequest(objectModel);
if (queryResults != null) {
return queryResults;
}
queryArgs = new SolrQuery();
//Make sure we add our default filters
queryArgs.addFilterQuery(SearchUtils.getDefaultFilters(BROWSE_URL_BASE));
queryArgs.setQuery("search.resourcetype: " + Constants.ITEM + ((request.getParameter("query") != null && !"".equals(request.getParameter("query"))) ? " AND (" + request.getParameter("query") + ")" : ""));
// queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
queryArgs.setRows(0);
queryArgs.setSortField(
ConfigurationManager.getProperty("recent.submissions.sort-option"),
getParameterOrder());
queryArgs.addFilterQuery(getParameterFacetQueries());
queryArgs.setFacet(true);
//Set the default limit to 11
//query.setFacetLimit(11);
queryArgs.setFacetMinCount(1);
//sort
//TODO: why this kind of sorting ? Should the sort not be on how many times the value appears like we do in the filter by sidebar ?
queryArgs.setFacetSort(getParameterSortBy());
String facetField = getParameterField();
int page = getParameterPage();
int rpp = getParameterRpp();
// FIXME: Have to retrieve everything, since there is no way of getting total facets in order to do masked pagination.
// queryArgs.setParam(FacetParams.FACET_OFFSET, String.valueOf((page - 1) * rpp));
// queryArgs.setFacetLimit(rpp);//setParam(FacetParams.FACET_LIMIT, String.valueOf(rpp));
queryArgs.setFacetLimit(-1);
// int offset = RequestUtils.getIntParameter(request, OFFSET);
// if (offset == -1) {
// offset = 0;
// }
// if (facetField != null && facetField.endsWith(".year")) {
// queryArgs.setParam(FacetParams.FACET_OFFSET, "0");
// queryArgs.setParam(FacetParams.FACET_LIMIT, "1000000");
// facetField = facetField.replace(".year", "");
// } else {
// queryArgs.setParam(FacetParams.FACET_OFFSET, String.valueOf(offset));
//We add +1 so we can use the extra one to make sure that we need to show the next page
// queryArgs.setParam(FacetParams.FACET_LIMIT, String.valueOf(rpp));
// }
if (scope != null) /* top level search / community */ {
if (scope instanceof Community) {
//queryArgs.setFilterQueries("location:m" + scope.getID());
queryArgs.addFilterQuery("location:m" + scope.getID());
} else if (scope instanceof Collection) {
//queryArgs.setFilterQueries("location:l" + scope.getID());
queryArgs.addFilterQuery("location:l" + scope.getID());
}
}
boolean isDate = false;
if (facetField != null && facetField.endsWith("_dt")) {
facetField = facetField.split("_")[0];
isDate = true;
}
if (isDate) {
queryArgs.setParam(FacetParams.FACET_DATE, new String[]{facetField});
queryArgs.setParam(FacetParams.FACET_DATE_GAP, "+1YEAR");
Date lowestDate = getLowestDateValue(queryArgs.getQuery(), facetField, queryArgs.getFilterQueries());
int thisYear = Calendar.getInstance().get(Calendar.YEAR);
DateFormat formatter = new SimpleDateFormat("yyyy");
int maxEndYear = Integer.parseInt(formatter.format(lowestDate));
//Since we have a date, we need to find the last year
String startDate = "NOW/YEAR-" + SearchUtils.getConfig().getString("solr.date.gap", "10") + "YEARS";
String endDate = "NOW";
// int startYear = thisYear - (offset + DEFAULT_PAGE_SIZE);
int startYear = thisYear - ((page - 1) * rpp);
// We shouldn't go lower then our max bottom year
// Make sure to substract one so the bottom year is also counted !
if (startYear < maxEndYear) {
startYear = maxEndYear - 1;
}
// if (0 < offset) {
if (page > 1) {
//Say that we have an offset of 10 years
//we need to go back 10 years (2010 - (2010 - 10))
//(add one to compensate for the NOW in the start)
// int endYear = thisYear - offset + 1;
int endYear = thisYear - ((page - 1) * rpp) + 1;
endDate = "NOW/YEAR-" + (thisYear - endYear) + "YEARS";
//Add one to the startyear to get one more result
//When we select NOW, the current year is also used (so auto+1)
}
startDate = "NOW/YEAR-" + (thisYear - startYear) + "YEARS";
queryArgs.setParam(FacetParams.FACET_DATE_START, startDate);
queryArgs.setParam(FacetParams.FACET_DATE_END, endDate);
queryArgs.setFacetMinCount(1);
System.out.println(startDate);
System.out.println(endDate);
} else {
queryArgs.addFacetField(new String[]{facetField});
}
// log.debug("queryArgs: " + queryArgs.toString());
String startsWith = getParameterStartsWith();
if (startsWith != null) {
queryArgs.setFacetPrefix(facetField, startsWith);
}
try {
queryResults = searchService.search(queryArgs);
} catch (SearchServiceException e) {
log.error(e.getMessage(), e);
}
return queryResults;
}
/**
* Retrieves the lowest date value in the given field
* @param query a solr query
* @param dateField the field for which we want to retrieve our date
* @param filterquery the filterqueries
* @return the lowest date found, in a date object
*/
private Date getLowestDateValue(String query, String dateField, String... filterquery) {
try {
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(query);
solrQuery.setFields(dateField);
solrQuery.setRows(1);
solrQuery.setSortField(dateField, SolrQuery.ORDER.asc);
solrQuery.setFilterQueries(filterquery);
QueryResponse rsp = searchService.search(solrQuery);
if (0 < rsp.getResults().getNumFound()) {
return (Date) rsp.getResults().get(0).getFieldValue(dateField);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Add the basic navigational options:
*
* Search - advanced search
*
* browse - browse by Titles - browse by Authors - browse by Dates
*
* language FIXME: add languages
*
* context no context options are added.
*
* action no action options are added.
*/
@Override
public void addOptions(Options options) throws SAXException, WingException,
UIException, SQLException, IOException, AuthorizeException
{
// DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
//List test = options.addList("browse");
// DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
// List test = options.addList("browse");
// org.dspace.app.xmlui.wing.element.List browse = options.addList("browse");
// browse.setHead(T_head_browse);
/*
List browseGlobal = browse.addList("global");
List browseContext = browse.addList("context");
browseGlobal.setHead(T_head_all_of_dspace);
if (dso != null)
{
if (dso instanceof Collection)
{
browseContext.addItem().addXref(contextPath + "/discovery/?q=search.resourcetype%3A2+AND+location%3Al" + dso.getID(), T_head_this_collection );
}
if (dso instanceof Community)
{
browseContext.addItem().addXref(contextPath + "/discovery/?q=search.resourcetype%3A2+AND+location%3Am" + dso.getID(), T_head_this_community );
}
}
browseGlobal.addItem().addXref(contextPath + "/community-list", T_head_all_of_dspace );
*/
}
/**
* Add a page title and trail links.
*/
@Override
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, SQLException, IOException, AuthorizeException {
// Request request = ObjectModelHelper.getRequest(objectModel);
String facetField = getParameterField();
pageMeta.addMetadata("title").addContent(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + facetField + "_browse"));
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
if ((dso instanceof Collection) || (dso instanceof Community)) {
HandleUtil.buildHandleTrail(dso, pageMeta, contextPath);
}
pageMeta.addTrail().addContent(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + facetField + "_browse"));
}
@Override
public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
Request request = ObjectModelHelper.getRequest(objectModel);
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
java.util.List fqs = Arrays.asList(getParameterFacetQueries());
//Make sure we get our results
// log.debug("query results 1: " + queryResults.toString());
queryResults = getQueryResponse(dso);
if (this.queryResults != null) {
log.debug("query results 2: " + queryResults.toString());
java.util.List<FacetField> facetFields = this.queryResults.getFacetFields();
if (facetFields == null) {
facetFields = new ArrayList<FacetField>();
}
facetFields.addAll(this.queryResults.getFacetDates());
log.debug("facetFields: " + facetFields.toString());
if (facetFields.size() > 0) {
FacetField field = facetFields.get(0);
java.util.List<FacetField.Count> values = field.getValues();
if (field.getGap() != null || field.getName().endsWith(".year")) {
//We are dealing with dates so flip em, top date comes first
DEFAULT_ORDER = SolrQuery.ORDER.desc;
} else {
DEFAULT_ORDER = SolrQuery.ORDER.asc;
}
// Build the DRI Body
Division div = body.addDivision("browse-by-" + field.getName(), "primary");
div.setHead(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + getParameterField() + "_browse"));
// Build the internal navigation (jump lists)
addBrowseJumpNavigation(div, field, request);
// Build the sort and display controls
addBrowseControls(div, field, request);
if (values != null && 0 < values.size()) {
if (getParameterOrder().equals(SolrQuery.ORDER.desc)) {
Collections.reverse(values);
}
// Division results = body.addDivision("browse-by-" + field.getName() + "-results", "primary");
Division results = div.addDivision("browse-by-" + field.getName() + "-results", this.getParameterView());
//results.setHead(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + getParameterField() + "_browse"));
// Find our faceting offset
/*
int offSet = 0;
try {
offSet = Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET));
} catch (NumberFormatException e) {
//Ignore
}
//Only show the nextpageurl if we have at least one result following our current results
String nextPageUrl = null;
if (field.getName().endsWith(".year")) {
offSet = Util.getIntParameter(request, "offset");
offSet = offSet == -1 ? 0 : offSet;
if ((offSet + DEFAULT_PAGE_SIZE) < values.size()) {
nextPageUrl = getNextPageURL(request);
}
} else {
if (values.size() == (DEFAULT_PAGE_SIZE + 1)) {
nextPageUrl = getNextPageURL(request);
}
}
int shownItemsMax;
if (field.getName().endsWith(".year")) {
if ((values.size() - offSet) < DEFAULT_PAGE_SIZE) {
shownItemsMax = values.size();
} else {
shownItemsMax = DEFAULT_PAGE_SIZE;
}
} else {
shownItemsMax = offSet + (DEFAULT_PAGE_SIZE < values.size() ? values.size() - 1 : values.size());
}
*/
// results.setSimplePagination((int) queryResults.getResults().getNumFound(), offSet + 1,
// shownItemsMax, getPreviousPageURL(request), nextPageUrl);
//// Switching to masked pagination.
// Pagination variables.
// int itemsTotal = (int) solrResults.getNumFound();
// int firstItemIndex = (int) solrResults.getStart() + 1;
// int lastItemIndex = (int) solrResults.getStart() + solrResults.size();
// //if (itemsTotal < lastItemIndex)
// // lastItemIndex = itemsTotal;
// int currentPage = (int) (solrResults.getStart() / this.queryArgs.getFacetLimit()) + 1;
// int pagesTotal = (int) ((solrResults.getNumFound() - 1) / this.queryArgs.getFacetLimit()) + 1;
int itemsTotal = values.size();
int firstItemIndex = (getParameterPage() - 1) * getParameterRpp() +1;
// int firstItemIndex = Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET,
// String.valueOf((getParameterPage() - 1) * queryArgs.getFacetLimit())));
int lastItemIndex = firstItemIndex + getParameterRpp() - 1;
if (lastItemIndex > itemsTotal)
lastItemIndex = itemsTotal;
//if (itemsTotal < lastItemIndex)
// lastItemIndex = itemsTotal;
int currentPage = getParameterPage(); //(int) (firstItemIndex / getParameterRpp()) + 1;
int pagesTotal = (int) ((itemsTotal - 1) / getParameterRpp()) + 1;
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("page", "{pageNum}");
String pageURLMask = generateURL(parameters);
results.setMaskedPagination(itemsTotal, firstItemIndex, lastItemIndex, currentPage, pagesTotal, pageURLMask);
////
Table singleTable = results.addTable("browse-by-" + field.getName() + "-results", lastItemIndex - firstItemIndex + 1, 1);
List<String> filterQueries = new ArrayList<String>();
// if (request.getParameterValues("fq") != null) {
// filterQueries = Arrays.asList(request.getParameterValues("fq"));
// }
filterQueries = Arrays.asList(getParameterFacetQueries());
if (field.getName().endsWith(".year")) {
for (int i = firstItemIndex - 1; i < lastItemIndex; i++) {
FacetField.Count value = values.get(i);
renderFacetField(request, dso, field, singleTable, filterQueries, value);
}
//TODO
// int start = (values.size() - 1) - this.queryArgs.getFacetLimit();
// int end = start - getParameterRpp();
// if (end < 0) {
// end = 0;
// } else {
// end++;
// }
// for (int i = start; end <= i; i--) {
// FacetField.Count value = values.get(i);
// renderFacetField(request, dso, field, singleTable, filterQueries, value);
// }
} else {
// int end = values.size();
// if (getParameterRpp() < end) {
// end = getParameterRpp();
// }
//
// for (int i = 0; i < end; i++) {
// FacetField.Count value = values.get(i);
// renderFacetField(request, dso, field, singleTable, filterQueries, value);
// }
for (int i = firstItemIndex - 1; i < lastItemIndex; i++) {
FacetField.Count value = values.get(i);
renderFacetField(request, dso, field, singleTable, filterQueries, value);
}
}
}
}
}
//DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
/*
if (dso != null)
{
if (dso instanceof Collection)
{
browseContext.addItem().addXref(contextPath + "/discovery/?q=search.resourcetype%3A2+AND+location%3Al" + dso.getID(), T_head_this_collection );
}
if (dso instanceof Community)
{
browseContext.addItem().addXref(contextPath + "/discovery/?q=search.resourcetype%3A2+AND+location%3Am" + dso.getID(), T_head_this_community );
}
}
browseGlobal.addItem().addXref(contextPath + "/discovery/?q=search.resourcetype%3A2", T_head_all_of_dspace );
*/
}
private void renderFacetField(Request request, DSpaceObject dso, FacetField field, Table singleTable, List<String> filterQueries, FacetField.Count value) throws SQLException, WingException, UnsupportedEncodingException {
String displayedValue = value.getName();
String filterQuery = value.getAsFilterQuery();
if (field.getName().equals("location.comm") || field.getName().equals("location.coll")) {
//We have a community/collection, resolve it to a dspaceObject
// displayedValue = SolrServiceImpl.locationToName(context, field.getName(), displayedValue);
int type = field.getName().equals("location.comm") ? Constants.COMMUNITY : Constants.COLLECTION;
DSpaceObject commColl = DSpaceObject.find(context, type, Integer.parseInt(displayedValue));
if (commColl != null) {
displayedValue = commColl.getName() + "TEST";
}
}
if (field.getGap() != null) {
//We have a date get the year so we can display it
DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
displayedValue = simpleDateformat.format(SolrServiceImpl.toDate(displayedValue));
//displayedValue = displayedValue.substring(0, 4);
filterQuery = ClientUtils.escapeQueryChars(value.getFacetField().getName()) + ":" + displayedValue + "*";
}
Cell cell = singleTable.addRow().addCell();
//No use in selecting the same filter twice
if (filterQueries.contains(filterQuery)) {
// cell.addContent(displayedValue + " (" + value.getCount() + ")");
cell.addContent(displayedValue + " (" + value.getCount() + ")");
} else {
cell.addXref(
contextPath + (dso == null ? "" : "/handle/" + dso.getHandle())
+ "/search?"
+ "&fq="
+ URLEncoder.encode(filterQuery, "UTF-8")
//+ (request.getQueryString() != null ? "&" + request.getQueryString() : "")
,
// displayedValue + " (" + value.getCount() + ")");
displayedValue,
String.valueOf(value.getCount()));
}
}
/*
private String getNextPageURL(Request request) {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(FACET_FIELD, getParameterField());
int offSet = Util.getIntParameter(request, "offset");
if (offSet == -1) {
offSet = 0;
}
parameters.put(OFFSET, String.valueOf(offSet + DEFAULT_PAGE_SIZE));
// Add the filter queries
String url = generateURL(BROWSE_URL_BASE, parameters);
String[] fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
url += "&fq=" + fq;
}
}
return url;
}
*/
/*
private String getPreviousPageURL(Request request) {
//If our offset should be 0 then we shouldn't be able to view a previous page url
if ("0".equals(queryArgs.get(FacetParams.FACET_OFFSET)) && Util.getIntParameter(request, "offset") == -1) {
return null;
}
int offset = Util.getIntParameter(request, "offset");
if (offset == -1 || offset == 0) {
return null;
}
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(FACET_FIELD, getParameterField());
parameters.put(OFFSET, String.valueOf(offset - DEFAULT_PAGE_SIZE));
// Add the filter queries
String url = generateURL(BROWSE_URL_BASE, parameters);
String[] fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
url += "&fq=" + fq;
}
}
return url;
}
*/
/**
* Generate a url to the simple search url.
*/
protected String generateURL(Map<String, String> parameters)
throws UIException {
// String query = getQuery();
// if (!"".equals(query)) {
// parameters.put("query", URLEncode(query));
// }
parameters.put(FACET_FIELD, getParameterField());
if (parameters.get(PAGE) == null) {
parameters.put(PAGE, String.valueOf(getParameterPage()));
}
if (parameters.get(VIEW) == null) {
parameters.put(VIEW, String.valueOf(getParameterView()));
}
if (parameters.get(RESULTS_PER_PAGE) == null) {
parameters.put(RESULTS_PER_PAGE, String.valueOf(getParameterRpp()));
}
// if (parameters.get("group_by") == null) {
// parameters.put("group_by", String.valueOf(this.getParameterGroup()));
// }
if (parameters.get(SORT_BY) == null) {
parameters.put(SORT_BY, String.valueOf(getParameterSortBy()));
}
if (parameters.get(ORDER) == null) {
parameters.put(ORDER, String.valueOf(getParameterOrder()));
}
if (parameters.get(STARTS_WITH) == null) {
parameters.put(STARTS_WITH, String.valueOf(getParameterStartsWith()));
}
// Add the filter queries
String url = super.generateURL(BROWSE_URL_BASE, parameters);
String[] fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
url += "&fq=" + fq;
}
}
return url;
}
/**
* Makes the jump-list navigation for the results
*
* @param div
* @param info
* @param params
* @throws WingException
*/
private void addBrowseJumpNavigation(Division div, FacetField field, Request request)
throws WingException
{
// Get the name of the index
String type = field.getName();
// Prepare a Map of query parameters required for all links
// Map<String, String> queryParamsGET = new HashMap<String, String>();
// queryParamsGET.putAll(params.getCommonParametersEncoded());
// queryParamsGET.putAll(params.getControlParameters());
//
// Map<String, String> queryParamsPOST = new HashMap<String, String>();
// queryParamsPOST.putAll(params.getCommonParameters());
// queryParamsPOST.putAll(params.getControlParameters());
// Navigation aid (really this is a poor version of pagination)
Division jump = div.addInteractiveDivision("browse-navigation", BROWSE_URL_BASE,
Division.METHOD_POST, "secondary navigation");
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(FACET_FIELD, getParameterField());
//parameters.put(OFFSET, "0");
parameters.put(PAGE, Integer.toString(getParameterPage()));
parameters.put(SORT_BY, getParameterSortBy());
parameters.put(ORDER, getParameterOrder().toString());
parameters.put(RESULTS_PER_PAGE, Integer.toString(getParameterRpp()));
parameters.put(VIEW, getParameterView());
// Add all the query parameters as hidden fields on the form
for (String key : parameters.keySet())
jump.addHidden(key).setValue(parameters.get(key));
// Remove 'page' parameter from jump list
parameters.remove(PAGE);
// If this is a date based browse, render the date navigation
if (type != null && type.startsWith("date"))
{
org.dspace.app.xmlui.wing.element.List jumpList = jump.addList("jump-list", org.dspace.app.xmlui.wing.element.List.TYPE_SIMPLE, "centuries");
jumpList.setHead(T_jump_century_head);
for (int i = 2100; i >= 1500; i -= 100)
{
// parameters.put(STARTS_WITH, Character.toString(c));
parameters.put("fq", type+":["+(i-99)+"+TO+"+(i)+"]");
// Add the filter queries
String url = generateURL(BROWSE_URL_BASE, parameters);
String[] fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
if (!fq.startsWith(type))
url += "&fq=" + fq;
}
}
int cent = (i / 100);
jumpList.addItemXref(url, T_jump_century.parameterize(cent));
}
// Create a free text entry box for the year
Para jumpForm = jump.addPara();
jumpForm.addContent(T_jump_year);
jumpForm.addText(STARTS_WITH).setHelp(T_jump_year_help);
jumpForm.addButton("submit").setValue(T_go);
}
else
{
// Create a clickable list of the alphabet
org.dspace.app.xmlui.wing.element.List jumpList = jump.addList("jump-list", org.dspace.app.xmlui.wing.element.List.TYPE_SIMPLE, "alphabet");
// browse params for each letter are all the query params
// WITHOUT the second-stage browse value, and add STARTS_WITH.
// Map<String, String> letterQuery = new HashMap<String, String>(queryParamsGET);
// for (String valueKey : BrowseParams.FILTER_VALUE)
// {
// letterQuery.remove(valueKey);
// }
parameters.put(STARTS_WITH, "0");
String url = generateURL(BROWSE_URL_BASE, parameters);
String[] fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
url += "&fq=" + fq;
}
}
jumpList.addItemXref(url, "0-9");
//jumpList.addItemXref(super.generateURL(BROWSE_URL_BASE, letterQuery), "0-9");
for (char c = 'A'; c <= 'Z'; c++)
{
parameters.put(STARTS_WITH, Character.toString(c));
// Add the filter queries
url = generateURL(BROWSE_URL_BASE, parameters);
fqs = getParameterFacetQueries();
if (fqs != null) {
for (String fq : fqs) {
url += "&fq=" + fq;
}
}
jumpList.addItemXref(url, Character.toString(c));
}
// Create a free text field for the initial characters
Para jumpForm = jump.addPara();
jumpForm.addContent(T_starts_with);
jumpForm.addText(STARTS_WITH).setHelp(T_starts_with_help);
jumpForm.addButton("submit").setValue(T_go);
}
}
/**
* Add the controls to changing sorting and display options.
*
* @param div
* @param info
* @param params
* @throws WingException
*/
private void addBrowseControls(Division div, FacetField field, Request request)
throws WingException
{
// Prepare a Map of query parameters required for all links
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(FACET_FIELD, getParameterField());
//parameters.put(OFFSET, getParameterOffset());
Division controlsDiv = div.addInteractiveDivision("browse-controls",
BROWSE_URL_BASE, Division.METHOD_GET, "secondary search");
for (String par : parameters.keySet())
controlsDiv.addHidden(par).setValue(parameters.get(par));
Table controlsTable = controlsDiv.addTable("browse-controls", 1, 3);
//Table controlsTable = controlsDiv.addTable("browse-controls", 1, 4);
Row controlsRow = controlsTable.addRow(Row.ROLE_DATA);
// Create a control for the type of view to display
Cell viewCell = controlsRow.addCell();
try {
viewCell.addContent(T_view);
Select viewSelect = viewCell.addSelect("view");
for (String v : VIEW_TYPES) {
viewSelect.addOption((v.equals(getParameterView())), v, message("xmlui.ArtifactBrowser.AbstractSearch.view." + v));
}
}
catch (Exception e) {
throw new WingException("Unable to get view options", e);
}
// Create a control for the number of records to display
Cell rppCell = controlsRow.addCell();
rppCell.addContent(T_rpp);
Select rppSelect = rppCell.addSelect("rpp");
for (int i : RESULTS_PER_PAGE_PROGRESSION) {
rppSelect.addOption((i == getParameterRpp()), i, Integer.toString(i));
}
/*
Cell groupCell = controlsRow.addCell();
try {
// Create a drop down of the different sort columns available
groupCell.addContent(T_group_by);
Select groupSelect = groupCell.addSelect("group_by");
groupSelect.addOption(false, "none", T_group_by_none);
String[] groups = {"publication_grp"};
for (String group : groups) {
groupSelect.addOption(group.equals(getParameterGroup()), group,
message("xmlui.ArtifactBrowser.AbstractSearch.group_by." + group));
}
}
catch (Exception se) {
throw new WingException("Unable to get group options", se);
}
*/
// Sorting does not make sense in browsing.
// Cell sortCell = controlsRow.addCell();
// try {
// // Create a drop down of the different sort columns available
// sortCell.addContent(T_sort_by);
// Select sortSelect = sortCell.addSelect("sort_by");
// sortSelect.addOption(false, "score", T_sort_by_relevance);
// for (SortOption so : SortOption.getSortOptions()) {
// if (so.isVisible()) {
// sortSelect.addOption((so.getMetadata().equals(getParameterSortBy())), so.getMetadata(),
// message("xmlui.ArtifactBrowser.AbstractSearch.sort_by." + so.getName()));
// }
// }
// }
// catch (SortException se) {
// throw new WingException("Unable to get sort options", se);
// }
// Create a control to changing ascending / descending order
Cell orderCell = controlsRow.addCell();
orderCell.addContent(T_order);
Select orderSelect = orderCell.addSelect("order");
orderSelect.addOption(SolrQuery.ORDER.asc.equals(getParameterOrder()), SolrQuery.ORDER.asc.toString(), T_order_asc);
orderSelect.addOption(SolrQuery.ORDER.desc.equals(getParameterOrder()), SolrQuery.ORDER.desc.toString(), T_order_desc);
// Create a control for the number of authors per item to display
// FIXME This is currently disabled, as the supporting functionality
// is not currently present in xmlui
//if (isItemBrowse(info))
//{
// controlsForm.addContent(T_etal);
// Select etalSelect = controlsForm.addSelect(BrowseParams.ETAL);
//
// etalSelect.addOption((info.getEtAl() < 0), 0, T_etal_all);
// etalSelect.addOption(1 == info.getEtAl(), 1, Integer.toString(1));
//
// for (int i = 5; i <= 50; i += 5)
// {
// etalSelect.addOption(i == info.getEtAl(), i, Integer.toString(i));
// }
//}
// controlsForm.addButton("update").setValue(T_update);
// query.addPara(null, "button-list").addButton("submit").setValue(T_go);
controlsDiv.addPara(null, "button-list").addButton("update").setValue(T_update);
}
/**
* Recycle
*/
@Override
public void recycle() {
// Clear out our item's cache.
this.queryResults = null;
this.validity = null;
super.recycle();
}
public String getParameterField() {
Request request = ObjectModelHelper.getRequest(objectModel);
String facetField = request.getParameter(FACET_FIELD);
// There is already a configuration option for this: solr.browse.default.filter.
// Can't make above option work as desired. Rolling back to the option below.
if (facetField == null) {
facetField = SearchUtils.getConfig().getString("solr.facets.default", "dc.title");
}
return facetField;
}
public String[] getParameterFacetQueries() {
Request request = ObjectModelHelper.getRequest(objectModel);
return request.getParameterValues("fq") != null ? request.getParameterValues("fq") : new String[0];
}
public String getParameterStartsWith() {
String s = ObjectModelHelper.getRequest(objectModel).getParameter(STARTS_WITH);
return s != null ? s : "";
}
protected String getParameterView() {
String s = ObjectModelHelper.getRequest(objectModel).getParameter(VIEW);
return s != null ? s : VIEW_TYPES[0];
}
protected int getParameterPage() {
try {
int page = Integer.parseInt(ObjectModelHelper.getRequest(objectModel).getParameter(PAGE));
return page > 0 ? page : 1;
}
catch (Exception e) {
return 1;
}
}
protected int getParameterRpp() {
try {
int rpp = Integer.parseInt(ObjectModelHelper.getRequest(objectModel).getParameter(RESULTS_PER_PAGE));
return rpp > 0 ? rpp : DEFAULT_PAGE_SIZE;
}
catch (Exception e) {
return DEFAULT_PAGE_SIZE;
}
}
protected String getParameterSortBy() {
String s = ObjectModelHelper.getRequest(objectModel).getParameter(SORT_BY);
// return s != null ? s : DEFAULT_SORT_BY;
return config.getPropertyAsType("solr.browse.sort", DEFAULT_SORT_BY);
}
// protected String getParameterGroup() {
// String s = ObjectModelHelper.getRequest(objectModel).getParameter("group_by");
// return s != null ? s : "none";
// }
protected SolrQuery.ORDER getParameterOrder() {
String s = ObjectModelHelper.getRequest(objectModel).getParameter(ORDER);
return s != null ? SolrQuery.ORDER.valueOf(s.toLowerCase()) : DEFAULT_ORDER;
}
}