mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
[DSCR-22] Discovery module back end rewrite to support discovery without solr.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/trunk@6463 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -38,18 +38,6 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.solr</groupId>
|
|
||||||
<artifactId>solr-solrj</artifactId>
|
|
||||||
<version>1.4.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -121,4 +109,4 @@
|
|||||||
</developerConnection>
|
</developerConnection>
|
||||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider</url>
|
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider</url>
|
||||||
</scm>
|
</scm>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -0,0 +1,51 @@
|
|||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a filter query for discovery and can contain the following objects:
|
||||||
|
* The field in which we are searching
|
||||||
|
* The query the query which the filter query is using
|
||||||
|
* The displayed value
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DiscoverFilterQuery {
|
||||||
|
|
||||||
|
private String field;
|
||||||
|
private String filterQuery;
|
||||||
|
private String displayedValue;
|
||||||
|
|
||||||
|
|
||||||
|
public DiscoverFilterQuery() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoverFilterQuery(String field, String filterQuery, String displayedValue) {
|
||||||
|
this.field = field;
|
||||||
|
this.filterQuery = filterQuery;
|
||||||
|
this.displayedValue = displayedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(String field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterQuery(String filterQuery) {
|
||||||
|
this.filterQuery = filterQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayedValue(String displayedValue) {
|
||||||
|
this.displayedValue = displayedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilterQuery() {
|
||||||
|
return filterQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayedValue() {
|
||||||
|
return displayedValue;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,279 @@
|
|||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a query which the discovery backend can use
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DiscoverQuery {
|
||||||
|
|
||||||
|
/** Main attributes for the discovery query **/
|
||||||
|
private String query;
|
||||||
|
private List<String> filterQueries;
|
||||||
|
private int DSpaceObjectFilter = -1;
|
||||||
|
private List<String> fieldPresentQueries;
|
||||||
|
|
||||||
|
private int start = 0;
|
||||||
|
private int maxResults = -1;
|
||||||
|
|
||||||
|
/** Attributes used for sorting of results **/
|
||||||
|
public enum SORT_ORDER {
|
||||||
|
desc,
|
||||||
|
asc
|
||||||
|
}
|
||||||
|
private String sortField;
|
||||||
|
private SORT_ORDER sortOrder;
|
||||||
|
|
||||||
|
/** Attributes required for the faceting of values **/
|
||||||
|
private List<FacetFieldConfig> facetFields;
|
||||||
|
private List<String> facetQueries;
|
||||||
|
private int facetLimit = -1;
|
||||||
|
private int facetMinCount = -1;
|
||||||
|
private int facetOffset = 0;
|
||||||
|
public enum FACET_SORT {
|
||||||
|
INDEX,
|
||||||
|
COUNT
|
||||||
|
}
|
||||||
|
private FACET_SORT facetSort;
|
||||||
|
|
||||||
|
/** Used when you want to search for a specific field value **/
|
||||||
|
private List<String> searchFields;
|
||||||
|
|
||||||
|
/** Misc attributes can be implementation dependent **/
|
||||||
|
private Map<String, List<String>> properties;
|
||||||
|
|
||||||
|
public DiscoverQuery() {
|
||||||
|
//Initialize all our lists
|
||||||
|
this.filterQueries = new ArrayList<String>();
|
||||||
|
this.fieldPresentQueries = new ArrayList<String>();
|
||||||
|
|
||||||
|
this.facetFields = new ArrayList<FacetFieldConfig>();
|
||||||
|
this.facetQueries = new ArrayList<String>();
|
||||||
|
this.searchFields = new ArrayList<String>();
|
||||||
|
//Use a linked hashmap since sometimes insertion order might matter
|
||||||
|
this.properties = new LinkedHashMap<String, List<String>>();
|
||||||
|
this.facetSort = FACET_SORT.COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart(int start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSortField(String sortField, SORT_ORDER sortOrder){
|
||||||
|
this.sortField = sortField;
|
||||||
|
this.sortOrder = sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSortField() {
|
||||||
|
return sortField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SORT_ORDER getSortOrder() {
|
||||||
|
return sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the DSpace object filter, must be an DSpace Object type integer
|
||||||
|
* can be used to only return objects from a certain DSpace Object type
|
||||||
|
* @param DSpaceObjectFilter the DSpace object filer
|
||||||
|
*/
|
||||||
|
public void setDSpaceObjectFilter(int DSpaceObjectFilter) {
|
||||||
|
this.DSpaceObjectFilter = DSpaceObjectFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the DSpace object filter
|
||||||
|
* can be used to only return objects from a certain DSpace Object type
|
||||||
|
* @return the DSpace object filer
|
||||||
|
*/
|
||||||
|
public int getDSpaceObjectFilter() {
|
||||||
|
return DSpaceObjectFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of results returned by this query
|
||||||
|
* @return the number of results
|
||||||
|
*/
|
||||||
|
public int getMaxResults() {
|
||||||
|
return maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum number of results by this query
|
||||||
|
* @param maxResults the number of results
|
||||||
|
*/
|
||||||
|
public void setMaxResults(int maxResults) {
|
||||||
|
this.maxResults = maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds new filter queries
|
||||||
|
* @param filterQueries the filter queries to be added
|
||||||
|
*/
|
||||||
|
public void addFilterQueries(String ...filterQueries){
|
||||||
|
this.filterQueries.addAll(Arrays.asList(filterQueries));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the filter queries
|
||||||
|
* @return the filter queries in a list
|
||||||
|
*/
|
||||||
|
public List<String> getFilterQueries() {
|
||||||
|
return filterQueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a query that will ensure that a certain field is present in the index
|
||||||
|
* @param fieldPresentQueries the queries to be added
|
||||||
|
*/
|
||||||
|
public void addFieldPresentQueries(String ...fieldPresentQueries){
|
||||||
|
this.fieldPresentQueries.addAll(Arrays.asList(fieldPresentQueries));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFieldPresentQueries() {
|
||||||
|
return fieldPresentQueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new facet query
|
||||||
|
* @param facetQuery the new facet query to be added
|
||||||
|
*/
|
||||||
|
public void addFacetQuery(String facetQuery){
|
||||||
|
this.facetQueries.add(facetQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the facet queries
|
||||||
|
* @return the facet queries for this query
|
||||||
|
*/
|
||||||
|
public List<String> getFacetQueries() {
|
||||||
|
return facetQueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new facet field
|
||||||
|
* @param facetField the new facet field to be added
|
||||||
|
*/
|
||||||
|
public void addFacetField(FacetFieldConfig facetField){
|
||||||
|
facetFields.add(facetField);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the facets fields configured
|
||||||
|
* @return the facet fields for this query
|
||||||
|
*/
|
||||||
|
public List<FacetFieldConfig> getFacetFields() {
|
||||||
|
return facetFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum number of values that need to be present before a valid facet value has been found
|
||||||
|
* @return facetMinCount the minimum number of values to be present for a valid facet
|
||||||
|
*/
|
||||||
|
public int getFacetMinCount() {
|
||||||
|
return facetMinCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the minimum number of values that need to be present before a valid facet value has been found
|
||||||
|
* @param facetMinCount the minimum number of values to be present for a valid facet
|
||||||
|
*/
|
||||||
|
public void setFacetMinCount(int facetMinCount) {
|
||||||
|
this.facetMinCount = facetMinCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of facet values that can be returned for one facet field
|
||||||
|
* @return how many facet values will be returned
|
||||||
|
*/
|
||||||
|
public int getFacetLimit() {
|
||||||
|
return facetLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets maximum number of facet values that can be returned for one facet field
|
||||||
|
* @param facetLimit how many facet values will be returned
|
||||||
|
*/
|
||||||
|
public void setFacetLimit(int facetLimit) {
|
||||||
|
this.facetLimit = facetLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the facet field offset
|
||||||
|
* @return the facet field offset
|
||||||
|
*/
|
||||||
|
public int getFacetOffset() {
|
||||||
|
return facetOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the facet field offset, one facet offset will be used for all the facet fields
|
||||||
|
* @param facetOffset an integer representing the offset
|
||||||
|
*/
|
||||||
|
public void setFacetOffset(int facetOffset) {
|
||||||
|
this.facetOffset = facetOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sort order for the facets
|
||||||
|
* @return the sort order for the facets
|
||||||
|
*/
|
||||||
|
public FACET_SORT getFacetSort() {
|
||||||
|
return facetSort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sort order for the facets
|
||||||
|
* @param facetSort the sort order for the facets
|
||||||
|
*/
|
||||||
|
public void setFacetSort(FACET_SORT facetSort) {
|
||||||
|
this.facetSort = facetSort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSearchField(String field){
|
||||||
|
this.searchFields.add(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSearchFields() {
|
||||||
|
return searchFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the misc search properties
|
||||||
|
* @return a map containing the properties
|
||||||
|
*/
|
||||||
|
public Map<String, List<String>> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new search property to the misc search properties
|
||||||
|
* @param property the name of the property
|
||||||
|
* @param value the value of the property
|
||||||
|
*/
|
||||||
|
public void addProperty(String property, String value){
|
||||||
|
List<String> toAddList = properties.get(property);
|
||||||
|
if(toAddList == null)
|
||||||
|
toAddList = new ArrayList<String>();
|
||||||
|
|
||||||
|
toAddList.add(value);
|
||||||
|
|
||||||
|
properties.put(property, toAddList);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,164 @@
|
|||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the result that the discovery search impl returns
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoverResult {
|
||||||
|
|
||||||
|
private long totalSearchResults;
|
||||||
|
private int start;
|
||||||
|
private List<DSpaceObject> dspaceObjects;
|
||||||
|
private Map<String, List<FacetResult>> facetResults;
|
||||||
|
/** A map that contains all the documents sougth after, the key is a string representation of the DSpace object */
|
||||||
|
private Map<String, List<SearchDocument>> searchDocuments;
|
||||||
|
private int maxResults = -1;
|
||||||
|
|
||||||
|
|
||||||
|
public DiscoverResult() {
|
||||||
|
dspaceObjects = new ArrayList<DSpaceObject>();
|
||||||
|
facetResults = new LinkedHashMap<String, List<FacetResult>>();
|
||||||
|
searchDocuments = new LinkedHashMap<String, List<SearchDocument>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addDSpaceObject(DSpaceObject dso){
|
||||||
|
this.dspaceObjects.add(dso);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DSpaceObject> getDspaceObjects() {
|
||||||
|
return dspaceObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalSearchResults() {
|
||||||
|
return totalSearchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalSearchResults(long totalSearchResults) {
|
||||||
|
this.totalSearchResults = totalSearchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart(int start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxResults() {
|
||||||
|
return maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxResults(int maxResults) {
|
||||||
|
this.maxResults = maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFacetResult(String facetField, FacetResult ...facetResults){
|
||||||
|
List<FacetResult> facetValues = this.facetResults.get(facetField);
|
||||||
|
if(facetValues == null)
|
||||||
|
{
|
||||||
|
facetValues = new ArrayList<FacetResult>();
|
||||||
|
}
|
||||||
|
facetValues.addAll(Arrays.asList(facetResults));
|
||||||
|
this.facetResults.put(facetField, facetValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, List<FacetResult>> getFacetResults() {
|
||||||
|
return facetResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FacetResult> getFacetResult(String facet){
|
||||||
|
return facetResults.get(facet) == null ? new ArrayList<FacetResult>() : facetResults.get(facet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class FacetResult{
|
||||||
|
// TODO: rename storedValue to filterValue
|
||||||
|
private String asFilterQuery;
|
||||||
|
private String displayedValue;
|
||||||
|
private long count;
|
||||||
|
|
||||||
|
public FacetResult(String asFilterQuery, String displayedValue, long count) {
|
||||||
|
this.asFilterQuery = asFilterQuery;
|
||||||
|
this.displayedValue = displayedValue;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAsFilterQuery() {
|
||||||
|
return asFilterQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayedValue() {
|
||||||
|
return displayedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSearchDocument(DSpaceObject dso, SearchDocument searchDocument){
|
||||||
|
String dsoString = SearchDocument.getDspaceObjectStringRepresentation(dso);
|
||||||
|
List<SearchDocument> docs = searchDocuments.get(dsoString);
|
||||||
|
if(docs == null){
|
||||||
|
docs = new ArrayList<SearchDocument>();
|
||||||
|
}
|
||||||
|
docs.add(searchDocument);
|
||||||
|
searchDocuments.put(dsoString, docs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the sought after search document values
|
||||||
|
* @param dso the dspace object we want our search documents for
|
||||||
|
* @return the search documents list
|
||||||
|
*/
|
||||||
|
public List<SearchDocument> getSearchDocument(DSpaceObject dso){
|
||||||
|
String dsoString = SearchDocument.getDspaceObjectStringRepresentation(dso);
|
||||||
|
List<SearchDocument> result = searchDocuments.get(dsoString);
|
||||||
|
if(result == null){
|
||||||
|
return new ArrayList<SearchDocument>();
|
||||||
|
}else{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains values from the fields searched for in DiscoveryQuery.java
|
||||||
|
*/
|
||||||
|
public static final class SearchDocument{
|
||||||
|
private Map<String, List<String>> searchFields;
|
||||||
|
|
||||||
|
public SearchDocument() {
|
||||||
|
this.searchFields = new LinkedHashMap<String, List<String>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSearchField(String field, String ...values){
|
||||||
|
List<String>searchFieldValues = searchFields.get(field);
|
||||||
|
if(searchFieldValues == null){
|
||||||
|
searchFieldValues = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
searchFieldValues.addAll(Arrays.asList(values));
|
||||||
|
searchFields.put(field, searchFieldValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, List<String>> getSearchFields() {
|
||||||
|
return searchFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSearchFieldValues(String field){
|
||||||
|
if(searchFields.get(field) == null)
|
||||||
|
return new ArrayList<String>();
|
||||||
|
else
|
||||||
|
return searchFields.get(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDspaceObjectStringRepresentation(DSpaceObject dso){
|
||||||
|
return dso.getType() + ":" + dso.getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
package org.dspace.discovery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class contains all the data that can be configured for a facet field
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class FacetFieldConfig {
|
||||||
|
private String field;
|
||||||
|
private boolean isDate;
|
||||||
|
/* The facet prefix, all facet values will have to start with the given prefix */
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
public FacetFieldConfig(String field, boolean date) {
|
||||||
|
this.field = field;
|
||||||
|
isDate = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FacetFieldConfig(String field, boolean date, String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.field = field;
|
||||||
|
isDate = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDate() {
|
||||||
|
return isDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
}
|
@@ -34,7 +34,6 @@ public class IndexClient {
|
|||||||
* @param args the command-line arguments, none used
|
* @param args the command-line arguments, none used
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
* @throws java.sql.SQLException
|
* @throws java.sql.SQLException
|
||||||
* @throws org.apache.solr.client.solrj.SolrServerException
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) throws SQLException, IOException, SearchServiceException {
|
public static void main(String[] args) throws SQLException, IOException, SearchServiceException {
|
||||||
@@ -78,7 +77,7 @@ public class IndexClient {
|
|||||||
"print this help message").create("h"));
|
"print this help message").create("h"));
|
||||||
|
|
||||||
options.addOption(OptionBuilder.isRequired(false).withDescription(
|
options.addOption(OptionBuilder.isRequired(false).withDescription(
|
||||||
"optimize search solr core").create("o"));
|
"optimize search core").create("o"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
line = new PosixParser().parse(options, args);
|
line = new PosixParser().parse(options, args);
|
||||||
|
@@ -7,15 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.discovery;
|
package org.dspace.discovery;
|
||||||
|
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search interface that discovery to search in solr
|
* Search interface that discovery uses
|
||||||
*
|
*
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
@@ -23,9 +22,33 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface SearchService {
|
public interface SearchService {
|
||||||
|
|
||||||
QueryResponse search(SolrQuery query) throws SearchServiceException;
|
DiscoverResult search(Context context, DiscoverQuery query) throws SearchServiceException;
|
||||||
|
|
||||||
|
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query) throws SearchServiceException;
|
||||||
|
|
||||||
|
String searchJSON(DiscoverQuery query, String jsonIdentifier) throws SearchServiceException;
|
||||||
|
|
||||||
|
|
||||||
List<DSpaceObject> search(Context context, String query, int offset, int max, String... filterquery);
|
|
||||||
|
|
||||||
List<DSpaceObject> search(Context context, String query, String orderfield, boolean ascending, int offset, int max, String... filterquery);
|
List<DSpaceObject> search(Context context, String query, String orderfield, boolean ascending, int offset, int max, String... filterquery);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the given string into a filter query
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param filterQuery the filter query
|
||||||
|
* @return a filter query object
|
||||||
|
* @throws java.sql.SQLException ...
|
||||||
|
*/
|
||||||
|
DiscoverFilterQuery toFilterQuery(Context context, String filterQuery) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the given string field and value into a filter query
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param field the field of the filter query
|
||||||
|
* @param value the filter query value
|
||||||
|
* @return a filter query
|
||||||
|
* @throws SQLException ...
|
||||||
|
*/
|
||||||
|
DiscoverFilterQuery toFilterQuery(Context context, String field, String value) throws SQLException;
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
package org.dspace.discovery;
|
package org.dspace.discovery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception used by discovery when solr exceptions occur
|
* Exception used by discovery when discovery search exceptions occur
|
||||||
*
|
*
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
@@ -9,16 +9,12 @@ package org.dspace.discovery;
|
|||||||
|
|
||||||
import org.apache.commons.collections.ExtendedProperties;
|
import org.apache.commons.collections.ExtendedProperties;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.content.DSpaceObject;
|
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.utils.DSpace;
|
||||||
import org.dspace.handle.HandleManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,18 +30,24 @@ public class SearchUtils {
|
|||||||
|
|
||||||
private static ExtendedProperties props = null;
|
private static ExtendedProperties props = null;
|
||||||
|
|
||||||
private static Map<String, SolrFacetConfig[]> solrFacets = new HashMap<String, SolrFacetConfig[]>();
|
private static Map<String, FacetFieldConfig[]> fieldFacets = new HashMap<String, FacetFieldConfig[]>();
|
||||||
|
|
||||||
private static List<String> allFacets = new ArrayList<String>();
|
private static List<String> allFacets = new ArrayList<String>();
|
||||||
|
|
||||||
private static List<String> searchFilters = new ArrayList<String>();
|
private static List<String> searchFilters = new ArrayList<String>();
|
||||||
|
|
||||||
|
private static List<String> searchFiltersFullAutocomplete = new ArrayList<String>();
|
||||||
|
|
||||||
private static List<String> sortFields = new ArrayList<String>();
|
private static List<String> sortFields = new ArrayList<String>();
|
||||||
|
|
||||||
private static List<String> dateIndexableFields = new ArrayList<String>();
|
private static List<String> dateIndexableFields = new ArrayList<String>();
|
||||||
|
|
||||||
public static final String FILTER_SEPARATOR = "|||";
|
public static final String FILTER_SEPARATOR = "|||";
|
||||||
|
|
||||||
|
|
||||||
|
/** Cached search service **/
|
||||||
|
private static SearchService searchService;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
||||||
log.debug("loading configuration");
|
log.debug("loading configuration");
|
||||||
@@ -61,7 +63,7 @@ public class SearchUtils {
|
|||||||
} else {
|
} else {
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
is = SolrServiceImpl.class.getResourceAsStream("dspace-solr-search.cfg");
|
is = SearchUtils.class.getResourceAsStream("dspace-solr-search.cfg");
|
||||||
ExtendedProperties defaults = new ExtendedProperties();
|
ExtendedProperties defaults = new ExtendedProperties();
|
||||||
defaults.load(is);
|
defaults.load(is);
|
||||||
props.combine(defaults);
|
props.combine(defaults);
|
||||||
@@ -87,30 +89,39 @@ public class SearchUtils {
|
|||||||
log.info("loading scope, " + propName);
|
log.info("loading scope, " + propName);
|
||||||
|
|
||||||
allFacets.addAll(Arrays.asList(propVals));
|
allFacets.addAll(Arrays.asList(propVals));
|
||||||
List<SolrFacetConfig> facets = new ArrayList<SolrFacetConfig>();
|
List<FacetFieldConfig> facets = new ArrayList<FacetFieldConfig>();
|
||||||
for (String propVal : propVals) {
|
for (String propVal : propVals) {
|
||||||
if (propVal.endsWith("_dt") || propVal.endsWith(".year")) {
|
if (propVal.endsWith("_dt") || propVal.endsWith(".year")) {
|
||||||
facets.add(new SolrFacetConfig(propVal.replace("_dt", ".year"), true));
|
facets.add(new FacetFieldConfig(propVal.replace("_dt", ".year"), true));
|
||||||
|
|
||||||
log.info("value, " + propVal);
|
log.info("value, " + propVal);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
facets.add(new SolrFacetConfig(propVal + "_filter", false));
|
facets.add(new FacetFieldConfig(propVal + "_filter", false));
|
||||||
|
|
||||||
log.info("value, " + propVal);
|
log.info("value, " + propVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//All the values are split into date & facetfields, so now store em
|
//All the values are split into date & facetfields, so now store em
|
||||||
solrFacets.put(propName.replace("solr.facets.", ""), facets.toArray(new SolrFacetConfig[facets.size()]));
|
fieldFacets.put(propName.replace("solr.facets.", ""), facets.toArray(new FacetFieldConfig[facets.size()]));
|
||||||
|
|
||||||
log.info("solrFacets size: " + solrFacets.size());
|
log.info("fieldFacets size: " + fieldFacets.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] filterFieldsProps = SearchUtils.getConfig().getStringArray("solr.search.filters");
|
String[] filterFieldsProps = SearchUtils.getConfig().getStringArray("solr.search.filters");
|
||||||
if (filterFieldsProps != null) {
|
if (filterFieldsProps != null) {
|
||||||
searchFilters.addAll(Arrays.asList(filterFieldsProps));
|
for (String filterProp : filterFieldsProps) {
|
||||||
|
if(filterProp.endsWith(":full")){
|
||||||
|
String field = filterProp.substring(0, filterProp.lastIndexOf(":"));
|
||||||
|
searchFiltersFullAutocomplete.add(field);
|
||||||
|
searchFilters.add(field);
|
||||||
|
}else{
|
||||||
|
searchFilters.add(filterProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] sortFieldProps = SearchUtils.getConfig().getStringArray("solr.search.sort");
|
String[] sortFieldProps = SearchUtils.getConfig().getStringArray("solr.search.sort");
|
||||||
@@ -131,8 +142,8 @@ public class SearchUtils {
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SolrFacetConfig[] getFacetsForType(String type) {
|
public static FacetFieldConfig[] getFacetsForType(String type) {
|
||||||
return solrFacets.get(type);
|
return fieldFacets.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getAllFacets() {
|
public static List<String> getAllFacets() {
|
||||||
@@ -143,24 +154,14 @@ public class SearchUtils {
|
|||||||
return searchFilters;
|
return searchFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isNonTokenizedSearchFilter(String field){
|
||||||
|
return searchFiltersFullAutocomplete.contains(field);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> getSortFields() {
|
public static List<String> getSortFields() {
|
||||||
return sortFields;
|
return sortFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DSpaceObject findDSpaceObject(Context context, SolrDocument doc) throws SQLException {
|
|
||||||
|
|
||||||
Integer type = (Integer) doc.getFirstValue("search.resourcetype");
|
|
||||||
Integer id = (Integer) doc.getFirstValue("search.resourceid");
|
|
||||||
String handle = (String) doc.getFirstValue("handle");
|
|
||||||
|
|
||||||
if (type != null && id != null) {
|
|
||||||
return DSpaceObject.find(context, type, id);
|
|
||||||
} else if (handle != null) {
|
|
||||||
return HandleManager.resolveToObject(context, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String[] getDefaultFilters(String scope) {
|
public static String[] getDefaultFilters(String scope) {
|
||||||
@@ -192,37 +193,14 @@ public class SearchUtils {
|
|||||||
return dateIndexableFields;
|
return dateIndexableFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFilterQueryDisplay(String filterQuery){
|
public static SearchService getSearchService()
|
||||||
String separator = SearchUtils.getConfig().getString("solr.facets.split.char", SearchUtils.FILTER_SEPARATOR);
|
{
|
||||||
//Escape any regex chars
|
if(searchService == null){
|
||||||
separator = java.util.regex.Pattern.quote(separator);
|
DSpace dspace = new DSpace();
|
||||||
String[] fqParts = filterQuery.split(separator);
|
org.dspace.kernel.ServiceManager manager = dspace.getServiceManager() ;
|
||||||
String result = "";
|
searchService = manager.getServiceByName(SearchService.class.getName(),SearchService.class);
|
||||||
int start = fqParts.length / 2;
|
|
||||||
for(int i = start; i < fqParts.length; i++){
|
|
||||||
result += fqParts[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SolrFacetConfig {
|
|
||||||
|
|
||||||
private String facetField;
|
|
||||||
private boolean isDate;
|
|
||||||
|
|
||||||
public SolrFacetConfig(String facetField, boolean date) {
|
|
||||||
this.facetField = facetField;
|
|
||||||
isDate = date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFacetField() {
|
|
||||||
return facetField;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDate() {
|
|
||||||
return isDate;
|
|
||||||
}
|
}
|
||||||
|
return searchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,17 +7,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.discovery;
|
package org.dspace.discovery;
|
||||||
|
|
||||||
import org.apache.commons.collections.ExtendedProperties;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.time.DateFormatUtils;
|
import org.apache.commons.lang.time.DateFormatUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.SolrServerException;
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
|
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
|
||||||
|
import org.apache.solr.client.solrj.response.FacetField;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
import org.apache.solr.common.SolrDocument;
|
import org.apache.solr.common.SolrDocument;
|
||||||
import org.apache.solr.common.SolrDocumentList;
|
import org.apache.solr.common.SolrDocumentList;
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.apache.solr.common.params.CommonParams;
|
||||||
|
import org.apache.solr.common.params.FacetParams;
|
||||||
import org.dspace.content.*;
|
import org.dspace.content.*;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
@@ -32,6 +36,7 @@ import org.springframework.beans.factory.annotation.Required;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -665,6 +670,8 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
indexItemFieldCustom(doc, item, field, value);
|
||||||
|
|
||||||
//Add the field to all for autocomplete so our autocomplete works for all fields
|
//Add the field to all for autocomplete so our autocomplete works for all fields
|
||||||
doc.addField("all_ac", value);
|
doc.addField("all_ac", value);
|
||||||
|
|
||||||
@@ -696,6 +703,9 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
if(SearchUtils.getSearchFilters().contains(field) || SearchUtils.getSearchFilters().contains(unqualifiedField + "." + Item.ANY)){
|
if(SearchUtils.getSearchFilters().contains(field) || SearchUtils.getSearchFilters().contains(unqualifiedField + "." + Item.ANY)){
|
||||||
//Add a dynamic fields for autocomplete in search
|
//Add a dynamic fields for autocomplete in search
|
||||||
doc.addField(field + "_ac", value);
|
doc.addField(field + "_ac", value);
|
||||||
|
if(SearchUtils.isNonTokenizedSearchFilter(field) || SearchUtils.isNonTokenizedSearchFilter(unqualifiedField + "." + Item.ANY)){
|
||||||
|
doc.addField(field + "_ac.full", value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SearchUtils.getAllFacets().contains(field) || SearchUtils.getAllFacets().contains(unqualifiedField + "." + Item.ANY)){
|
if(SearchUtils.getAllFacets().contains(field) || SearchUtils.getAllFacets().contains(unqualifiedField + "." + Item.ANY)){
|
||||||
@@ -814,6 +824,18 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that can be overriden to handle special metadata indexing tasks
|
||||||
|
* @param doc the solr input document
|
||||||
|
* @param item the DSpace item that is beeing indexed
|
||||||
|
* @param field the metadata field which we are indexing
|
||||||
|
* @param value the metadata value which we are indexing
|
||||||
|
* @return whether or not to continue indexing the metadata value
|
||||||
|
*/
|
||||||
|
public boolean indexItemFieldCustom(SolrInputDocument doc, Item item, String field, String value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Lucene document with all the shared fields initialized.
|
* Create Lucene document with all the shared fields initialized.
|
||||||
*
|
*
|
||||||
@@ -931,16 +953,319 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//******** SearchService implementation
|
//******** SearchService implementation
|
||||||
public QueryResponse search(SolrQuery query) throws SearchServiceException {
|
public DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery discoveryQuery) throws SearchServiceException {
|
||||||
|
if(dso != null){
|
||||||
|
if (dso instanceof Community) {
|
||||||
|
discoveryQuery.addFilterQueries("location:m" + dso.getID());
|
||||||
|
} else if (dso instanceof Collection) {
|
||||||
|
discoveryQuery.addFilterQueries("location:l" + dso.getID());
|
||||||
|
} else if (dso instanceof Item){
|
||||||
|
discoveryQuery.addFilterQueries("handle:" + dso.getHandle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return search(context, discoveryQuery);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DiscoverResult search(Context context, DiscoverQuery discoveryQuery) throws SearchServiceException {
|
||||||
try {
|
try {
|
||||||
return getSolr().query(query);
|
SolrQuery solrQuery = new SolrQuery();
|
||||||
|
|
||||||
|
String query = "*:*";
|
||||||
|
if(discoveryQuery.getQuery() != null){
|
||||||
|
query = discoveryQuery.getQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
solrQuery.setQuery(query);
|
||||||
|
|
||||||
|
for (int i = 0; i < discoveryQuery.getFilterQueries().size(); i++) {
|
||||||
|
String filterQuery = discoveryQuery.getFilterQueries().get(i);
|
||||||
|
solrQuery.addFilterQuery(prepareFilterQuery(filterQuery));
|
||||||
|
}
|
||||||
|
if(discoveryQuery.getDSpaceObjectFilter() != -1){
|
||||||
|
solrQuery.addFilterQuery("search.resourcetype:" + discoveryQuery.getDSpaceObjectFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < discoveryQuery.getFieldPresentQueries().size(); i++) {
|
||||||
|
String filterQuery = discoveryQuery.getFieldPresentQueries().get(i);
|
||||||
|
solrQuery.addFilterQuery(filterQuery + ":[* TO *]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discoveryQuery.getStart() != -1){
|
||||||
|
solrQuery.setStart(discoveryQuery.getStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discoveryQuery.getMaxResults() != -1){
|
||||||
|
solrQuery.setRows(discoveryQuery.getMaxResults());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discoveryQuery.getSortField() != null){
|
||||||
|
SolrQuery.ORDER order = SolrQuery.ORDER.asc;
|
||||||
|
if(discoveryQuery.getSortOrder().equals(DiscoverQuery.SORT_ORDER.desc))
|
||||||
|
order = SolrQuery.ORDER.desc;
|
||||||
|
|
||||||
|
solrQuery.addSortField(discoveryQuery.getSortField(), order);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String property : discoveryQuery.getProperties().keySet()){
|
||||||
|
List<String> values = discoveryQuery.getProperties().get(property);
|
||||||
|
solrQuery.add(property, values.toArray(new String[values.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<FacetFieldConfig> facetFields = discoveryQuery.getFacetFields();
|
||||||
|
if(0 < facetFields.size()){
|
||||||
|
//Only add facet information if there are any facets
|
||||||
|
for (FacetFieldConfig facetFieldConfig : facetFields) {
|
||||||
|
solrQuery.addFacetField(facetFieldConfig.getField());
|
||||||
|
if(facetFieldConfig.getPrefix() != null){
|
||||||
|
solrQuery.setFacetPrefix(facetFieldConfig.getField(), facetFieldConfig.getPrefix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> facetQueries = discoveryQuery.getFacetQueries();
|
||||||
|
for (String facetQuery : facetQueries) {
|
||||||
|
solrQuery.addFacetQuery(facetQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discoveryQuery.getFacetLimit() != -1){
|
||||||
|
solrQuery.setFacetLimit(discoveryQuery.getFacetLimit());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(discoveryQuery.getFacetMinCount() != -1){
|
||||||
|
solrQuery.setFacetMinCount(discoveryQuery.getFacetMinCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
solrQuery.setParam(FacetParams.FACET_OFFSET, String.valueOf(discoveryQuery.getFacetOffset()));
|
||||||
|
|
||||||
|
if(discoveryQuery.getFacetSort() == DiscoverQuery.FACET_SORT.COUNT){
|
||||||
|
solrQuery.setFacetSort(FacetParams.FACET_SORT_COUNT);
|
||||||
|
} else {
|
||||||
|
solrQuery.setFacetSort(FacetParams.FACET_SORT_INDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QueryResponse queryResponse = getSolr().query(solrQuery);
|
||||||
|
return retrieveResult(context, discoveryQuery, queryResponse);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new org.dspace.discovery.SearchServiceException(e.getMessage(),e);
|
throw new org.dspace.discovery.SearchServiceException(e.getMessage(),e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String searchJSON(DiscoverQuery query, String jsonIdentifier) throws SearchServiceException {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
|
||||||
|
String solrRequestUrl = solr.getBaseURL() + "/select";
|
||||||
|
|
||||||
|
//Add our default parameters
|
||||||
|
params.put(CommonParams.ROWS, "0");
|
||||||
|
params.put(CommonParams.WT, "json");
|
||||||
|
//We uwe json as out output type
|
||||||
|
params.put("json.nl", "map");
|
||||||
|
params.put("json.wrf", jsonIdentifier);
|
||||||
|
params.put(FacetParams.FACET, Boolean.TRUE.toString());
|
||||||
|
|
||||||
|
//Generate our json out of the given params
|
||||||
|
try
|
||||||
|
{
|
||||||
|
params.put(CommonParams.Q, URLEncoder.encode(query.getQuery(), org.dspace.constants.Constants.DEFAULT_ENCODING));
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException uee)
|
||||||
|
{
|
||||||
|
//Should never occur
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(query.getFacetSort() == DiscoverQuery.FACET_SORT.COUNT){
|
||||||
|
params.put(FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT);
|
||||||
|
} else {
|
||||||
|
params.put(FacetParams.FACET_SORT, FacetParams.FACET_SORT_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.put(FacetParams.FACET_LIMIT, String.valueOf(query.getFacetLimit()));
|
||||||
|
|
||||||
|
params.put(FacetParams.FACET_MINCOUNT, String.valueOf(query.getFacetMinCount()));
|
||||||
|
|
||||||
|
solrRequestUrl = generateURL(solrRequestUrl, params);
|
||||||
|
if (query.getFacetFields() != null || query.getFilterQueries() != null) {
|
||||||
|
StringBuilder urlBuilder = new StringBuilder(solrRequestUrl);
|
||||||
|
if(query.getFacetFields() != null){
|
||||||
|
|
||||||
|
//Add our facet fields
|
||||||
|
for (FacetFieldConfig facetFieldConfig : query.getFacetFields()) {
|
||||||
|
urlBuilder.append("&").append(FacetParams.FACET_FIELD).append("=");
|
||||||
|
|
||||||
|
//This class can only be used for autocomplete facet fields
|
||||||
|
if(!facetFieldConfig.getField().endsWith(".year") && !facetFieldConfig.getField().endsWith("_ac"))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
String field;
|
||||||
|
if(SearchUtils.isNonTokenizedSearchFilter(facetFieldConfig.getField())){
|
||||||
|
field = facetFieldConfig.getField() + "_ac.full";
|
||||||
|
}else{
|
||||||
|
field = facetFieldConfig.getField() + "_ac";
|
||||||
|
}
|
||||||
|
|
||||||
|
urlBuilder.append(URLEncoder.encode(field, org.dspace.constants.Constants.DEFAULT_ENCODING));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
//Ignore this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
urlBuilder.append(URLEncoder.encode(facetFieldConfig.getField(), org.dspace.constants.Constants.DEFAULT_ENCODING));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
//Ignore this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(query.getFilterQueries() != null){
|
||||||
|
for (String filterQuery : query.getFilterQueries()) {
|
||||||
|
try {
|
||||||
|
urlBuilder.append("&").append(CommonParams.FQ).append("=").append(URLEncoder.encode(filterQuery, org.dspace.constants.Constants.DEFAULT_ENCODING));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
//Ignore this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
solrRequestUrl = urlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
GetMethod get = new GetMethod(solrRequestUrl);
|
||||||
|
new HttpClient().executeMethod(get);
|
||||||
|
return get.getResponseBodyAsString();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while getting json solr result for discovery search recommendation", e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateURL(String baseURL, Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
boolean first = true;
|
||||||
|
for (String key : parameters.keySet())
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
baseURL += "?";
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
baseURL += "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
baseURL += key + "=" + parameters.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String prepareFilterQuery(String filterQuery) {
|
||||||
|
//Ensure that range queries or specified field queries do not get a wildcard at the end
|
||||||
|
if(!filterQuery.matches(".*\\:\\[.* TO .*\\](?![a-z 0-9]).*") && !filterQuery.matches(".*:\".*\"$") && !filterQuery.endsWith("*")){
|
||||||
|
filterQuery = filterQuery + " OR " + filterQuery + "*";
|
||||||
|
}
|
||||||
|
return filterQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DiscoverResult retrieveResult(Context context, DiscoverQuery query, QueryResponse solrQueryResponse) throws SQLException {
|
||||||
|
DiscoverResult result = new DiscoverResult();
|
||||||
|
|
||||||
|
if(solrQueryResponse != null){
|
||||||
|
result.setStart(query.getStart());
|
||||||
|
result.setMaxResults(query.getMaxResults());
|
||||||
|
result.setTotalSearchResults(solrQueryResponse.getResults().getNumFound());
|
||||||
|
|
||||||
|
List<String> searchFields = query.getSearchFields();
|
||||||
|
for (SolrDocument doc : solrQueryResponse.getResults()) {
|
||||||
|
DSpaceObject dso = findDSpaceObject(context, doc);
|
||||||
|
|
||||||
|
if(dso != null){
|
||||||
|
result.addDSpaceObject(dso);
|
||||||
|
} else {
|
||||||
|
//TODO: Log this !
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscoverResult.SearchDocument resultDoc = new DiscoverResult.SearchDocument();
|
||||||
|
//Add information about our search fields
|
||||||
|
for (String field : searchFields){
|
||||||
|
List<String> valuesAsString = new ArrayList<String>();
|
||||||
|
for (Object o : doc.getFieldValues(field)) {
|
||||||
|
valuesAsString.add(String.valueOf(o));
|
||||||
|
}
|
||||||
|
resultDoc.addSearchField(field, valuesAsString.toArray(new String[valuesAsString.size()]));
|
||||||
|
}
|
||||||
|
result.addSearchDocument(dso, resultDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Resolve our facet field values
|
||||||
|
List<FacetField> facetFields = solrQueryResponse.getFacetFields();
|
||||||
|
if(facetFields != null){
|
||||||
|
for (FacetField facetField : facetFields) {
|
||||||
|
List<FacetField.Count> facetValues = facetField.getValues();
|
||||||
|
if(facetValues != null){
|
||||||
|
for (FacetField.Count facetValue : facetValues) {
|
||||||
|
String displayedValue = transformDisplayedValue(context, facetField.getName(), facetValue.getName());
|
||||||
|
result.addFacetResult(facetField.getName(), new DiscoverResult.FacetResult(facetValue.getAsFilterQuery(), displayedValue, facetValue.getCount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(solrQueryResponse.getFacetQuery() != null){
|
||||||
|
//TODO: do not sort when not a date, just retrieve the facets in the order they where requested !
|
||||||
|
//At the moment facet queries are only used for dates so we need to sort our results
|
||||||
|
TreeMap<String, Integer> sortedFacetQueries = new TreeMap<String, Integer>(solrQueryResponse.getFacetQuery());
|
||||||
|
for(String facetQuery : sortedFacetQueries.descendingKeySet()){
|
||||||
|
//TODO: do not assume this, people may want to use it for other ends, use a regex to make sure
|
||||||
|
//We have a facet query, the values looks something like: dateissued.year:[1990 TO 2000] AND -2000
|
||||||
|
//Prepare the string from {facet.field.name}:[startyear TO endyear] to startyear - endyear
|
||||||
|
String facetField = facetQuery.substring(0, facetQuery.indexOf(":"));
|
||||||
|
String name = facetQuery.substring(facetQuery.indexOf('[') + 1);
|
||||||
|
name = name.substring(0, name.lastIndexOf(']')).replaceAll("TO", "-");
|
||||||
|
Integer count = sortedFacetQueries.get(facetQuery);
|
||||||
|
|
||||||
|
//No need to show empty years
|
||||||
|
if(0 < count){
|
||||||
|
result.addFacetResult(facetField, new DiscoverResult.FacetResult(facetQuery, name, count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DSpaceObject findDSpaceObject(Context context, SolrDocument doc) throws SQLException {
|
||||||
|
|
||||||
|
Integer type = (Integer) doc.getFirstValue("search.resourcetype");
|
||||||
|
Integer id = (Integer) doc.getFirstValue("search.resourceid");
|
||||||
|
String handle = (String) doc.getFirstValue("handle");
|
||||||
|
|
||||||
|
if (type != null && id != null) {
|
||||||
|
return DSpaceObject.find(context, type, id);
|
||||||
|
} else if (handle != null) {
|
||||||
|
return HandleManager.resolveToObject(context, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Simple means to return the search result as an InputStream */
|
/** Simple means to return the search result as an InputStream */
|
||||||
public java.io.InputStream searchAsInputStream(SolrQuery query) throws SearchServiceException, java.io.IOException {
|
public java.io.InputStream searchAsInputStream(DiscoverQuery query) throws SearchServiceException, java.io.IOException {
|
||||||
try {
|
try {
|
||||||
org.apache.commons.httpclient.methods.GetMethod method =
|
org.apache.commons.httpclient.methods.GetMethod method =
|
||||||
new org.apache.commons.httpclient.methods.GetMethod(getSolr().getHttpClient().getHostConfiguration().getHostURL() + "");
|
new org.apache.commons.httpclient.methods.GetMethod(getSolr().getHttpClient().getHostConfiguration().getHostURL() + "");
|
||||||
@@ -998,4 +1323,70 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DiscoverFilterQuery toFilterQuery(Context context, String filterQuery) throws SQLException {
|
||||||
|
DiscoverFilterQuery result = new DiscoverFilterQuery();
|
||||||
|
|
||||||
|
//TODO: what if user enters something with a ":" in it
|
||||||
|
String field = filterQuery;
|
||||||
|
String value = filterQuery;
|
||||||
|
|
||||||
|
if(filterQuery.contains(":"))
|
||||||
|
{
|
||||||
|
field = filterQuery.substring(0, filterQuery.indexOf(":"));
|
||||||
|
value = filterQuery.substring(filterQuery.indexOf(":") + 1, filterQuery.length());
|
||||||
|
}else{
|
||||||
|
//We have got no field, so we are using everything
|
||||||
|
field = "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value.replace("\\", "");
|
||||||
|
if("*".equals(field))
|
||||||
|
{
|
||||||
|
field = "all";
|
||||||
|
}
|
||||||
|
if(filterQuery.startsWith("*:") || filterQuery.startsWith(":"))
|
||||||
|
{
|
||||||
|
filterQuery = filterQuery.substring(filterQuery.indexOf(":") + 1, filterQuery.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
value = transformDisplayedValue(context, field, value);
|
||||||
|
|
||||||
|
result.setField(field);
|
||||||
|
result.setFilterQuery(filterQuery);
|
||||||
|
result.setDisplayedValue(value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoverFilterQuery toFilterQuery(Context context, String field, String value) throws SQLException{
|
||||||
|
DiscoverFilterQuery result = new DiscoverFilterQuery();
|
||||||
|
|
||||||
|
result.setField(field);
|
||||||
|
result.setDisplayedValue(transformDisplayedValue(context, field, value));
|
||||||
|
// TODO: solr escape of value ?
|
||||||
|
result.setFilterQuery((field == null || field.equals("") ? "" : field + ":") + "\"" + value + "\"");
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String transformDisplayedValue(Context context, String field, String value) throws SQLException {
|
||||||
|
if(field.equals("location.comm") || field.equals("location.coll")){
|
||||||
|
value = locationToName(context, field, value);
|
||||||
|
}else
|
||||||
|
if(field.endsWith("_filter")){
|
||||||
|
//We have a filter make sure we split !
|
||||||
|
String separator = SearchUtils.getConfig().getString("solr.facets.split.char", SearchUtils.FILTER_SEPARATOR);
|
||||||
|
//Escape any regex chars
|
||||||
|
separator = java.util.regex.Pattern.quote(separator);
|
||||||
|
String[] fqParts = value.split(separator);
|
||||||
|
StringBuffer valueBuffer = new StringBuffer();
|
||||||
|
int start = fqParts.length / 2;
|
||||||
|
for(int i = start; i < fqParts.length; i++){
|
||||||
|
valueBuffer.append(fqParts[i]);
|
||||||
|
}
|
||||||
|
value = valueBuffer.toString();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -27,4 +27,4 @@
|
|||||||
<bean class="org.dspace.discovery.SolrServiceImpl" id="org.dspace.discovery.SearchService"/>
|
<bean class="org.dspace.discovery.SolrServiceImpl" id="org.dspace.discovery.SearchService"/>
|
||||||
|
|
||||||
<alias name="org.dspace.discovery.SearchService" alias="org.dspace.discovery.IndexingService"/>
|
<alias name="org.dspace.discovery.SearchService" alias="org.dspace.discovery.IndexingService"/>
|
||||||
</beans>
|
</beans>
|
@@ -0,0 +1,144 @@
|
|||||||
|
package org.dspace.app.xmlui.aspect.discovery;
|
||||||
|
|
||||||
|
import org.apache.cocoon.caching.CacheableProcessingComponent;
|
||||||
|
import org.apache.cocoon.util.HashUtil;
|
||||||
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
|
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
||||||
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.discovery.*;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract class containing the shared methods which all recent submission transformers use
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
*/
|
||||||
|
public abstract class AbstractRecentSubmissionTransformer extends AbstractDSpaceTransformer implements CacheableProcessingComponent {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(AbstractRecentSubmissionTransformer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached query results
|
||||||
|
*/
|
||||||
|
protected DiscoverResult queryResults;
|
||||||
|
|
||||||
|
/** Cached validity object */
|
||||||
|
private SourceValidity validity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* The validity object all recently submitted items.
|
||||||
|
* This does not include the community / collection
|
||||||
|
* hierarchy, when this changes they will not be reflected in the cache.
|
||||||
|
*/
|
||||||
|
public SourceValidity getValidity()
|
||||||
|
{
|
||||||
|
if (this.validity == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
|
||||||
|
DSpaceValidity validity = new DSpaceValidity();
|
||||||
|
|
||||||
|
// Add the actual collection;
|
||||||
|
validity.add(dso);
|
||||||
|
|
||||||
|
getRecentlySubmittedItems(dso);
|
||||||
|
if(queryResults != null){
|
||||||
|
List<DSpaceObject> resultingObjects = queryResults.getDspaceObjects();
|
||||||
|
for(DSpaceObject resultObject : resultingObjects){
|
||||||
|
validity.add(resultObject);
|
||||||
|
}
|
||||||
|
validity.add("numFound:" + resultingObjects.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.validity = validity.complete();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Just ignore all errors and return an invalid cache.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.validity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract String getView();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the recent submitted items of the given scope
|
||||||
|
*
|
||||||
|
* @param dso the DSpace object can either be null (indicating home page), a collection or a community
|
||||||
|
*/
|
||||||
|
protected void getRecentlySubmittedItems(DSpaceObject dso) {
|
||||||
|
|
||||||
|
if(queryResults != null)
|
||||||
|
{
|
||||||
|
return; // queryResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DiscoverQuery queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
|
queryArgs.addFilterQueries(SearchUtils.getDefaultFilters(getView()));
|
||||||
|
queryArgs.setDSpaceObjectFilter(Constants.ITEM);
|
||||||
|
|
||||||
|
queryArgs.setMaxResults(SearchUtils.getConfig().getInt("solr.recent-submissions.size", 5));
|
||||||
|
|
||||||
|
String sortField = SearchUtils.getConfig().getString("recent.submissions.sort-option");
|
||||||
|
if(sortField != null){
|
||||||
|
queryArgs.setSortField(
|
||||||
|
sortField,
|
||||||
|
DiscoverQuery.SORT_ORDER.desc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchService service = SearchUtils.getSearchService();
|
||||||
|
queryResults = service.search(context, dso, queryArgs);
|
||||||
|
}catch (SearchServiceException se){
|
||||||
|
log.error("Caught SearchServiceException while retrieving recent submission for: " + getView(), se);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recycle() {
|
||||||
|
queryResults = null;
|
||||||
|
validity = null;
|
||||||
|
super.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,13 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.xmlui.aspect.discovery;
|
package org.dspace.app.xmlui.aspect.discovery;
|
||||||
|
|
||||||
|
import org.apache.cocoon.caching.CacheableProcessingComponent;
|
||||||
import org.apache.cocoon.environment.ObjectModelHelper;
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
import org.apache.cocoon.util.HashUtil;
|
import org.apache.cocoon.util.HashUtil;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.apache.solr.common.SolrDocumentList;
|
|
||||||
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
||||||
import org.dspace.app.xmlui.utils.HandleUtil;
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
import org.dspace.app.xmlui.utils.UIException;
|
import org.dspace.app.xmlui.utils.UIException;
|
||||||
@@ -26,6 +26,7 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
import org.dspace.discovery.*;
|
import org.dspace.discovery.*;
|
||||||
|
import org.dspace.handle.HandleManager;
|
||||||
import org.dspace.sort.SortOption;
|
import org.dspace.sort.SortOption;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ import java.util.List;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
public abstract class AbstractSearch extends AbstractDSpaceTransformer implements CacheableProcessingComponent{
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(AbstractSearch.class);
|
private static final Logger log = Logger.getLogger(AbstractSearch.class);
|
||||||
|
|
||||||
@@ -86,6 +87,16 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
|
|
||||||
private static final Message T_rpp = message("xmlui.ArtifactBrowser.AbstractSearch.rpp");
|
private static final Message T_rpp = message("xmlui.ArtifactBrowser.AbstractSearch.rpp");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached query results
|
||||||
|
*/
|
||||||
|
protected DiscoverResult queryResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached query arguments
|
||||||
|
*/
|
||||||
|
protected DiscoverQuery queryArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The options for results per page
|
* The options for results per page
|
||||||
*/
|
*/
|
||||||
@@ -147,15 +158,24 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
|
|
||||||
performSearch(scope);
|
performSearch(scope);
|
||||||
|
|
||||||
SolrDocumentList results = this.queryResults.getResults();
|
List<DSpaceObject> results = this.queryResults.getDspaceObjects();
|
||||||
|
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
validity.add("total:"+results.getNumFound());
|
validity.add("total:"+this.queryResults.getTotalSearchResults());
|
||||||
validity.add("start:"+results.getStart());
|
validity.add("start:"+this.queryResults.getStart());
|
||||||
validity.add("size:" + results.size());
|
validity.add("size:" + results.size());
|
||||||
|
|
||||||
for (SolrDocument result : results) {
|
for (DSpaceObject dso : results) {
|
||||||
validity.add(result.toString());
|
validity.add(dso);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, List<DiscoverResult.FacetResult>> facetResults = this.queryResults.getFacetResults();
|
||||||
|
for(String facetField : facetResults.keySet()){
|
||||||
|
List<DiscoverResult.FacetResult> facetValues = facetResults.get(facetField);
|
||||||
|
for (DiscoverResult.FacetResult facetResult : facetValues)
|
||||||
|
{
|
||||||
|
validity.add(facetResult.getAsFilterQuery() + facetResult.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +211,7 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
throws IOException, SQLException, WingException, SearchServiceException {
|
throws IOException, SQLException, WingException, SearchServiceException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (queryResults == null || queryResults.getResults() == null) {
|
if (queryResults == null) {
|
||||||
|
|
||||||
DSpaceObject scope = getScope();
|
DSpaceObject scope = getScope();
|
||||||
this.performSearch(scope);
|
this.performSearch(scope);
|
||||||
@@ -208,7 +228,7 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
|
|
||||||
if (queryResults != null) {
|
if (queryResults != null) {
|
||||||
search.addPara("result-query", "result-query")
|
search.addPara("result-query", "result-query")
|
||||||
.addContent(T_result_query.parameterize(getQuery(), queryResults.getResults().getNumFound()));
|
.addContent(T_result_query.parameterize(getQuery(), queryResults.getTotalSearchResults()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Division results = search.addDivision("search-results", "primary");
|
Division results = search.addDivision("search-results", "primary");
|
||||||
@@ -227,20 +247,18 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
results.setHead(T_head1_none);
|
results.setHead(T_head1_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryResults != null &&
|
if (queryResults != null && 0< queryResults.getDspaceObjects().size())
|
||||||
queryResults.getResults().getNumFound() > 0) {
|
{
|
||||||
|
|
||||||
SolrDocumentList solrResults = queryResults.getResults();
|
|
||||||
|
|
||||||
// Pagination variables.
|
// Pagination variables.
|
||||||
int itemsTotal = (int) solrResults.getNumFound();
|
int itemsTotal = (int) queryResults.getTotalSearchResults();
|
||||||
int firstItemIndex = (int) solrResults.getStart() + 1;
|
int firstItemIndex = (int) this.queryResults.getStart() + 1;
|
||||||
int lastItemIndex = (int) solrResults.getStart() + solrResults.size();
|
int lastItemIndex = (int) this.queryResults.getStart() + queryResults.getDspaceObjects().size();
|
||||||
|
|
||||||
//if (itemsTotal < lastItemIndex)
|
//if (itemsTotal < lastItemIndex)
|
||||||
// lastItemIndex = itemsTotal;
|
// lastItemIndex = itemsTotal;
|
||||||
int currentPage = (int) (solrResults.getStart() / this.queryArgs.getRows()) + 1;
|
int currentPage = (int) (this.queryResults.getStart() / this.queryResults.getMaxResults()) + 1;
|
||||||
int pagesTotal = (int) ((solrResults.getNumFound() - 1) / this.queryArgs.getRows()) + 1;
|
int pagesTotal = (int) ((this.queryResults.getTotalSearchResults() - 1) / this.queryResults.getMaxResults()) + 1;
|
||||||
Map<String, String> parameters = new HashMap<String, String>();
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
parameters.put("page", "{pageNum}");
|
parameters.put("page", "{pageNum}");
|
||||||
String pageURLMask = generateURL(parameters);
|
String pageURLMask = generateURL(parameters);
|
||||||
@@ -261,20 +279,16 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
// Look for any communities or collections in the mix
|
// Look for any communities or collections in the mix
|
||||||
ReferenceSet referenceSet = null;
|
ReferenceSet referenceSet = null;
|
||||||
|
|
||||||
for (SolrDocument doc : solrResults) {
|
for (DSpaceObject resultDso : queryResults.getDspaceObjects())
|
||||||
|
{
|
||||||
DSpaceObject resultDSO =
|
if (resultDso instanceof Community || resultDso instanceof Collection) {
|
||||||
SearchUtils.findDSpaceObject(context, doc);
|
|
||||||
|
|
||||||
if (resultDSO instanceof Community
|
|
||||||
|| resultDSO instanceof Collection) {
|
|
||||||
if (referenceSet == null) {
|
if (referenceSet == null) {
|
||||||
referenceSet = results.addReferenceSet("search-results-repository",
|
referenceSet = results.addReferenceSet("search-results-repository",
|
||||||
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
||||||
// Set a heading showing that we will be listing containers that matched:
|
// Set a heading showing that we will be listing containers that matched:
|
||||||
referenceSet.setHead(T_head2);
|
referenceSet.setHead(T_head2);
|
||||||
}
|
}
|
||||||
referenceSet.addReference(resultDSO);
|
referenceSet.addReference(resultDso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,12 +298,11 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
||||||
|
|
||||||
|
|
||||||
for (SolrDocument doc : solrResults) {
|
for (DSpaceObject resultDso : queryResults.getDspaceObjects())
|
||||||
|
{
|
||||||
DSpaceObject resultDSO = SearchUtils.findDSpaceObject(context, doc);
|
if (resultDso instanceof Item)
|
||||||
|
{
|
||||||
if (resultDSO instanceof Item) {
|
referenceSet.addReference(resultDso);
|
||||||
referenceSet.addReference(resultDSO);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,14 +387,7 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
|
|
||||||
List<String> filterQueries = new ArrayList<String>();
|
List<String> filterQueries = new ArrayList<String>();
|
||||||
|
|
||||||
if (scope instanceof Community) {
|
String[] fqs = getFilterQueries();
|
||||||
filterQueries.add("location:m" + scope.getID());
|
|
||||||
|
|
||||||
} else if (scope instanceof Collection) {
|
|
||||||
filterQueries.add("location:l" + scope.getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] fqs = getSolrFilterQueries();
|
|
||||||
|
|
||||||
if (fqs != null)
|
if (fqs != null)
|
||||||
{
|
{
|
||||||
@@ -389,14 +395,16 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
queryArgs = this.prepareDefaultFilters("search", filterQueries.toArray(new String[filterQueries.size()]));
|
this.queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
|
queryArgs.addFilterQueries(SearchUtils.getDefaultFilters(getView()));
|
||||||
|
|
||||||
if (filterQueries.size() > 0) {
|
if (filterQueries.size() > 0) {
|
||||||
queryArgs.addFilterQuery(filterQueries.toArray(new String[filterQueries.size()]));
|
queryArgs.addFilterQueries(filterQueries.toArray(new String[filterQueries.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
queryArgs.setRows(getParameterRpp());
|
queryArgs.setMaxResults(getParameterRpp());
|
||||||
|
|
||||||
String sortBy = ObjectModelHelper.getRequest(objectModel).getParameter("sort_by");
|
String sortBy = ObjectModelHelper.getRequest(objectModel).getParameter("sort_by");
|
||||||
|
|
||||||
@@ -411,14 +419,14 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
if (sortBy != null) {
|
if (sortBy != null) {
|
||||||
if (sortOrder == null || sortOrder.equals("DESC"))
|
if (sortOrder == null || sortOrder.equals("DESC"))
|
||||||
{
|
{
|
||||||
queryArgs.addSortField(sortBy, SolrQuery.ORDER.desc);
|
queryArgs.setSortField(sortBy, DiscoverQuery.SORT_ORDER.desc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
queryArgs.addSortField(sortBy, SolrQuery.ORDER.asc);
|
queryArgs.setSortField(sortBy, DiscoverQuery.SORT_ORDER.asc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
queryArgs.addSortField("score", SolrQuery.ORDER.asc);
|
queryArgs.setSortField("score", DiscoverQuery.SORT_ORDER.asc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -428,26 +436,26 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
// Enable groupBy collapsing if designated
|
// Enable groupBy collapsing if designated
|
||||||
if (groupBy != null && !groupBy.equalsIgnoreCase("none")) {
|
if (groupBy != null && !groupBy.equalsIgnoreCase("none")) {
|
||||||
/** Construct a Collapse Field Query */
|
/** Construct a Collapse Field Query */
|
||||||
queryArgs.add("collapse.field", groupBy);
|
queryArgs.addProperty("collapse.field", groupBy);
|
||||||
queryArgs.add("collapse.threshold", "1");
|
queryArgs.addProperty("collapse.threshold", "1");
|
||||||
queryArgs.add("collapse.includeCollapsedDocs.fl", "handle");
|
queryArgs.addProperty("collapse.includeCollapsedDocs.fl", "handle");
|
||||||
queryArgs.add("collapse.facet", "before");
|
queryArgs.addProperty("collapse.facet", "before");
|
||||||
|
|
||||||
//queryArgs.a type:Article^2
|
//queryArgs.a type:Article^2
|
||||||
|
|
||||||
// TODO: This is a hack to get Publications (Articles) to always be at the top of Groups.
|
// TODO: This is a hack to get Publications (Articles) to always be at the top of Groups.
|
||||||
// TODO: I think the can be more transparently done in the solr solrconfig.xml with DISMAX and boosting
|
// TODO: I think the can be more transparently done in the solr solrconfig.xml with DISMAX and boosting
|
||||||
/** sort in groups to get publications to top */
|
/** sort in groups to get publications to top */
|
||||||
queryArgs.addSortField("dc.type", SolrQuery.ORDER.asc);
|
queryArgs.setSortField("dc.type", DiscoverQuery.SORT_ORDER.asc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
queryArgs.setQuery(query != null && !query.trim().equals("") ? query : "*:*");
|
queryArgs.setQuery(query != null && !query.trim().equals("") ? query : null);
|
||||||
|
|
||||||
if (page > 1)
|
if (page > 1)
|
||||||
{
|
{
|
||||||
queryArgs.setStart((page - 1) * queryArgs.getRows());
|
queryArgs.setStart((page - 1) * queryResults.getMaxResults());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -509,7 +517,7 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.queryResults = getSearchService().search(queryArgs);
|
this.queryResults = SearchUtils.getSearchService().search(context, scope, queryArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -532,7 +540,7 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
* This method returns more expanded filter queries then the getParameterFilterQueries
|
* This method returns more expanded filter queries then the getParameterFilterQueries
|
||||||
* @return an array containing the filter queries
|
* @return an array containing the filter queries
|
||||||
*/
|
*/
|
||||||
protected String[] getSolrFilterQueries() {
|
protected String[] getFilterQueries() {
|
||||||
try {
|
try {
|
||||||
return ObjectModelHelper.getRequest(objectModel).getParameterValues("fq");
|
return ObjectModelHelper.getRequest(objectModel).getParameterValues("fq");
|
||||||
}
|
}
|
||||||
@@ -628,6 +636,8 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
* Recycle
|
* Recycle
|
||||||
*/
|
*/
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
|
this.queryArgs = null;
|
||||||
|
this.queryResults = null;
|
||||||
this.validity = null;
|
this.validity = null;
|
||||||
super.recycle();
|
super.recycle();
|
||||||
}
|
}
|
||||||
@@ -635,11 +645,6 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
|
|
||||||
protected void buildSearchControls(Division div)
|
protected void buildSearchControls(Division div)
|
||||||
throws WingException {
|
throws WingException {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Table controlsTable = div.addTable("search-controls", 1, 3);
|
Table controlsTable = div.addTable("search-controls", 1, 3);
|
||||||
//Table controlsTable = div.addTable("search-controls", 1, 4);
|
//Table controlsTable = div.addTable("search-controls", 1, 4);
|
||||||
Row controlsRow = controlsTable.addRow(Row.ROLE_DATA);
|
Row controlsRow = controlsTable.addRow(Row.ROLE_DATA);
|
||||||
@@ -710,6 +715,33 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the current scope. This may be derived from the current url
|
||||||
|
* handle if present or the scope parameter is given. If no scope is
|
||||||
|
* specified then null is returned.
|
||||||
|
*
|
||||||
|
* @return The current scope.
|
||||||
|
*/
|
||||||
|
private DSpaceObject getScope() throws SQLException {
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
String scopeString = request.getParameter("scope");
|
||||||
|
|
||||||
|
// Are we in a community or collection?
|
||||||
|
DSpaceObject dso;
|
||||||
|
if (scopeString == null || "".equals(scopeString))
|
||||||
|
{
|
||||||
|
// get the search scope from the url handle
|
||||||
|
dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get the search scope from the location parameter
|
||||||
|
dso = HandleManager.resolveToObject(context, scopeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dso;
|
||||||
|
}
|
||||||
|
|
||||||
protected void logSearch() {
|
protected void logSearch() {
|
||||||
int countCommunities = 0;
|
int countCommunities = 0;
|
||||||
int countCollections = 0;
|
int countCollections = 0;
|
||||||
@@ -750,7 +782,9 @@ public abstract class AbstractSearch extends AbstractFiltersTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.info(LogManager.getHeader(context, "search", logInfo + "query=\""
|
log.info(LogManager.getHeader(context, "search", logInfo + "query=\""
|
||||||
+ queryArgs.getQuery() + "\",results=(" + countCommunities + ","
|
+ (queryArgs == null ? "" : queryArgs.getQuery()) + "\",results=(" + countCommunities + ","
|
||||||
+ countCollections + "," + countItems + ")"));
|
+ countCollections + "," + countItems + ")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract String getView();
|
||||||
}
|
}
|
||||||
|
@@ -26,13 +26,8 @@ import org.apache.cocoon.util.HashUtil;
|
|||||||
import org.apache.cocoon.environment.Request;
|
import org.apache.cocoon.environment.Request;
|
||||||
import org.apache.cocoon.environment.ObjectModelHelper;
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
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.apache.log4j.Logger;
|
||||||
|
import org.dspace.core.Context;
|
||||||
import org.dspace.discovery.*;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
@@ -42,8 +37,6 @@ import java.io.Serializable;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -63,7 +56,7 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
/**
|
/**
|
||||||
* The cache of recently submitted items
|
* The cache of recently submitted items
|
||||||
*/
|
*/
|
||||||
protected QueryResponse queryResults;
|
protected DiscoverResult queryResults;
|
||||||
/**
|
/**
|
||||||
* Cached validity object
|
* Cached validity object
|
||||||
*/
|
*/
|
||||||
@@ -72,7 +65,7 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
/**
|
/**
|
||||||
* Cached query arguments
|
* Cached query arguments
|
||||||
*/
|
*/
|
||||||
protected SolrQuery queryArgs;
|
protected DiscoverQuery queryArgs;
|
||||||
|
|
||||||
private int DEFAULT_PAGE_SIZE = 10;
|
private int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
@@ -134,23 +127,20 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add reciently submitted items, serialize solr query contents.
|
// add reciently submitted items, serialize solr query contents.
|
||||||
QueryResponse response = getQueryResponse(dso);
|
DiscoverResult response = getQueryResponse(dso);
|
||||||
|
|
||||||
validity.add("numFound:" + response.getResults().getNumFound());
|
validity.add("numFound:" + response.getDspaceObjects().size());
|
||||||
|
|
||||||
for (SolrDocument doc : response.getResults()) {
|
for (DSpaceObject resultDso : response.getDspaceObjects()) {
|
||||||
validity.add(doc.toString());
|
validity.add(resultDso);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SolrDocument doc : response.getResults()) {
|
for (String facetField : response.getFacetResults().keySet()) {
|
||||||
validity.add(doc.toString());
|
validity.add(facetField);
|
||||||
}
|
|
||||||
|
|
||||||
for (FacetField field : response.getFacetFields()) {
|
List<DiscoverResult.FacetResult> facetValues = response.getFacetResults().get(facetField);
|
||||||
validity.add(field.getName());
|
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
||||||
|
validity.add(facetValue.getAsFilterQuery() + facetValue.getCount());
|
||||||
for (FacetField.Count count : field.getValues()) {
|
|
||||||
validity.add(count.getName() + count.getCount());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +161,7 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
*
|
*
|
||||||
* @param scope The collection.
|
* @param scope The collection.
|
||||||
*/
|
*/
|
||||||
protected QueryResponse getQueryResponse(DSpaceObject scope) {
|
protected DiscoverResult getQueryResponse(DSpaceObject scope) {
|
||||||
|
|
||||||
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
@@ -181,24 +171,24 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
return queryResults;
|
return queryResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryArgs = new SolrQuery();
|
queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
//Make sure we add our default filters
|
//Make sure we add our default filters
|
||||||
queryArgs.addFilterQuery(SearchUtils.getDefaultFilters("browse"));
|
queryArgs.addFilterQueries(SearchUtils.getDefaultFilters("browse"));
|
||||||
|
|
||||||
|
|
||||||
queryArgs.setQuery("search.resourcetype: " + Constants.ITEM + ((request.getParameter("query") != null && !"".equals(request.getParameter("query"))) ? " AND (" + request.getParameter("query") + ")" : ""));
|
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.setQuery("search.resourcetype:" + Constants.ITEM);
|
||||||
|
|
||||||
queryArgs.setRows(0);
|
queryArgs.setMaxResults(0);
|
||||||
|
|
||||||
|
|
||||||
// TODO: change this !
|
// TODO: change this !
|
||||||
queryArgs.setSortField(
|
queryArgs.setSortField(
|
||||||
ConfigurationManager.getProperty("recent.submissions.sort-option"),
|
ConfigurationManager.getProperty("recent.submissions.sort-option"),
|
||||||
SolrQuery.ORDER.asc
|
DiscoverQuery.SORT_ORDER.asc
|
||||||
);
|
);
|
||||||
queryArgs.addFilterQuery(getParameterFacetQueries());
|
queryArgs.addFilterQueries(getParameterFacetQueries());
|
||||||
|
|
||||||
|
|
||||||
//Set the default limit to 11
|
//Set the default limit to 11
|
||||||
@@ -207,85 +197,26 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
|
|
||||||
//sort
|
//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 ?
|
//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(config.getPropertyAsType("solr.browse.sort","lex"));
|
// queryArgs.setFacetSort(config.getPropertyAsType("solr.browse.sort","lex"));
|
||||||
|
|
||||||
queryArgs.setFacet(true);
|
// queryArgs.setFacet(true);
|
||||||
|
|
||||||
int offset = RequestUtils.getIntParameter(request, OFFSET);
|
int offset = RequestUtils.getIntParameter(request, OFFSET);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
{
|
{
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
queryArgs.setParam(FacetParams.FACET_OFFSET, String.valueOf(offset));
|
queryArgs.setFacetOffset(offset);
|
||||||
|
|
||||||
//We add +1 so we can use the extra one to make sure that we need to show the next page
|
//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(DEFAULT_PAGE_SIZE + 1));
|
queryArgs.setFacetLimit(DEFAULT_PAGE_SIZE + 1);
|
||||||
|
|
||||||
|
|
||||||
if (scope != null) /* top level search / community */ {
|
|
||||||
if (scope instanceof Community) {
|
|
||||||
queryArgs.setFilterQueries("location:m" + scope.getID());
|
|
||||||
} else if (scope instanceof Collection) {
|
|
||||||
queryArgs.setFilterQueries("location:l" + scope.getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
String facetField = request.getParameter(FACET_FIELD);
|
|
||||||
boolean isDate = false;
|
|
||||||
if(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);
|
|
||||||
// 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){
|
|
||||||
//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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
System.out.println(startDate);
|
|
||||||
System.out.println(endDate);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
queryArgs.addFacetField(new FacetFieldConfig(request.getParameter(FACET_FIELD), false));
|
||||||
queryArgs.addFacetField(new String[]{facetField});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
queryResults = searchService.search(queryArgs);
|
queryResults = searchService.search(context, scope, queryArgs);
|
||||||
} catch (SearchServiceException e) {
|
} catch (SearchServiceException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@@ -300,21 +231,20 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
* @param filterquery the filterqueries
|
* @param filterquery the filterqueries
|
||||||
* @return the lowest date found, in a date object
|
* @return the lowest date found, in a date object
|
||||||
*/
|
*/
|
||||||
private Date getLowestDateValue(String query, String dateField, String... filterquery){
|
private Date getLowestDateValue(Context context, String query, String dateField, String... filterquery){
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SolrQuery solrQuery = new SolrQuery();
|
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||||
solrQuery.setQuery(query);
|
discoverQuery.setQuery(query);
|
||||||
solrQuery.setFields(dateField);
|
discoverQuery.setMaxResults(1);
|
||||||
solrQuery.setRows(1);
|
discoverQuery.setSortField(dateField, DiscoverQuery.SORT_ORDER.asc);
|
||||||
solrQuery.setSortField(dateField, SolrQuery.ORDER.asc);
|
discoverQuery.addFilterQueries(filterquery);
|
||||||
solrQuery.setFilterQueries(filterquery);
|
|
||||||
|
|
||||||
QueryResponse rsp = searchService.search(solrQuery);
|
DiscoverResult rsp = searchService.search(context, discoverQuery);
|
||||||
if(0 < rsp.getResults().getNumFound()){
|
// if(0 < rsp.getResults().getNumFound()){
|
||||||
return (Date) rsp.getResults().get(0).getFieldValue(dateField);
|
// return (Date) rsp.getResults().get(0).getFieldValue(dateField);
|
||||||
}
|
// }
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
log.error("Unable to get lowest date", e);
|
log.error("Unable to get lowest date", e);
|
||||||
}
|
}
|
||||||
@@ -358,37 +288,30 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
queryResults = getQueryResponse(dso);
|
queryResults = getQueryResponse(dso);
|
||||||
if (this.queryResults != null) {
|
if (this.queryResults != null) {
|
||||||
|
|
||||||
java.util.List<FacetField> facetFields = this.queryResults.getFacetFields();
|
Map<String, List<DiscoverResult.FacetResult>> facetFields = this.queryResults.getFacetResults();
|
||||||
if (facetFields == null)
|
if (facetFields == null)
|
||||||
{
|
{
|
||||||
facetFields = new ArrayList<FacetField>();
|
facetFields = new LinkedHashMap<String, List<DiscoverResult.FacetResult>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
facetFields.addAll(this.queryResults.getFacetDates());
|
// facetFields.addAll(this.queryResults.getFacetDates());
|
||||||
|
|
||||||
|
|
||||||
if (facetFields.size() > 0) {
|
if (facetFields.size() > 0) {
|
||||||
FacetField field = facetFields.get(0);
|
String facetField = String.valueOf(facetFields.keySet().toArray(new String[facetFields.size()])[0]);
|
||||||
java.util.List<FacetField.Count> values = field.getValues();
|
java.util.List<DiscoverResult.FacetResult> values = facetFields.get(facetField);
|
||||||
if(field.getGap() != null){
|
|
||||||
//We are dealing with dates so flip em, top date comes first
|
|
||||||
Collections.reverse(values);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values != null && 0 < values.size()) {
|
if (values != null && 0 < values.size()) {
|
||||||
|
|
||||||
|
|
||||||
Division results = body.addDivision("browse-by-" + field + "-results", "primary");
|
Division results = body.addDivision("browse-by-" + facetField + "-results", "primary");
|
||||||
|
|
||||||
results.setHead(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + request.getParameter(FACET_FIELD) + "_browse"));
|
results.setHead(message("xmlui.ArtifactBrowser.AbstractSearch.type_" + request.getParameter(FACET_FIELD) + "_browse"));
|
||||||
|
|
||||||
// Find our faceting offset
|
// Find our faceting offset
|
||||||
int offSet = 0;
|
int offSet = queryArgs.getFacetOffset();
|
||||||
try {
|
if(offSet == -1){
|
||||||
offSet = Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET));
|
offSet = 0;
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
//Ignore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only show the nextpageurl if we have at least one result following our current results
|
//Only show the nextpageurl if we have at least one result following our current results
|
||||||
@@ -398,11 +321,11 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
nextPageUrl = getNextPageURL(request);
|
nextPageUrl = getNextPageURL(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
results.setSimplePagination((int) queryResults.getResults().getNumFound(), offSet + 1,
|
results.setSimplePagination((int) queryResults.getDspaceObjects().size(), offSet + 1,
|
||||||
(offSet + (values.size() - 1)), getPreviousPageURL(request), nextPageUrl);
|
(offSet + (values.size() - 1)), getPreviousPageURL(request), nextPageUrl);
|
||||||
|
|
||||||
|
|
||||||
Table singleTable = results.addTable("browse-by-" + field + "-results", (int) (queryResults.getResults().getNumFound() + 1), 1);
|
Table singleTable = results.addTable("browse-by-" + facetField + "-results", (int) (queryResults.getDspaceObjects().size() + 1), 1);
|
||||||
|
|
||||||
List<String> filterQueries = new ArrayList<String>();
|
List<String> filterQueries = new ArrayList<String>();
|
||||||
if(request.getParameterValues("fq") != null)
|
if(request.getParameterValues("fq") != null)
|
||||||
@@ -410,20 +333,17 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
filterQueries = Arrays.asList(request.getParameterValues("fq"));
|
filterQueries = Arrays.asList(request.getParameterValues("fq"));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < values.size(); i++) {
|
for (int i = 0; i < values.size(); i++) {
|
||||||
FacetField.Count value = values.get(i);
|
DiscoverResult.FacetResult value = values.get(i);
|
||||||
|
|
||||||
String displayedValue = value.getName();
|
String displayedValue = value.getDisplayedValue();
|
||||||
String filterQuery = value.getAsFilterQuery();
|
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
|
// if(field.getGap() != null){
|
||||||
displayedValue = SolrServiceImpl.locationToName(context, field.getName(), displayedValue);
|
// //We have a date get the year so we can display it
|
||||||
}
|
// DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
||||||
if(field.getGap() != null){
|
// displayedValue = simpleDateformat.format(SolrServiceImpl.toDate(displayedValue));
|
||||||
//We have a date get the year so we can display it
|
// filterQuery = ClientUtils.escapeQueryChars(value.getFacetField().getName()) + ":" + displayedValue + "*";
|
||||||
DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
// }
|
||||||
displayedValue = simpleDateformat.format(SolrServiceImpl.toDate(displayedValue));
|
|
||||||
filterQuery = ClientUtils.escapeQueryChars(value.getFacetField().getName()) + ":" + displayedValue + "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
Cell cell = singleTable.addRow().addCell();
|
Cell cell = singleTable.addRow().addCell();
|
||||||
|
|
||||||
@@ -468,9 +388,9 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
private String getNextPageURL(Request request) {
|
private String getNextPageURL(Request request) {
|
||||||
Map<String, String> parameters = new HashMap<String, String>();
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
parameters.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
parameters.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
||||||
if (queryArgs.get(FacetParams.FACET_OFFSET) != null)
|
if (queryArgs.getFacetOffset() != -1)
|
||||||
{
|
{
|
||||||
parameters.put(OFFSET, String.valueOf(Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET)) + DEFAULT_PAGE_SIZE));
|
parameters.put(OFFSET, String.valueOf(queryArgs.getFacetOffset() + DEFAULT_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the filter queries
|
// Add the filter queries
|
||||||
@@ -490,16 +410,16 @@ public class BrowseFacet extends AbstractDSpaceTransformer implements CacheableP
|
|||||||
|
|
||||||
private String getPreviousPageURL(Request request) {
|
private String getPreviousPageURL(Request request) {
|
||||||
//If our offset should be 0 then we shouldn't be able to view a previous page url
|
//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)))
|
if (0 == queryArgs.getFacetOffset())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> parameters = new HashMap<String, String>();
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
parameters.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
parameters.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
||||||
if (queryArgs.get(FacetParams.FACET_OFFSET) != null)
|
if (queryArgs.getFacetOffset() != -1)
|
||||||
{
|
{
|
||||||
parameters.put(OFFSET, String.valueOf(Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET)) - DEFAULT_PAGE_SIZE));
|
parameters.put(OFFSET, String.valueOf(queryArgs.getFacetOffset() - DEFAULT_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the filter queries
|
// Add the filter queries
|
||||||
|
@@ -1,17 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* The contents of this file are subject to the license and copyright
|
* The contents of this file are subject to the license and copyright
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
* tree and available online at
|
* tree and avaiNlable online at
|
||||||
*
|
*
|
||||||
* http://www.dspace.org/license/
|
* http://www.dspace.org/license/
|
||||||
*/
|
*/
|
||||||
package org.dspace.app.xmlui.aspect.discovery;
|
package org.dspace.app.xmlui.aspect.discovery;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.dspace.core.Constants;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.app.xmlui.utils.HandleUtil;
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
import org.dspace.app.xmlui.wing.Message;
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
import org.dspace.app.xmlui.wing.WingException;
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
@@ -33,31 +28,34 @@ import java.sql.SQLException;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class CollectionRecentSubmissions extends AbstractFiltersTransformer {
|
public class CollectionRecentSubmissions extends AbstractRecentSubmissionTransformer {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(CollectionRecentSubmissions.class);
|
|
||||||
|
|
||||||
private static final Message T_head_recent_submissions =
|
private static final Message T_head_recent_submissions =
|
||||||
message("xmlui.ArtifactBrowser.CollectionViewer.head_recent_submissions");
|
message("xmlui.ArtifactBrowser.CollectionViewer.head_recent_submissions");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a single collection
|
* Displays the recent submissions for this collection
|
||||||
*/
|
*/
|
||||||
public void addBody(Body body) throws SAXException, WingException,
|
public void addBody(Body body) throws SAXException, WingException,
|
||||||
SQLException, IOException, AuthorizeException {
|
SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
|
||||||
// Set up the major variables
|
// Set up the major variables
|
||||||
Collection collection = (Collection) dso;
|
Collection collection = (Collection) dso;
|
||||||
|
if(!(dso instanceof Collection))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
performSearch(collection);
|
|
||||||
|
|
||||||
|
getRecentlySubmittedItems(collection);
|
||||||
|
|
||||||
|
//Only attempt to render our result if we have one.
|
||||||
if(queryResults == null)
|
if(queryResults == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}// queryResults;
|
}
|
||||||
|
|
||||||
// Build the collection viewer division.
|
// Build the collection viewer division.
|
||||||
Division home = body.addDivision("collection-home", "primary repository collection");
|
Division home = body.addDivision("collection-home", "primary repository collection");
|
||||||
@@ -71,48 +69,8 @@ public class CollectionRecentSubmissions extends AbstractFiltersTransformer {
|
|||||||
"collection-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
"collection-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
||||||
null, "recent-submissions");
|
null, "recent-submissions");
|
||||||
|
|
||||||
for (SolrDocument doc : queryResults.getResults()) {
|
for (DSpaceObject resultObj : queryResults.getDspaceObjects()) {
|
||||||
lastSubmitted.addReference(
|
lastSubmitted.addReference(resultObj);
|
||||||
SearchUtils.findDSpaceObject(context, doc));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the recently submitted items for the given community or collection.
|
|
||||||
*
|
|
||||||
* @param scope The comm/collection.
|
|
||||||
* @return the response of the query
|
|
||||||
*/
|
|
||||||
public void performSearch(DSpaceObject scope) {
|
|
||||||
if(queryResults != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}// queryResults;
|
|
||||||
|
|
||||||
queryArgs = prepareDefaultFilters(getView());
|
|
||||||
|
|
||||||
queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
|
|
||||||
|
|
||||||
queryArgs.setRows(SearchUtils.getConfig().getInt("solr.recent-submissions.size", 5));
|
|
||||||
|
|
||||||
String sortField = SearchUtils.getConfig().getString("recent.submissions.sort-option");
|
|
||||||
if(sortField != null){
|
|
||||||
queryArgs.setSortField(
|
|
||||||
sortField,
|
|
||||||
SolrQuery.ORDER.desc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
queryArgs.setFilterQueries("location:l" + scope.getID());
|
|
||||||
|
|
||||||
try {
|
|
||||||
queryResults = getSearchService().search(queryArgs);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,9 +10,6 @@ package org.dspace.app.xmlui.aspect.discovery;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.app.xmlui.utils.HandleUtil;
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
import org.dspace.app.xmlui.utils.UIException;
|
import org.dspace.app.xmlui.utils.UIException;
|
||||||
import org.dspace.app.xmlui.wing.Message;
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
@@ -23,8 +20,6 @@ import org.dspace.app.xmlui.wing.element.ReferenceSet;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.core.Constants;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,19 +29,13 @@ import org.xml.sax.SAXException;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class CommunityRecentSubmissions extends AbstractFiltersTransformer
|
public class CommunityRecentSubmissions extends AbstractRecentSubmissionTransformer {
|
||||||
{
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(CommunityRecentSubmissions.class);
|
|
||||||
|
|
||||||
private static final Message T_head_recent_submissions =
|
private static final Message T_head_recent_submissions =
|
||||||
message("xmlui.ArtifactBrowser.CollectionViewer.head_recent_submissions");
|
message("xmlui.ArtifactBrowser.CommunityViewer.head_recent_submissions");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a single community (and refrence any sub communites or
|
* Displays the recent submissions for this community
|
||||||
* collections)
|
|
||||||
*/
|
*/
|
||||||
public void addBody(Body body) throws SAXException, WingException,
|
public void addBody(Body body) throws SAXException, WingException,
|
||||||
UIException, SQLException, IOException, AuthorizeException
|
UIException, SQLException, IOException, AuthorizeException
|
||||||
@@ -61,7 +50,13 @@ public class CommunityRecentSubmissions extends AbstractFiltersTransformer
|
|||||||
// Build the community viewer division.
|
// Build the community viewer division.
|
||||||
Division home = body.addDivision("community-home", "primary repository community");
|
Division home = body.addDivision("community-home", "primary repository community");
|
||||||
|
|
||||||
performSearch(dso);
|
getRecentlySubmittedItems(dso);
|
||||||
|
|
||||||
|
//Only attempt to render our result if we have one.
|
||||||
|
if(queryResults == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Division lastSubmittedDiv = home
|
Division lastSubmittedDiv = home
|
||||||
.addDivision("community-recent-submission", "secondary recent-submission");
|
.addDivision("community-recent-submission", "secondary recent-submission");
|
||||||
@@ -72,56 +67,13 @@ public class CommunityRecentSubmissions extends AbstractFiltersTransformer
|
|||||||
"community-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
"community-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
||||||
null, "recent-submissions");
|
null, "recent-submissions");
|
||||||
|
|
||||||
for (SolrDocument doc : queryResults.getResults()) {
|
for (DSpaceObject resultObject : queryResults.getDspaceObjects()) {
|
||||||
lastSubmitted.addReference(SearchUtils.findDSpaceObject(context, doc));
|
lastSubmitted.addReference(resultObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the recently submitted items for the given community or collection.
|
|
||||||
*
|
|
||||||
* @param scope The comm/collection.
|
|
||||||
* @return the response of the query
|
|
||||||
*/
|
|
||||||
public void performSearch(DSpaceObject scope) {
|
|
||||||
|
|
||||||
|
|
||||||
if(queryResults != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}// queryResults;
|
|
||||||
|
|
||||||
queryArgs = prepareDefaultFilters(getView());
|
|
||||||
|
|
||||||
queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
|
|
||||||
|
|
||||||
queryArgs.setRows(SearchUtils.getConfig().getInt("solr.recent-submissions.size", 5));
|
|
||||||
|
|
||||||
String sortField = SearchUtils.getConfig().getString("recent.submissions.sort-option");
|
|
||||||
if(sortField != null){
|
|
||||||
queryArgs.setSortField(
|
|
||||||
sortField,
|
|
||||||
SolrQuery.ORDER.desc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* Set the communities facet filters */
|
|
||||||
queryArgs.setFilterQueries("location:m" + scope.getID());
|
|
||||||
|
|
||||||
try {
|
|
||||||
queryResults = getSearchService().search(queryArgs);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getView()
|
public String getView()
|
||||||
{
|
{
|
||||||
return "community";
|
return "community";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.app.xmlui.aspect.discovery;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class used to display facets for an item
|
|
||||||
*
|
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
|
||||||
* @author Mark Diggory (markd at atmire dot com)
|
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
|
||||||
*/
|
|
||||||
public class ItemFacets extends org.dspace.app.xmlui.aspect.discovery.AbstractFiltersTransformer
|
|
||||||
{
|
|
||||||
|
|
||||||
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(org.dspace.app.xmlui.aspect.discovery.ItemFacets.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a single item
|
|
||||||
*/
|
|
||||||
public void addBody(org.dspace.app.xmlui.wing.element.Body body) throws org.xml.sax.SAXException, org.dspace.app.xmlui.wing.WingException,
|
|
||||||
org.dspace.app.xmlui.utils.UIException, java.sql.SQLException, java.io.IOException, org.dspace.authorize.AuthorizeException
|
|
||||||
{
|
|
||||||
|
|
||||||
org.dspace.content.DSpaceObject dso = org.dspace.app.xmlui.utils.HandleUtil.obtainHandle(objectModel);
|
|
||||||
if (!(dso instanceof org.dspace.content.Item))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
org.dspace.content.Item item = (org.dspace.content.Item) dso;
|
|
||||||
|
|
||||||
try {
|
|
||||||
performSearch(item);
|
|
||||||
} catch (org.dspace.discovery.SearchServiceException e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void performSearch(org.dspace.content.DSpaceObject dso) throws org.dspace.discovery.SearchServiceException {
|
|
||||||
|
|
||||||
if(queryResults != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.queryArgs = prepareDefaultFilters(getView());
|
|
||||||
|
|
||||||
this.queryArgs.setRows(1);
|
|
||||||
this.queryArgs.setQuery("handle:" + dso.getHandle());
|
|
||||||
|
|
||||||
queryResults = getSearchService().search(queryArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getView()
|
|
||||||
{
|
|
||||||
return "item";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recycle
|
|
||||||
*/
|
|
||||||
public void recycle() {
|
|
||||||
this.queryArgs = null;
|
|
||||||
this.queryResults = null;
|
|
||||||
super.recycle();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,14 +9,9 @@ package org.dspace.app.xmlui.aspect.discovery;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
|
||||||
import org.apache.solr.common.SolrDocumentList;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.app.xmlui.utils.HandleUtil;
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
import org.dspace.app.xmlui.utils.UIException;
|
import org.dspace.app.xmlui.utils.UIException;
|
||||||
import org.dspace.app.xmlui.wing.WingException;
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
@@ -24,7 +19,8 @@ import org.dspace.app.xmlui.wing.element.*;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.discovery.DiscoverQuery;
|
||||||
|
import org.dspace.discovery.DiscoverResult;
|
||||||
import org.dspace.discovery.SearchUtils;
|
import org.dspace.discovery.SearchUtils;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
import org.dspace.discovery.SearchServiceException;
|
||||||
@@ -36,8 +32,17 @@ import org.dspace.discovery.SearchServiceException;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class RelatedItems extends AbstractFiltersTransformer
|
public class RelatedItems extends AbstractDSpaceTransformer
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Cached query results
|
||||||
|
*/
|
||||||
|
protected DiscoverResult queryResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached query arguments
|
||||||
|
*/
|
||||||
|
protected DiscoverQuery queryArgs;
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(RelatedItems.class);
|
private static final Logger log = Logger.getLogger(RelatedItems.class);
|
||||||
|
|
||||||
@@ -65,7 +70,8 @@ public class RelatedItems extends AbstractFiltersTransformer
|
|||||||
|
|
||||||
|
|
||||||
if (this.queryResults != null) {
|
if (this.queryResults != null) {
|
||||||
|
// TODO: develop this !
|
||||||
|
/*
|
||||||
NamedList nList = this.queryResults.getResponse();
|
NamedList nList = this.queryResults.getResponse();
|
||||||
|
|
||||||
SimpleOrderedMap<SolrDocumentList> mlt = (SimpleOrderedMap<SolrDocumentList>)nList.get("moreLikeThis");
|
SimpleOrderedMap<SolrDocumentList> mlt = (SimpleOrderedMap<SolrDocumentList>)nList.get("moreLikeThis");
|
||||||
@@ -118,20 +124,20 @@ public class RelatedItems extends AbstractFiltersTransformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void performSearch(DSpaceObject dso) throws SearchServiceException {
|
public void performSearch(DSpaceObject dso) throws SearchServiceException {
|
||||||
|
|
||||||
if(queryResults != null)
|
if(queryResults != null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
this.queryArgs = prepareDefaultFilters(getView());
|
this.queryArgs = prepareDefaultFilters(getView());
|
||||||
this.queryArgs.setRows(1);
|
this.queryArgs.setMaxResults(1);
|
||||||
this.queryArgs.add("fl","author,handle");
|
this.queryArgs.add("fl","author,handle");
|
||||||
this.queryArgs.add("mlt","true");
|
this.queryArgs.add("mlt","true");
|
||||||
this.queryArgs.add("mlt.fl","author,handle");
|
this.queryArgs.add("mlt.fl","author,handle");
|
||||||
@@ -139,8 +145,8 @@ public class RelatedItems extends AbstractFiltersTransformer
|
|||||||
this.queryArgs.add("mlt.mintf","1");
|
this.queryArgs.add("mlt.mintf","1");
|
||||||
this.queryArgs.setQuery("handle:" + dso.getHandle());
|
this.queryArgs.setQuery("handle:" + dso.getHandle());
|
||||||
this.queryArgs.setRows(1);
|
this.queryArgs.setRows(1);
|
||||||
|
*/
|
||||||
queryResults = getSearchService().search(queryArgs);
|
queryResults = SearchUtils.getSearchService().search(context, queryArgs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,12 +13,6 @@ import org.apache.cocoon.environment.Request;
|
|||||||
import org.apache.cocoon.util.HashUtil;
|
import org.apache.cocoon.util.HashUtil;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.apache.solr.client.solrj.response.FacetField;
|
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
|
||||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.apache.solr.common.params.FacetParams;
|
|
||||||
import org.dspace.app.util.Util;
|
import org.dspace.app.util.Util;
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
||||||
@@ -33,10 +27,7 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.discovery.SearchService;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
|
||||||
import org.dspace.discovery.SolrServiceImpl;
|
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@@ -44,10 +35,7 @@ import org.xml.sax.SAXException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -69,7 +57,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
/**
|
/**
|
||||||
* The cache of recently submitted items
|
* The cache of recently submitted items
|
||||||
*/
|
*/
|
||||||
protected QueryResponse queryResults;
|
protected DiscoverResult queryResults;
|
||||||
/**
|
/**
|
||||||
* Cached validity object
|
* Cached validity object
|
||||||
*/
|
*/
|
||||||
@@ -78,7 +66,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
/**
|
/**
|
||||||
* Cached query arguments
|
* Cached query arguments
|
||||||
*/
|
*/
|
||||||
protected SolrQuery queryArgs;
|
protected DiscoverQuery queryArgs;
|
||||||
|
|
||||||
private int DEFAULT_PAGE_SIZE = 10;
|
private int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
@@ -139,23 +127,20 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add reciently submitted items, serialize solr query contents.
|
// add reciently submitted items, serialize solr query contents.
|
||||||
QueryResponse response = getQueryResponse(dso);
|
DiscoverResult response = getQueryResponse(dso);
|
||||||
|
|
||||||
validity.add("numFound:" + response.getResults().getNumFound());
|
validity.add("numFound:" + response.getDspaceObjects().size());
|
||||||
|
|
||||||
for (SolrDocument doc : response.getResults()) {
|
for (DSpaceObject resultDso : queryResults.getDspaceObjects()) {
|
||||||
validity.add(doc.toString());
|
validity.add(resultDso);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SolrDocument doc : response.getResults()) {
|
for (String facetField : queryResults.getFacetResults().keySet()) {
|
||||||
validity.add(doc.toString());
|
validity.add(facetField);
|
||||||
}
|
|
||||||
|
|
||||||
for (FacetField field : response.getFacetFields()) {
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
||||||
validity.add(field.getName());
|
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
||||||
|
validity.add(facetValue.getAsFilterQuery() + facetValue.getCount());
|
||||||
for (FacetField.Count count : field.getValues()) {
|
|
||||||
validity.add(count.getName() + count.getCount());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +161,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
*
|
*
|
||||||
* @param scope The collection.
|
* @param scope The collection.
|
||||||
*/
|
*/
|
||||||
protected QueryResponse getQueryResponse(DSpaceObject scope) {
|
protected DiscoverResult getQueryResponse(DSpaceObject scope) {
|
||||||
|
|
||||||
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
@@ -186,18 +171,19 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
return queryResults;
|
return queryResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryArgs = new SolrQuery();
|
queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
//Make sure we add our default filters
|
//Make sure we add our default filters
|
||||||
queryArgs.addFilterQuery(SearchUtils.getDefaultFilters("search"));
|
queryArgs.addFilterQueries(SearchUtils.getDefaultFilters("search"));
|
||||||
|
|
||||||
|
|
||||||
queryArgs.setQuery("search.resourcetype: " + Constants.ITEM + ((request.getParameter("query") != null && !"".equals(request.getParameter("query"))) ? " AND (" + request.getParameter("query") + ")" : ""));
|
queryArgs.setQuery(((request.getParameter("query") != null && !"".equals(request.getParameter("query").trim())) ? request.getParameter("query") : null));
|
||||||
// queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
|
// queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
|
||||||
|
queryArgs.setDSpaceObjectFilter(Constants.ITEM);
|
||||||
|
|
||||||
queryArgs.setRows(0);
|
queryArgs.setMaxResults(0);
|
||||||
|
|
||||||
queryArgs.addFilterQuery(getParameterFilterQueries());
|
queryArgs.addFilterQueries(getDiscoveryFilterQueries());
|
||||||
|
|
||||||
|
|
||||||
//Set the default limit to 11
|
//Set the default limit to 11
|
||||||
@@ -206,9 +192,8 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
//sort
|
//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 ?
|
//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(config.getPropertyAsType("solr.browse.sort","lex"));
|
queryArgs.setFacetSort(DiscoverQuery.FACET_SORT.INDEX);
|
||||||
|
|
||||||
queryArgs.setFacet(true);
|
|
||||||
String facetField = request.getParameter(SearchFilterParam.FACET_FIELD);
|
String facetField = request.getParameter(SearchFilterParam.FACET_FIELD);
|
||||||
|
|
||||||
|
|
||||||
@@ -217,87 +202,25 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
{
|
{
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
if(facetField.endsWith(".year")){
|
queryArgs.setFacetOffset(offset);
|
||||||
// TODO: dates are now handled in another way, throw this away?
|
|
||||||
queryArgs.setParam(FacetParams.FACET_OFFSET, "0");
|
|
||||||
queryArgs.setParam(FacetParams.FACET_LIMIT, "1000000");
|
|
||||||
|
|
||||||
} 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
|
//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(DEFAULT_PAGE_SIZE + 1));
|
queryArgs.setFacetLimit(DEFAULT_PAGE_SIZE + 1);
|
||||||
}
|
|
||||||
|
|
||||||
|
FacetFieldConfig facetFieldConfig;
|
||||||
if (scope != null) /* top level search / community */ {
|
if(request.getParameter(SearchFilterParam.STARTS_WITH) != null)
|
||||||
if (scope instanceof Community) {
|
|
||||||
queryArgs.setFilterQueries("location:m" + scope.getID());
|
|
||||||
} else if (scope instanceof Collection) {
|
|
||||||
queryArgs.setFilterQueries("location:l" + scope.getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
boolean isDate = false;
|
|
||||||
if(facetField.endsWith("_dt")){
|
|
||||||
facetField = facetField.split("_")[0];
|
|
||||||
isDate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDate) {
|
|
||||||
|
|
||||||
queryArgs.setParam(FacetParams.FACET_DATE, 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);
|
|
||||||
// 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;
|
facetFieldConfig = new FacetFieldConfig(facetField, false, request.getParameter(SearchFilterParam.STARTS_WITH).toLowerCase());
|
||||||
|
}else{
|
||||||
|
facetFieldConfig = new FacetFieldConfig(facetField, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 < offset){
|
|
||||||
//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;
|
|
||||||
|
|
||||||
endDate = "NOW/YEAR-" + (thisYear - endYear) + "YEARS";
|
queryArgs.addFacetField(facetFieldConfig);
|
||||||
//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);
|
|
||||||
|
|
||||||
System.out.println(startDate);
|
|
||||||
System.out.println(endDate);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if(request.getParameter(SearchFilterParam.STARTS_WITH) != null)
|
|
||||||
{
|
|
||||||
queryArgs.setFacetPrefix(facetField, request.getParameter(SearchFilterParam.STARTS_WITH).toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
queryArgs.addFacetField(facetField);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
queryResults = searchService.search(queryArgs);
|
queryResults = searchService.search(context, scope, queryArgs);
|
||||||
} catch (SearchServiceException e) {
|
} catch (SearchServiceException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@@ -306,34 +229,6 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 a page title and trail links.
|
* Add a page title and trail links.
|
||||||
*/
|
*/
|
||||||
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, SQLException, IOException, AuthorizeException {
|
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, SQLException, IOException, AuthorizeException {
|
||||||
@@ -374,25 +269,20 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
queryResults = getQueryResponse(dso);
|
queryResults = getQueryResponse(dso);
|
||||||
if (this.queryResults != null) {
|
if (this.queryResults != null) {
|
||||||
|
|
||||||
java.util.List<FacetField> facetFields = this.queryResults.getFacetFields();
|
Map<String, List<DiscoverResult.FacetResult>> facetFields = this.queryResults.getFacetResults();
|
||||||
if (facetFields == null)
|
if (facetFields == null)
|
||||||
{
|
{
|
||||||
facetFields = new ArrayList<FacetField>();
|
facetFields = new LinkedHashMap<String, List<DiscoverResult.FacetResult>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
facetFields.addAll(this.queryResults.getFacetDates());
|
// facetFields.addAll(this.queryResults.getFacetDates());
|
||||||
|
|
||||||
|
|
||||||
if (facetFields.size() > 0) {
|
if (facetFields.size() > 0) {
|
||||||
FacetField field = facetFields.get(0);
|
String facetField = facetFields.keySet().toArray(new String[facetFields.size()])[0];
|
||||||
java.util.List<FacetField.Count> values = field.getValues();
|
java.util.List<DiscoverResult.FacetResult> values = facetFields.get(facetField);
|
||||||
if(field.getGap() != null){
|
|
||||||
//We are dealing with dates so flip em, top date comes first
|
|
||||||
Collections.reverse(values);
|
|
||||||
|
|
||||||
}
|
Division results = body.addDivision("browse-by-" + facetField + "-results", "primary");
|
||||||
|
|
||||||
Division results = body.addDivision("browse-by-" + field + "-results", "primary");
|
|
||||||
|
|
||||||
results.setHead(message("xmlui.Discovery.AbstractSearch.type_" + browseParams.getFacetField()));
|
results.setHead(message("xmlui.Discovery.AbstractSearch.type_" + browseParams.getFacetField()));
|
||||||
if (values != null && 0 < values.size()) {
|
if (values != null && 0 < values.size()) {
|
||||||
@@ -400,16 +290,14 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
|
|
||||||
// Find our faceting offset
|
// Find our faceting offset
|
||||||
int offSet = 0;
|
int offSet = queryArgs.getFacetOffset();
|
||||||
try {
|
if(offSet == -1){
|
||||||
offSet = Integer.parseInt(queryArgs.get(FacetParams.FACET_OFFSET));
|
offSet = 0;
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
//Ignore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only show the nextpageurl if we have at least one result following our current results
|
//Only show the nextpageurl if we have at least one result following our current results
|
||||||
String nextPageUrl = null;
|
String nextPageUrl = null;
|
||||||
if(field.getName().endsWith(".year")){
|
if(facetField.endsWith(".year")){
|
||||||
offSet = Util.getIntParameter(request, SearchFilterParam.OFFSET);
|
offSet = Util.getIntParameter(request, SearchFilterParam.OFFSET);
|
||||||
offSet = offSet == -1 ? 0 : offSet;
|
offSet = offSet == -1 ? 0 : offSet;
|
||||||
|
|
||||||
@@ -428,7 +316,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
int shownItemsMax;
|
int shownItemsMax;
|
||||||
|
|
||||||
|
|
||||||
if(field.getName().endsWith(".year")){
|
if(facetField.endsWith(".year")){
|
||||||
if((values.size() - offSet) < DEFAULT_PAGE_SIZE)
|
if((values.size() - offSet) < DEFAULT_PAGE_SIZE)
|
||||||
{
|
{
|
||||||
shownItemsMax = values.size();
|
shownItemsMax = values.size();
|
||||||
@@ -447,7 +335,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
results.setSimplePagination(-1, offSet + 1,
|
results.setSimplePagination(-1, offSet + 1,
|
||||||
shownItemsMax, getPreviousPageURL(browseParams, request), nextPageUrl);
|
shownItemsMax, getPreviousPageURL(browseParams, request), nextPageUrl);
|
||||||
|
|
||||||
Table singleTable = results.addTable("browse-by-" + field + "-results", (int) (queryResults.getResults().getNumFound() + 1), 1);
|
Table singleTable = results.addTable("browse-by-" + facetField + "-results", (int) (queryResults.getDspaceObjects().size() + 1), 1);
|
||||||
|
|
||||||
List<String> filterQueries = new ArrayList<String>();
|
List<String> filterQueries = new ArrayList<String>();
|
||||||
if(request.getParameterValues("fq") != null)
|
if(request.getParameterValues("fq") != null)
|
||||||
@@ -455,7 +343,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
filterQueries = Arrays.asList(request.getParameterValues("fq"));
|
filterQueries = Arrays.asList(request.getParameterValues("fq"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(field.getName().endsWith(".year")){
|
if(facetField.endsWith(".year")){
|
||||||
int start = (values.size() - 1) - offSet;
|
int start = (values.size() - 1) - offSet;
|
||||||
int end = start - DEFAULT_PAGE_SIZE;
|
int end = start - DEFAULT_PAGE_SIZE;
|
||||||
if(end < 0)
|
if(end < 0)
|
||||||
@@ -468,9 +356,9 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
for(int i = start; end <= i; i--)
|
for(int i = start; end <= i; i--)
|
||||||
{
|
{
|
||||||
FacetField.Count value = values.get(i);
|
DiscoverResult.FacetResult value = values.get(i);
|
||||||
|
|
||||||
renderFacetField(browseParams, dso, field, singleTable, filterQueries, value);
|
renderFacetField(browseParams, dso, facetField, singleTable, filterQueries, value);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
int end = values.size();
|
int end = values.size();
|
||||||
@@ -481,9 +369,9 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < end; i++) {
|
for (int i = 0; i < end; i++) {
|
||||||
FacetField.Count value = values.get(i);
|
DiscoverResult.FacetResult value = values.get(i);
|
||||||
|
|
||||||
renderFacetField(browseParams, dso, field, singleTable, filterQueries, value);
|
renderFacetField(browseParams, dso, facetField, singleTable, filterQueries, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,9 +384,16 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addBrowseJumpNavigation(Division div, SearchFilterParam browseParams, Request request)
|
private void addBrowseJumpNavigation(Division div, SearchFilterParam browseParams, Request request)
|
||||||
throws WingException
|
throws WingException, SQLException {
|
||||||
{
|
String action;
|
||||||
Division jump = div.addInteractiveDivision("filter-navigation", contextPath + "/search-filter",
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
if(dso != null){
|
||||||
|
action = contextPath + "/handle/" + dso.getHandle() + "/search-filter";
|
||||||
|
}else{
|
||||||
|
action = contextPath + "/search-filter";
|
||||||
|
}
|
||||||
|
|
||||||
|
Division jump = div.addInteractiveDivision("filter-navigation", action,
|
||||||
Division.METHOD_POST, "secondary navigation");
|
Division.METHOD_POST, "secondary navigation");
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
@@ -540,25 +435,21 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderFacetField(SearchFilterParam browseParams, DSpaceObject dso, FacetField field, Table singleTable, List<String> filterQueries, FacetField.Count value) throws SQLException, WingException, UnsupportedEncodingException {
|
private void renderFacetField(SearchFilterParam browseParams, DSpaceObject dso, String facetField, Table singleTable, List<String> filterQueries, DiscoverResult.FacetResult value) throws SQLException, WingException, UnsupportedEncodingException {
|
||||||
String displayedValue = value.getName();
|
String displayedValue = value.getDisplayedValue();
|
||||||
String filterQuery = value.getAsFilterQuery();
|
String filterQuery = value.getAsFilterQuery();
|
||||||
if (field.getName().equals("location.comm") || field.getName().equals("location.coll")) {
|
// if(field.getGap() != null){
|
||||||
//We have a community/collection, resolve it to a dspaceObject
|
// //We have a date get the year so we can display it
|
||||||
displayedValue = SolrServiceImpl.locationToName(context, field.getName(), displayedValue);
|
// DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
||||||
}
|
// displayedValue = simpleDateformat.format(SolrServiceImpl.toDate(displayedValue));
|
||||||
if(field.getGap() != null){
|
// filterQuery = ClientUtils.escapeQueryChars(value.getFacetField().getName()) + ":" + displayedValue + "*";
|
||||||
//We have a date get the year so we can display it
|
// }
|
||||||
DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
|
||||||
displayedValue = simpleDateformat.format(SolrServiceImpl.toDate(displayedValue));
|
|
||||||
filterQuery = ClientUtils.escapeQueryChars(value.getFacetField().getName()) + ":" + displayedValue + "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
Cell cell = singleTable.addRow().addCell();
|
Cell cell = singleTable.addRow().addCell();
|
||||||
|
|
||||||
//No use in selecting the same filter twice
|
//No use in selecting the same filter twice
|
||||||
if(filterQueries.contains(filterQuery)){
|
if(filterQueries.contains(filterQuery)){
|
||||||
cell.addContent(SearchUtils.getFilterQueryDisplay(displayedValue) + " (" + value.getCount() + ")");
|
cell.addContent(displayedValue + " (" + value.getCount() + ")");
|
||||||
} else {
|
} else {
|
||||||
//Add the basics
|
//Add the basics
|
||||||
Map<String, String> urlParams = new HashMap<String, String>();
|
Map<String, String> urlParams = new HashMap<String, String>();
|
||||||
@@ -568,7 +459,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
url = addFilterQueriesToUrl(url);
|
url = addFilterQueriesToUrl(url);
|
||||||
//Last add the current filter query
|
//Last add the current filter query
|
||||||
url += "&fq=" + filterQuery;
|
url += "&fq=" + filterQuery;
|
||||||
cell.addXref(url, SearchUtils.getFilterQueryDisplay(displayedValue) + " (" + value.getCount() + ")"
|
cell.addXref(url, displayedValue + " (" + value.getCount() + ")"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -595,7 +486,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
private String getPreviousPageURL(SearchFilterParam browseParams, Request request) {
|
private String getPreviousPageURL(SearchFilterParam browseParams, Request request) {
|
||||||
//If our offset should be 0 then we shouldn't be able to view a previous page url
|
//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)
|
if (0 == queryArgs.getFacetOffset() && Util.getIntParameter(request, "offset") == -1)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -644,15 +535,65 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String[] getParameterFilterQueries() {
|
protected String[] getParameterFilterQueries() {
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
return request.getParameterValues("fq") != null ? request.getParameterValues("fq") : new String[0];
|
java.util.List<String> fqs = new ArrayList<String>();
|
||||||
|
if(request.getParameterValues("fq") != null)
|
||||||
|
{
|
||||||
|
fqs.addAll(Arrays.asList(request.getParameterValues("fq")));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Have we added a filter using the UI
|
||||||
|
if(request.getParameter("filter") != null && !"".equals(request.getParameter("filter")))
|
||||||
|
{
|
||||||
|
fqs.add((request.getParameter("filtertype").equals("*") ? "" : request.getParameter("filtertype") + ":") + request.getParameter("filter"));
|
||||||
|
}
|
||||||
|
return fqs.toArray(new String[fqs.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the filter queries for use by discovery
|
||||||
|
* This method returns more expanded filter queries then the getParameterFilterQueries
|
||||||
|
* @return an array containing the filter queries
|
||||||
|
* TODO: almost identical to: SimpleSearch.getFilterQueries
|
||||||
|
*/
|
||||||
|
protected String[] getDiscoveryFilterQueries() {
|
||||||
|
try {
|
||||||
|
java.util.List<String> allFilterQueries = new ArrayList<String>();
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
java.util.List<String> fqs = new ArrayList<String>();
|
||||||
|
|
||||||
|
if(request.getParameterValues("fq") != null)
|
||||||
|
{
|
||||||
|
fqs.addAll(Arrays.asList(request.getParameterValues("fq")));
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = request.getParameter("filtertype");
|
||||||
|
String value = request.getParameter("filter");
|
||||||
|
|
||||||
|
if(value != null && !value.equals("")){
|
||||||
|
allFilterQueries.add(searchService.toFilterQuery(context, (type.equals("*") ? "" : type), value).getFilterQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add all the previous filters also
|
||||||
|
for (String fq : fqs) {
|
||||||
|
allFilterQueries.add(searchService.toFilterQuery(context, fq).getFilterQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
return allFilterQueries.toArray(new String[allFilterQueries.size()]);
|
||||||
|
}
|
||||||
|
catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SearchFilterParam {
|
private static class SearchFilterParam {
|
||||||
private Request request;
|
private Request request;
|
||||||
|
|
||||||
/** The always present commond params **/
|
/** The always present commond params **/
|
||||||
|
public static final String QUERY = "query";
|
||||||
public static final String FACET_FIELD = "field";
|
public static final String FACET_FIELD = "field";
|
||||||
|
|
||||||
/** The browse control params **/
|
/** The browse control params **/
|
||||||
@@ -671,6 +612,8 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
public Map<String, String> getCommonBrowseParams(){
|
public Map<String, String> getCommonBrowseParams(){
|
||||||
Map<String, String> result = new HashMap<String, String>();
|
Map<String, String> result = new HashMap<String, String>();
|
||||||
result.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
result.put(FACET_FIELD, request.getParameter(FACET_FIELD));
|
||||||
|
if(request.getParameter(QUERY) != null)
|
||||||
|
result.put(QUERY, request.getParameter(QUERY));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,15 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.xmlui.aspect.discovery;
|
package org.dspace.app.xmlui.aspect.discovery;
|
||||||
|
|
||||||
|
import org.apache.cocoon.caching.CacheableProcessingComponent;
|
||||||
import org.apache.cocoon.environment.ObjectModelHelper;
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
import org.apache.cocoon.environment.Request;
|
import org.apache.cocoon.environment.Request;
|
||||||
import org.apache.cocoon.util.HashUtil;
|
import org.apache.cocoon.util.HashUtil;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.apache.solr.client.solrj.response.FacetField;
|
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
import org.dspace.app.xmlui.utils.DSpaceValidity;
|
||||||
import org.dspace.app.xmlui.utils.HandleUtil;
|
import org.dspace.app.xmlui.utils.HandleUtil;
|
||||||
@@ -25,13 +22,12 @@ import org.dspace.app.xmlui.wing.WingException;
|
|||||||
import org.dspace.app.xmlui.wing.element.List;
|
import org.dspace.app.xmlui.wing.element.List;
|
||||||
import org.dspace.app.xmlui.wing.element.Options;
|
import org.dspace.app.xmlui.wing.element.Options;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
import org.dspace.discovery.SearchService;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
|
||||||
import org.dspace.discovery.SolrServiceImpl;
|
|
||||||
import org.dspace.handle.HandleManager;
|
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@@ -49,23 +45,20 @@ import java.util.regex.Pattern;
|
|||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransformer {
|
public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implements CacheableProcessingComponent {
|
||||||
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(AbstractFiltersTransformer.class);
|
private static final Logger log = Logger.getLogger(SidebarFacetsTransformer.class);
|
||||||
|
|
||||||
|
|
||||||
public abstract String getView();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached query results
|
* Cached query results
|
||||||
*/
|
*/
|
||||||
protected QueryResponse queryResults;
|
protected DiscoverResult queryResults;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached query arguments
|
* Cached query arguments
|
||||||
*/
|
*/
|
||||||
protected SolrQuery queryArgs;
|
protected DiscoverQuery queryArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached validity object
|
* Cached validity object
|
||||||
@@ -90,13 +83,12 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
public Serializable getKey() {
|
public Serializable getKey() {
|
||||||
try {
|
try {
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
if (dso != null)
|
||||||
if (dso == null)
|
|
||||||
{
|
{
|
||||||
|
return HashUtil.hash(dso.getHandle());
|
||||||
|
}else{
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
return HashUtil.hash(dso.getHandle());
|
|
||||||
}
|
}
|
||||||
catch (SQLException sqle) {
|
catch (SQLException sqle) {
|
||||||
// Ignore all errors and just return that the component is not
|
// Ignore all errors and just return that the component is not
|
||||||
@@ -117,12 +109,10 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
|
||||||
|
|
||||||
DSpaceValidity val = new DSpaceValidity();
|
DSpaceValidity val = new DSpaceValidity();
|
||||||
|
|
||||||
// add reciently submitted items, serialize solr query contents.
|
// Retrieve any facet results to add to the validity key
|
||||||
performSearch(dso);
|
performSearch();
|
||||||
|
|
||||||
// Add the actual collection;
|
// Add the actual collection;
|
||||||
if (dso != null)
|
if (dso != null)
|
||||||
@@ -130,71 +120,173 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
val.add(dso);
|
val.add(dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
val.add("numFound:" + queryResults.getResults().getNumFound());
|
val.add("numFound:" + queryResults.getDspaceObjects().size());
|
||||||
|
|
||||||
for (SolrDocument doc : queryResults.getResults()) {
|
for (DSpaceObject resultDso : queryResults.getDspaceObjects()) {
|
||||||
val.add(doc.toString());
|
val.add(resultDso);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SolrDocument doc : queryResults.getResults()) {
|
for (String facetField : queryResults.getFacetResults().keySet()) {
|
||||||
val.add(doc.toString());
|
val.add(facetField);
|
||||||
}
|
|
||||||
|
|
||||||
for (FacetField field : queryResults.getFacetFields()) {
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
||||||
val.add(field.getName());
|
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
||||||
|
val.add(facetValue.getAsFilterQuery() + facetValue.getCount());
|
||||||
for (FacetField.Count count : field.getValues()) {
|
|
||||||
val.add(count.getName() + count.getCount());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.validity = val.complete();
|
this.validity = val.complete();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
log.error(e.getMessage(),e);
|
log.error(e.getMessage(),e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: dependent on tags as well :)
|
//TODO: dependent on tags as well :)
|
||||||
}
|
}
|
||||||
return this.validity;
|
return this.validity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract void performSearch(DSpaceObject object) throws SearchServiceException, UIException;
|
public void performSearch() throws SearchServiceException, UIException, SQLException {
|
||||||
|
queryArgs = prepareDefaultFilters(context, getView(), getAllFilterQueries());
|
||||||
/**
|
//If we are on a search page performing a search a query may be used
|
||||||
* Determine the current scope. This may be derived from the current url
|
|
||||||
* handle if present or the scope parameter is given. If no scope is
|
|
||||||
* specified then null is returned.
|
|
||||||
*
|
|
||||||
* @return The current scope.
|
|
||||||
*/
|
|
||||||
protected DSpaceObject getScope() throws SQLException {
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
String scopeString = request.getParameter("scope");
|
String query = request.getParameter("query");
|
||||||
|
if(query != null && !"".equals(query)){
|
||||||
// Are we in a community or collection?
|
queryArgs.setQuery(query);
|
||||||
DSpaceObject dso;
|
|
||||||
if (scopeString == null || "".equals(scopeString))
|
|
||||||
{
|
|
||||||
// get the search scope from the url handle
|
|
||||||
dso = HandleUtil.obtainHandle(objectModel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get the search scope from the location parameter
|
|
||||||
dso = HandleManager.resolveToObject(context, scopeString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dso;
|
//We do not need to retrieve any dspace objects, only facets
|
||||||
|
queryArgs.setMaxResults(0);
|
||||||
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
queryResults = getSearchService().search(context, dso, queryArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SolrQuery prepareDefaultFilters(String scope, String ...filterQueries) {
|
@Override
|
||||||
|
public void addOptions(Options options) throws SAXException, WingException, SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
queryArgs = new SolrQuery();
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
|
||||||
SearchUtils.SolrFacetConfig[] facets = SearchUtils.getFacetsForType(scope);
|
try {
|
||||||
|
performSearch();
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("Error while searching for sidebar facets", e);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.queryResults != null) {
|
||||||
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
java.util.List<String> fqs = new ArrayList<String>();
|
||||||
|
if(request.getParameterValues("fq") != null){
|
||||||
|
for (int i = 0; i < request.getParameterValues("fq").length; i++) {
|
||||||
|
String fq = request.getParameterValues("fq")[i];
|
||||||
|
fqs.add(getSearchService().toFilterQuery(context, fq).getFilterQuery());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FacetFieldConfig[] facets = SearchUtils.getFacetsForType(getView());
|
||||||
|
|
||||||
|
if (facets != null && 0 < facets.length) {
|
||||||
|
|
||||||
|
List browse = options.addList("discovery");
|
||||||
|
|
||||||
|
browse.setHead(T_FILTER_HEAD);
|
||||||
|
|
||||||
|
for (FacetFieldConfig field : facets) {
|
||||||
|
//Retrieve our values
|
||||||
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResult(field.getField());
|
||||||
|
|
||||||
|
int shownFacets = this.queryArgs.getFacetLimit();
|
||||||
|
|
||||||
|
//This is needed to make sure that the date filters do not remain empty
|
||||||
|
if (0 < facetValues.size()) {
|
||||||
|
|
||||||
|
Iterator<DiscoverResult.FacetResult> iter = facetValues.iterator();
|
||||||
|
|
||||||
|
List filterValsList = browse.addList(field.getField());
|
||||||
|
|
||||||
|
filterValsList.setHead(message("xmlui.ArtifactBrowser.AdvancedSearch.type_" + field.getField().replace("_lc", "")));
|
||||||
|
|
||||||
|
for (int i = 0; i < shownFacets; i++) {
|
||||||
|
|
||||||
|
if (!iter.hasNext())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscoverResult.FacetResult value = iter.next();
|
||||||
|
|
||||||
|
if (i < shownFacets - 1) {
|
||||||
|
String displayedValue = value.getDisplayedValue();
|
||||||
|
String filterQuery = value.getAsFilterQuery();
|
||||||
|
|
||||||
|
if (fqs.contains(filterQuery)) {
|
||||||
|
filterValsList.addItem(Math.random() + "", "selected").addContent(displayedValue + " (" + value.getCount() + ")");
|
||||||
|
} else {
|
||||||
|
String paramsQuery = retrieveParameters(request);
|
||||||
|
|
||||||
|
filterValsList.addItem().addXref(
|
||||||
|
contextPath +
|
||||||
|
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
||||||
|
"/discover?" +
|
||||||
|
paramsQuery +
|
||||||
|
"fq=" +
|
||||||
|
//TODO: encode URLEncoder ?
|
||||||
|
filterQuery,
|
||||||
|
displayedValue + " (" + value.getCount() + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Show a view more url should there be more values, unless we have a date
|
||||||
|
if (i == shownFacets - 1 && !field.isDate()/*&& facetField.getGap() == null*/) {
|
||||||
|
|
||||||
|
addViewMoreUrl(filterValsList, dso, request, field.getField());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parameters used so it can be used in a url
|
||||||
|
* @param request the cocoon request
|
||||||
|
* @return the parameters used on this page
|
||||||
|
*/
|
||||||
|
private String retrieveParameters(Request request) {
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
Enumeration keys = request.getParameterNames();
|
||||||
|
if(keys != null){
|
||||||
|
while (keys.hasMoreElements()){
|
||||||
|
String key = (String) keys.nextElement();
|
||||||
|
//Ignore the page and submit button keys
|
||||||
|
if(key != null && !"page".equals(key) && !key.startsWith("submit")){
|
||||||
|
String[] vals = request.getParameterValues(key);
|
||||||
|
for(String paramValue : vals){
|
||||||
|
result.append(key).append("=").append(paramValue);
|
||||||
|
result.append("&");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addViewMoreUrl(List facet, DSpaceObject dso, Request request, String fieldName) throws WingException {
|
||||||
|
String parameters = retrieveParameters(request);
|
||||||
|
facet.addItem().addXref(
|
||||||
|
contextPath +
|
||||||
|
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
||||||
|
"/search-filter?" + parameters + BrowseFacet.FACET_FIELD + "=" + fieldName,
|
||||||
|
T_VIEW_MORE
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoverQuery prepareDefaultFilters(Context context, String scope, String ...filterQueries) {
|
||||||
|
DiscoverQuery queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
|
FacetFieldConfig[] facets = SearchUtils.getFacetsForType(scope);
|
||||||
|
|
||||||
log.info("facets for scope, " + scope + ": " + (facets != null ? facets.length : null));
|
log.info("facets for scope, " + scope + ": " + (facets != null ? facets.length : null));
|
||||||
|
|
||||||
@@ -213,24 +305,24 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
if (facets != null){
|
if (facets != null){
|
||||||
queryArgs.setFacetLimit(max);
|
queryArgs.setFacetLimit(max);
|
||||||
queryArgs.setFacetMinCount(1);
|
queryArgs.setFacetMinCount(1);
|
||||||
queryArgs.setFacet(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add the default filters
|
||||||
|
queryArgs.addFilterQueries(SearchUtils.getDefaultFilters(scope));
|
||||||
|
queryArgs.addFilterQueries(filterQueries);
|
||||||
|
|
||||||
/** enable faceting of search results */
|
/** enable faceting of search results */
|
||||||
if (facets != null){
|
if (facets != null){
|
||||||
for (SearchUtils.SolrFacetConfig facet : facets) {
|
for (FacetFieldConfig facet : facets) {
|
||||||
|
|
||||||
|
|
||||||
if(facet.isDate()){
|
if(facet.isDate()){
|
||||||
|
String dateFacet = facet.getField();
|
||||||
String dateFacet = facet.getFacetField();
|
|
||||||
try{
|
try{
|
||||||
//Get a range query so we can create facet queries ranging from out first to our last date
|
//Get a range query so we can create facet queries ranging from out first to our last date
|
||||||
//Attempt to determine our oldest & newest year by checking for previously selected filters
|
//Attempt to determine our oldest & newest year by checking for previously selected filters
|
||||||
int oldestYear = -1;
|
int oldestYear = -1;
|
||||||
int newestYear = -1;
|
int newestYear = -1;
|
||||||
for (String filterQuery : filterQueries) {
|
for (String filterQuery : filterQueries) {
|
||||||
if(filterQuery.startsWith(facet.getFacetField() + ":")){
|
if(filterQuery.startsWith(facet.getField() + ":")){
|
||||||
//Check for a range
|
//Check for a range
|
||||||
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
||||||
Matcher matcher = pattern.matcher(filterQuery);
|
Matcher matcher = pattern.matcher(filterQuery);
|
||||||
@@ -264,22 +356,31 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
//Check if we have found a range, if not then retrieve our first & last year by using solr
|
//Check if we have found a range, if not then retrieve our first & last year by using solr
|
||||||
if(oldestYear == -1 && newestYear == -1){
|
if(oldestYear == -1 && newestYear == -1){
|
||||||
|
|
||||||
SolrQuery yearRangeQuery = new SolrQuery();
|
DiscoverQuery yearRangeQuery = new DiscoverQuery();
|
||||||
yearRangeQuery.setRows(1);
|
yearRangeQuery.setMaxResults(1);
|
||||||
//Set our query to anything that has this value
|
//Set our query to anything that has this value
|
||||||
yearRangeQuery.setQuery(facet.getFacetField() + ":[* TO *]");
|
yearRangeQuery.addFieldPresentQueries(facet.getField());
|
||||||
//Set sorting so our last value will appear on top
|
//Set sorting so our last value will appear on top
|
||||||
yearRangeQuery.setSortField(dateFacet, SolrQuery.ORDER.asc);
|
yearRangeQuery.setSortField(dateFacet, DiscoverQuery.SORT_ORDER.asc);
|
||||||
yearRangeQuery.addFilterQuery(filterQueries);
|
yearRangeQuery.addFilterQueries(filterQueries);
|
||||||
QueryResponse lastYearResult = getSearchService().search(yearRangeQuery);
|
yearRangeQuery.addSearchField(dateFacet);
|
||||||
if(lastYearResult.getResults() != null && 0 < lastYearResult.getResults().size() && lastYearResult.getResults().get(0).getFieldValue(dateFacet) != null){
|
DiscoverResult lastYearResult = getSearchService().search(context, yearRangeQuery);
|
||||||
oldestYear = (Integer) lastYearResult.getResults().get(0).get(dateFacet);
|
|
||||||
|
|
||||||
|
if(0 < lastYearResult.getDspaceObjects().size()){
|
||||||
|
java.util.List<DiscoverResult.SearchDocument> searchDocuments = lastYearResult.getSearchDocument(lastYearResult.getDspaceObjects().get(0));
|
||||||
|
if(0 < searchDocuments.size() && 0 < searchDocuments.get(0).getSearchFieldValues(dateFacet).size()){
|
||||||
|
oldestYear = Integer.parseInt(searchDocuments.get(0).getSearchFieldValues(dateFacet).get(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Now get the first year
|
//Now get the first year
|
||||||
yearRangeQuery.setSortField(dateFacet, SolrQuery.ORDER.desc);
|
yearRangeQuery.setSortField(dateFacet, DiscoverQuery.SORT_ORDER.desc);
|
||||||
QueryResponse firstYearResult = getSearchService().search(yearRangeQuery);
|
DiscoverResult firstYearResult = getSearchService().search(context, yearRangeQuery);
|
||||||
if(firstYearResult.getResults() != null && 0 < firstYearResult.getResults().size() && firstYearResult.getResults().get(0).getFieldValue(dateFacet) != null){
|
if( 0 < firstYearResult.getDspaceObjects().size()){
|
||||||
newestYear = (Integer) firstYearResult.getResults().get(0).get(dateFacet);
|
java.util.List<DiscoverResult.SearchDocument> searchDocuments = firstYearResult.getSearchDocument(firstYearResult.getDspaceObjects().get(0));
|
||||||
|
if(0 < searchDocuments.size() && 0 < searchDocuments.get(0).getSearchFieldValues(dateFacet).size()){
|
||||||
|
newestYear = Integer.parseInt(searchDocuments.get(0).getSearchFieldValues(dateFacet).get(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//No values found!
|
//No values found!
|
||||||
if(newestYear == -1 || oldestYear == -1)
|
if(newestYear == -1 || oldestYear == -1)
|
||||||
@@ -305,7 +406,7 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
//We need a list of our years
|
//We need a list of our years
|
||||||
//We have a date range add faceting for our field
|
//We have a date range add faceting for our field
|
||||||
//The faceting will automatically be limited to the 10 years in our span due to our filterquery
|
//The faceting will automatically be limited to the 10 years in our span due to our filterquery
|
||||||
queryArgs.addFacetField(facet.getFacetField());
|
queryArgs.addFacetField(facet);
|
||||||
}else{
|
}else{
|
||||||
java.util.List<String> facetQueries = new ArrayList<String>();
|
java.util.List<String> facetQueries = new ArrayList<String>();
|
||||||
//Create facet queries but limit then to 11 (11 == when we need to show a show more url)
|
//Create facet queries but limit then to 11 (11 == when we need to show a show more url)
|
||||||
@@ -338,201 +439,79 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
|||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
log.error(LogManager.getHeader(context, "Error in discovery while setting up date facet range", "date facet: " + dateFacet), e);
|
log.error(LogManager.getHeader(context, "Error in discovery while setting up date facet range", "date facet: " + dateFacet), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
queryArgs.addFacetField(facet);
|
||||||
queryArgs.addFacetField(facet.getFacetField());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Add the default filters
|
|
||||||
queryArgs.addFilterQuery(SearchUtils.getDefaultFilters(scope));
|
|
||||||
|
|
||||||
return queryArgs;
|
return queryArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getView() throws SQLException {
|
||||||
@Override
|
|
||||||
public void addOptions(Options options) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
|
|
||||||
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
|
||||||
|
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
if(dso == null){
|
||||||
java.util.List<String> fqs = Arrays.asList(request.getParameterValues("fq") != null ? request.getParameterValues("fq") : new String[0]);
|
if("discover".equals(ObjectModelHelper.getRequest(objectModel).getSitemapURI())){
|
||||||
|
//We are on a search page
|
||||||
if (this.queryResults != null) {
|
return "search";
|
||||||
|
}else{
|
||||||
SearchUtils.SolrFacetConfig[] facets = SearchUtils.getFacetsForType(getView());
|
return "site";
|
||||||
|
|
||||||
if (facets != null && 0 < facets.length) {
|
|
||||||
|
|
||||||
List browse = options.addList("discovery");
|
|
||||||
|
|
||||||
browse.setHead(T_FILTER_HEAD);
|
|
||||||
|
|
||||||
for (SearchUtils.SolrFacetConfig field : facets) {
|
|
||||||
//Retrieve our values
|
|
||||||
java.util.List<FilterDisplayValue> values = new ArrayList<FilterDisplayValue>();
|
|
||||||
|
|
||||||
int shownFacets = this.queryArgs.getFacetLimit();
|
|
||||||
FacetField facet = queryResults.getFacetField(field.getFacetField());
|
|
||||||
if(facet != null){
|
|
||||||
java.util.List<FacetField.Count> facetVals = facet.getValues();
|
|
||||||
if(facetVals == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (FacetField.Count count : facetVals) {
|
|
||||||
values.add(new FilterDisplayValue(SearchUtils.getFilterQueryDisplay(count.getName()), count.getCount(), count.getAsFilterQuery()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(field.isDate()){
|
|
||||||
if(0 < values.size()){
|
|
||||||
//Check for values comming from a facet field.
|
|
||||||
//If we have values we need to sort these & get the newest ones on top
|
|
||||||
//There is no other way for this since solr doesn't support facet sorting
|
|
||||||
TreeMap<String, FilterDisplayValue> sortedVals = new TreeMap<String, FilterDisplayValue>(Collections.reverseOrder());
|
|
||||||
for (FilterDisplayValue filterDisplayValue : values) {
|
|
||||||
//No need to show empty years
|
|
||||||
if(0 < filterDisplayValue.getCount())
|
|
||||||
{
|
|
||||||
sortedVals.put(filterDisplayValue.getDisplayedVal(), filterDisplayValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Make sure we retrieve our sorted values
|
|
||||||
values = Arrays.asList(sortedVals.values().toArray(new FilterDisplayValue[sortedVals.size()]));
|
|
||||||
}else{
|
|
||||||
//Attempt to retrieve it as a facet query
|
|
||||||
//Since our facet query result is returned as a hashmap we need to sort it by using a treemap
|
|
||||||
TreeMap<String, Integer> sortedFacetQueries = new TreeMap<String, Integer>(queryResults.getFacetQuery());
|
|
||||||
for(String facetQuery : sortedFacetQueries.descendingKeySet()){
|
|
||||||
if(facetQuery != null && facetQuery.startsWith(field.getFacetField())){
|
|
||||||
//We have a facet query, the values looks something like: dateissued.year:[1990 TO 2000] AND -2000
|
|
||||||
//Prepare the string from {facet.field.name}:[startyear TO endyear] to startyear - endyear
|
|
||||||
String name = facetQuery.substring(facetQuery.indexOf('[') + 1);
|
|
||||||
name = name.substring(0, name.lastIndexOf(']')).replaceAll("TO", "-");
|
|
||||||
Integer count = sortedFacetQueries.get(facetQuery);
|
|
||||||
|
|
||||||
//No need to show empty years
|
|
||||||
if(0 < count)
|
|
||||||
{
|
|
||||||
values.add(new FilterDisplayValue(name, count, facetQuery));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//This is needed to make sure that the date filters do not remain empty
|
|
||||||
if (0 < values.size()) {
|
|
||||||
|
|
||||||
Iterator<FilterDisplayValue> iter = values.iterator();
|
|
||||||
|
|
||||||
List filterValsList = browse.addList(field.getFacetField());
|
|
||||||
|
|
||||||
filterValsList.setHead(message("xmlui.ArtifactBrowser.AdvancedSearch.type_" + field.getFacetField().replace("_lc", "")));
|
|
||||||
|
|
||||||
for (int i = 0; i < shownFacets; i++) {
|
|
||||||
|
|
||||||
if (!iter.hasNext())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterDisplayValue value = iter.next();
|
|
||||||
|
|
||||||
if (i < shownFacets - 1) {
|
|
||||||
String displayedValue = value.getDisplayedVal();
|
|
||||||
String filterQuery = value.getAsFilterQuery();
|
|
||||||
if (field.getFacetField().equals("location.comm") || field.getFacetField().equals("location.coll")) {
|
|
||||||
//We have a community/collection, resolve it to a dspaceObject
|
|
||||||
displayedValue = SolrServiceImpl.locationToName(context, field.getFacetField(), displayedValue);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (fqs.contains(filterQuery)) {
|
|
||||||
filterValsList.addItem(Math.random() + "", "selected").addContent(displayedValue + " (" + value.getCount() + ")");
|
|
||||||
} else {
|
|
||||||
String paramsQuery = "";
|
|
||||||
Enumeration keys = request.getParameterNames();
|
|
||||||
if(keys != null){
|
|
||||||
while (keys.hasMoreElements()){
|
|
||||||
String key = (String) keys.nextElement();
|
|
||||||
if(key != null && !"page".equals(key)){
|
|
||||||
String[] vals = request.getParameterValues(key);
|
|
||||||
for(String paramValue : vals){
|
|
||||||
paramsQuery += key + "=" + paramValue;
|
|
||||||
paramsQuery += "&";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filterValsList.addItem().addXref(
|
|
||||||
contextPath +
|
|
||||||
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
|
||||||
"/discover?" +
|
|
||||||
paramsQuery +
|
|
||||||
"fq=" +
|
|
||||||
filterQuery,
|
|
||||||
displayedValue + " (" + value.getCount() + ")"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Show a view more url should there be more values, unless we have a date
|
|
||||||
if (i == shownFacets - 1 && !field.isDate()/*&& facetField.getGap() == null*/) {
|
|
||||||
|
|
||||||
addViewMoreUrl(filterValsList, dso, request, field.getFacetField());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}else
|
||||||
|
if(dso instanceof Community){
|
||||||
|
return "community";
|
||||||
|
}else
|
||||||
|
if(dso instanceof org.dspace.content.Collection){
|
||||||
|
return "collection";
|
||||||
|
}else
|
||||||
|
if(dso instanceof Item){
|
||||||
|
return "item";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the filter queries for use by discovery
|
||||||
|
* This method returns more expanded filter queries then the getParameterFilterQueries
|
||||||
|
* @return an array containing the filter queries
|
||||||
|
*/
|
||||||
|
protected String[] getAllFilterQueries() {
|
||||||
|
try {
|
||||||
|
java.util.List<String> allFilterQueries = new ArrayList<String>();
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
java.util.List<String> fqs = new ArrayList<String>();
|
||||||
|
|
||||||
|
if(request.getParameterValues("fq") != null)
|
||||||
|
{
|
||||||
|
fqs.addAll(Arrays.asList(request.getParameterValues("fq")));
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = request.getParameter("filtertype");
|
||||||
|
String value = request.getParameter("filter");
|
||||||
|
|
||||||
|
if(value != null && !value.equals("") && request.getParameter("submit_search-filter-controls_add") != null){
|
||||||
|
allFilterQueries.add(getSearchService().toFilterQuery(context, (type.equals("*") ? "" : type), value).getFilterQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add all the previous filters also
|
||||||
|
for (String fq : fqs) {
|
||||||
|
allFilterQueries.add(getSearchService().toFilterQuery(context, fq).getFilterQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
return allFilterQueries.toArray(new String[allFilterQueries.size()]);
|
||||||
|
}
|
||||||
|
catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addViewMoreUrl(List facet, DSpaceObject dso, Request request, String fieldName) throws WingException {
|
|
||||||
facet.addItem().addXref(
|
|
||||||
contextPath +
|
|
||||||
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
|
||||||
"/search-filter?" + BrowseFacet.FACET_FIELD + "=" + fieldName +
|
|
||||||
(request.getQueryString() != null ? "&" + request.getQueryString() : ""),
|
|
||||||
T_VIEW_MORE
|
|
||||||
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
queryResults = null;
|
queryResults = null;
|
||||||
queryArgs = null;
|
queryArgs = null;
|
||||||
}
|
validity = null;
|
||||||
|
super.recycle();
|
||||||
private static final class FilterDisplayValue {
|
|
||||||
private String asFilterQuery;
|
|
||||||
private String displayedVal;
|
|
||||||
private long count;
|
|
||||||
|
|
||||||
private FilterDisplayValue(String displayedVal, long count, String asFilterQuery) {
|
|
||||||
this.asFilterQuery = asFilterQuery;
|
|
||||||
this.displayedVal = displayedVal;
|
|
||||||
this.count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDisplayedVal() {
|
|
||||||
return displayedVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAsFilterQuery(){
|
|
||||||
return asFilterQuery;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -10,7 +10,6 @@ package org.dspace.app.xmlui.aspect.discovery;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -27,10 +26,12 @@ import org.dspace.app.xmlui.wing.element.List;
|
|||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.*;
|
import org.dspace.content.*;
|
||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.discovery.DiscoverFilterQuery;
|
||||||
|
import org.dspace.discovery.SearchService;
|
||||||
import org.dspace.discovery.SearchUtils;
|
import org.dspace.discovery.SearchUtils;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
import org.dspace.discovery.SearchServiceException;
|
||||||
import org.dspace.discovery.SolrServiceImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preform a simple search of the repository. The user provides a simple one
|
* Preform a simple search of the repository. The user provides a simple one
|
||||||
@@ -65,6 +66,14 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
private static final Message T_FILTER_HEAD = message("xmlui.Discovery.SimpleSearch.filter_head");
|
private static final Message T_FILTER_HEAD = message("xmlui.Discovery.SimpleSearch.filter_head");
|
||||||
private static final Message T_FILTERS_SELECTED = message("xmlui.ArtifactBrowser.SimpleSearch.filter.selected");
|
private static final Message T_FILTERS_SELECTED = message("xmlui.ArtifactBrowser.SimpleSearch.filter.selected");
|
||||||
|
|
||||||
|
private SearchService searchService = null;
|
||||||
|
|
||||||
|
public SimpleSearch() {
|
||||||
|
DSpace dspace = new DSpace();
|
||||||
|
searchService = dspace.getServiceManager().getServiceByName(SearchService.class.getName(),SearchService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Page metadata.
|
* Add Page metadata.
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +82,7 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
|
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
|
||||||
|
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
if ((dso instanceof Collection) || (dso instanceof Community)) {
|
if ((dso instanceof org.dspace.content.Collection) || (dso instanceof Community)) {
|
||||||
HandleUtil.buildHandleTrail(dso, pageMeta, contextPath);
|
HandleUtil.buildHandleTrail(dso, pageMeta, contextPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +106,9 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
// String searchUrl = SearchUtils.getConfig().getString("solr.search.server");
|
// String searchUrl = SearchUtils.getConfig().getString("solr.search.server");
|
||||||
// if(searchUrl != null && !searchUrl.endsWith("/"))
|
// if(searchUrl != null && !searchUrl.endsWith("/"))
|
||||||
// searchUrl += "/";
|
// searchUrl += "/";
|
||||||
String searchUrl = ConfigurationManager.getProperty("dspace.url") + "/JSON/discovery/searchSolr";
|
String searchUrl = ConfigurationManager.getProperty("dspace.url") + "/JSON/discovery/search";
|
||||||
|
|
||||||
search.addHidden("solr-search-url").setValue(searchUrl);
|
search.addHidden("discovery-json-search-url").setValue(searchUrl);
|
||||||
search.addHidden("contextpath").setValue(contextPath);
|
search.addHidden("contextpath").setValue(contextPath);
|
||||||
|
|
||||||
String[] fqs = getParameterFilterQueries();
|
String[] fqs = getParameterFilterQueries();
|
||||||
@@ -132,47 +141,26 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
|
|
||||||
CheckBox box = composite.addCheckBox("fq");
|
CheckBox box = composite.addCheckBox("fq");
|
||||||
|
|
||||||
for(String name : fqs){
|
for(String filterQuery : fqs){
|
||||||
//for(Map.Entry<String, Integer> filter : filters.entrySet()){
|
//for(Map.Entry<String, Integer> filter : filters.entrySet()){
|
||||||
//String name = filter.getKey();
|
//String name = filter.getKey();
|
||||||
//long count = filter.getValue();
|
//long count = filter.getValue();
|
||||||
|
|
||||||
|
DiscoverFilterQuery fq = searchService.toFilterQuery(context, filterQuery);
|
||||||
|
|
||||||
String field = name;
|
|
||||||
String value = name;
|
|
||||||
|
|
||||||
if(name.contains(":"))
|
Option option = box.addOption(true,fq.getFilterQuery());
|
||||||
{
|
String field = fq.getField();
|
||||||
field = name.split(":")[0];
|
//If no field specified, then all is used.
|
||||||
value = name.split(":")[1];
|
if(field == null || field.equals("") || field.equals("*") || field.equals("all_ac")){
|
||||||
}else{
|
|
||||||
//We have got no field, so we are using everything
|
|
||||||
field = "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
value = value.replace("\\", "");
|
|
||||||
if("*".equals(field))
|
|
||||||
{
|
|
||||||
field = "all";
|
field = "all";
|
||||||
}
|
}
|
||||||
if(name.startsWith("*:"))
|
|
||||||
{
|
|
||||||
name = name.substring(name.indexOf(":") + 1, name.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
Option option = box.addOption(true,name);
|
|
||||||
option.addContent(message("xmlui.ArtifactBrowser.SimpleSearch.filter." + field));
|
option.addContent(message("xmlui.ArtifactBrowser.SimpleSearch.filter." + field));
|
||||||
|
|
||||||
if(field.equals("location.comm") || field.equals("location.coll")){
|
//We have a filter query get the display value
|
||||||
//We have a community/collection, resolve it to a dspaceObject
|
|
||||||
value = SolrServiceImpl.locationToName(context, field, value);
|
|
||||||
} else
|
|
||||||
if(field.endsWith("_filter")){
|
|
||||||
value = SearchUtils.getFilterQueryDisplay(value);
|
|
||||||
}
|
|
||||||
//Check for a range query
|
//Check for a range query
|
||||||
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
||||||
Matcher matcher = pattern.matcher(value);
|
Matcher matcher = pattern.matcher(fq.getDisplayedValue());
|
||||||
boolean hasPattern = matcher.find();
|
boolean hasPattern = matcher.find();
|
||||||
if(hasPattern){
|
if(hasPattern){
|
||||||
String[] years = matcher.group(0).replace("[", "").replace("]", "").split(" TO ");
|
String[] years = matcher.group(0).replace("[", "").replace("]", "").split(" TO ");
|
||||||
@@ -180,9 +168,7 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
option.addContent(": " + fq.getDisplayedValue());
|
||||||
option.addContent(": " + value);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +185,7 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
|
|
||||||
Select select = filterComp.addSelect("filtertype");
|
Select select = filterComp.addSelect("filtertype");
|
||||||
//First of all add a default filter
|
//First of all add a default filter
|
||||||
select.addOption("*", message("xmlui.ArtifactBrowser.SimpleSearch.filter.all"));
|
select.addOption("all_ac", message("xmlui.ArtifactBrowser.SimpleSearch.filter.all"));
|
||||||
//For each field found (at least one) add options
|
//For each field found (at least one) add options
|
||||||
|
|
||||||
for (String field : filterFields) {
|
for (String field : filterFields) {
|
||||||
@@ -246,17 +232,17 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
//Have we added a filter using the UI
|
//Have we added a filter using the UI
|
||||||
if(request.getParameter("filter") != null && !"".equals(request.getParameter("filter")) && request.getParameter("submit_search-filter-controls_add") != null)
|
if(request.getParameter("filter") != null && !"".equals(request.getParameter("filter")) && request.getParameter("submit_search-filter-controls_add") != null)
|
||||||
{
|
{
|
||||||
fqs.add((request.getParameter("filtertype").equals("*") ? "" : request.getParameter("filtertype") + ":") + request.getParameter("filter"));
|
fqs.add((request.getParameter("filtertype")) + ":" + request.getParameter("filter"));
|
||||||
}
|
}
|
||||||
return fqs.toArray(new String[fqs.size()]);
|
return fqs.toArray(new String[fqs.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the filter queries for use by solr
|
* Returns all the filter queries for use by discovery
|
||||||
* This method returns more expanded filter queries then the getParameterFilterQueries
|
* This method returns more expanded filter queries then the getParameterFilterQueries
|
||||||
* @return an array containing the filter queries
|
* @return an array containing the filter queries
|
||||||
*/
|
*/
|
||||||
protected String[] getSolrFilterQueries() {
|
protected String[] getFilterQueries() {
|
||||||
try {
|
try {
|
||||||
java.util.List<String> allFilterQueries = new ArrayList<String>();
|
java.util.List<String> allFilterQueries = new ArrayList<String>();
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
@@ -271,20 +257,12 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
String value = request.getParameter("filter");
|
String value = request.getParameter("filter");
|
||||||
|
|
||||||
if(value != null && !value.equals("") && request.getParameter("submit_search-filter-controls_add") != null){
|
if(value != null && !value.equals("") && request.getParameter("submit_search-filter-controls_add") != null){
|
||||||
String exactFq = (type.equals("*") ? "" : type + ":") + value;
|
allFilterQueries.add(searchService.toFilterQuery(context, (type.equals("*") ? "" : type), value).getFilterQuery());
|
||||||
fqs.add(exactFq + " OR " + exactFq + "*");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add all the previous filters also
|
||||||
for (String fq : fqs) {
|
for (String fq : fqs) {
|
||||||
//Do not put a wildcard after a range query
|
allFilterQueries.add(searchService.toFilterQuery(context, fq).getFilterQuery());
|
||||||
if (fq.matches(".*\\:\\[.* TO .*\\](?![a-z 0-9]).*")) {
|
|
||||||
allFilterQueries.add(fq);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allFilterQueries.add(fq.endsWith("*") ? fq : fq + " OR " + fq + "*");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allFilterQueries.toArray(new String[allFilterQueries.size()]);
|
return allFilterQueries.toArray(new String[allFilterQueries.size()]);
|
||||||
|
@@ -7,10 +7,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.xmlui.aspect.discovery;
|
package org.dspace.app.xmlui.aspect.discovery;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
|
||||||
import org.apache.solr.common.SolrDocument;
|
|
||||||
import org.dspace.app.xmlui.utils.UIException;
|
|
||||||
import org.dspace.app.xmlui.wing.Message;
|
import org.dspace.app.xmlui.wing.Message;
|
||||||
import org.dspace.app.xmlui.wing.WingException;
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
import org.dspace.app.xmlui.wing.element.Body;
|
import org.dspace.app.xmlui.wing.element.Body;
|
||||||
@@ -18,25 +14,19 @@ import org.dspace.app.xmlui.wing.element.Division;
|
|||||||
import org.dspace.app.xmlui.wing.element.ReferenceSet;
|
import org.dspace.app.xmlui.wing.element.ReferenceSet;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
import org.dspace.core.Constants;
|
|
||||||
import org.dspace.discovery.SearchService;
|
|
||||||
import org.dspace.discovery.SearchServiceException;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transformer that displays the recently submitted items on the dspace home page
|
* Renders a list of recently submitted items for the homepage by using discovery
|
||||||
*
|
*
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
* @author Mark Diggory (markd at atmire dot com)
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class SiteRecentSubmissions extends AbstractFiltersTransformer {
|
public class SiteRecentSubmissions extends AbstractRecentSubmissionTransformer {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(SiteRecentSubmissions.class);
|
|
||||||
|
|
||||||
private static final Message T_head_recent_submissions =
|
private static final Message T_head_recent_submissions =
|
||||||
message("xmlui.ArtifactBrowser.SiteViewer.head_recent_submissions");
|
message("xmlui.ArtifactBrowser.SiteViewer.head_recent_submissions");
|
||||||
@@ -47,12 +37,13 @@ public class SiteRecentSubmissions extends AbstractFiltersTransformer {
|
|||||||
* collections)
|
* collections)
|
||||||
*/
|
*/
|
||||||
public void addBody(Body body) throws SAXException, WingException,
|
public void addBody(Body body) throws SAXException, WingException,
|
||||||
UIException, SQLException, IOException, AuthorizeException {
|
SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
try {
|
getRecentlySubmittedItems(null);
|
||||||
performSearch(null);
|
|
||||||
} catch (SearchServiceException e) {
|
//Only attempt to render our result if we have one.
|
||||||
log.error(e.getMessage(), e);
|
if (queryResults == null) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Division home = body.addDivision("site-home", "primary repository");
|
Division home = body.addDivision("site-home", "primary repository");
|
||||||
@@ -66,53 +57,14 @@ public class SiteRecentSubmissions extends AbstractFiltersTransformer {
|
|||||||
"site-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
"site-last-submitted", ReferenceSet.TYPE_SUMMARY_LIST,
|
||||||
null, "recent-submissions");
|
null, "recent-submissions");
|
||||||
|
|
||||||
if (queryResults != null) {
|
for (DSpaceObject dso : queryResults.getDspaceObjects()) {
|
||||||
for (SolrDocument doc : queryResults.getResults()) {
|
lastSubmitted.addReference(dso);
|
||||||
DSpaceObject obj = SearchUtils.findDSpaceObject(context, doc);
|
|
||||||
if(obj != null)
|
|
||||||
{
|
|
||||||
lastSubmitted.addReference(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getView()
|
public String getView()
|
||||||
{
|
{
|
||||||
return "site";
|
return "site";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* facet.limit=11&wt=javabin&rows=5&sort=dateaccessioned+asc&facet=true&facet.mincount=1&q=search.resourcetype:2&version=1
|
|
||||||
*
|
|
||||||
* @param object
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void performSearch(DSpaceObject object) throws SearchServiceException, UIException {
|
|
||||||
|
|
||||||
if(queryResults != null)
|
|
||||||
{
|
|
||||||
return; // queryResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryArgs = prepareDefaultFilters(getView());
|
|
||||||
|
|
||||||
queryArgs.setQuery("search.resourcetype:" + Constants.ITEM);
|
|
||||||
|
|
||||||
queryArgs.setRows(SearchUtils.getConfig().getInt("solr.recent-submissions.size", 5));
|
|
||||||
|
|
||||||
String sortField = SearchUtils.getConfig().getString("recent.submissions.sort-option");
|
|
||||||
if(sortField != null){
|
|
||||||
queryArgs.setSortField(
|
|
||||||
sortField,
|
|
||||||
SolrQuery.ORDER.desc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchService service = getSearchService();
|
|
||||||
|
|
||||||
queryResults = service.search(queryArgs);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.xmlui.aspect.discovery.json;
|
||||||
|
|
||||||
|
import org.apache.avalon.excalibur.pool.Recyclable;
|
||||||
|
import org.apache.avalon.framework.parameters.Parameters;
|
||||||
|
import org.apache.cocoon.ProcessingException;
|
||||||
|
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.apache.cocoon.environment.Response;
|
||||||
|
import org.apache.cocoon.environment.SourceResolver;
|
||||||
|
import org.apache.cocoon.reading.AbstractReader;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.discovery.*;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to search in the discovery backend and return a json formatted string
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class JSONDiscoverySearcher extends AbstractReader implements Recyclable {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(JSONDiscoverySearcher.class);
|
||||||
|
/** These are all our parameters which can be used by this generator **/
|
||||||
|
private DiscoverQuery queryArgs;
|
||||||
|
private String jsonWrf;
|
||||||
|
|
||||||
|
|
||||||
|
/** The Cocoon response */
|
||||||
|
protected Response response;
|
||||||
|
|
||||||
|
protected SearchService getSearchService()
|
||||||
|
{
|
||||||
|
DSpace dspace = new DSpace();
|
||||||
|
|
||||||
|
org.dspace.kernel.ServiceManager manager = dspace.getServiceManager() ;
|
||||||
|
|
||||||
|
return manager.getServiceByName(SearchService.class.getName(),SearchService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
|
||||||
|
//Retrieve all the given parameters
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
this.response = ObjectModelHelper.getResponse(objectModel);
|
||||||
|
|
||||||
|
queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
|
queryArgs.setQuery(request.getParameter("q"));
|
||||||
|
|
||||||
|
|
||||||
|
//Retrieve all our filter queries
|
||||||
|
if(request.getParameterValues("fq") != null)
|
||||||
|
queryArgs.addFilterQueries(request.getParameterValues("fq"));
|
||||||
|
|
||||||
|
//Retrieve our facet fields
|
||||||
|
if(request.getParameterValues("facet.field") != null){
|
||||||
|
for (int i = 0; i < request.getParameterValues("facet.field").length; i++) {
|
||||||
|
String facetField = request.getParameterValues("facet.field")[i];
|
||||||
|
queryArgs.addFacetField(new FacetFieldConfig(facetField, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Retrieve our facet limit (if any)
|
||||||
|
int facetLimit;
|
||||||
|
if(request.getParameter("facet.limit") != null){
|
||||||
|
try{
|
||||||
|
facetLimit = Integer.parseInt(request.getParameter("facet.limit"));
|
||||||
|
}catch (Exception e){
|
||||||
|
//Should an invalid value be supplied use -1
|
||||||
|
facetLimit = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facetLimit = -1;
|
||||||
|
}
|
||||||
|
queryArgs.setFacetLimit(facetLimit);
|
||||||
|
|
||||||
|
//Retrieve our sorting value
|
||||||
|
String facetSort = request.getParameter("facet.sort");
|
||||||
|
if(facetSort == null || facetSort.equalsIgnoreCase("count"))
|
||||||
|
queryArgs.setFacetSort(DiscoverQuery.FACET_SORT.COUNT);
|
||||||
|
else
|
||||||
|
queryArgs.setFacetSort(DiscoverQuery.FACET_SORT.INDEX);
|
||||||
|
|
||||||
|
//Retrieve our facet min count
|
||||||
|
int facetMinCount;
|
||||||
|
try{
|
||||||
|
facetMinCount = Integer.parseInt(request.getParameter("facet.mincount"));
|
||||||
|
}catch (Exception e){
|
||||||
|
facetMinCount = 1;
|
||||||
|
}
|
||||||
|
queryArgs.setFacetMinCount(facetMinCount);
|
||||||
|
jsonWrf = request.getParameter("json.wrf");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generate() throws IOException, SAXException, ProcessingException {
|
||||||
|
String result = null;
|
||||||
|
try {
|
||||||
|
result = getSearchService().searchJSON(queryArgs, jsonWrf);
|
||||||
|
} catch (SearchServiceException e) {
|
||||||
|
log.error("Error while retrieving JSON string for Discovery auto complete", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result != null){
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(result.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
|
||||||
|
response.setHeader("Content-Length", String.valueOf(result.length()));
|
||||||
|
int length;
|
||||||
|
while ((length = inputStream.read(buffer)) > -1)
|
||||||
|
{
|
||||||
|
out.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,238 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.app.xmlui.aspect.discovery.json;
|
|
||||||
|
|
||||||
import org.apache.avalon.excalibur.pool.Recyclable;
|
|
||||||
import org.apache.avalon.framework.parameters.Parameters;
|
|
||||||
import org.apache.cocoon.ProcessingException;
|
|
||||||
import org.apache.cocoon.environment.ObjectModelHelper;
|
|
||||||
import org.apache.cocoon.environment.Request;
|
|
||||||
import org.apache.cocoon.environment.Response;
|
|
||||||
import org.apache.cocoon.environment.SourceResolver;
|
|
||||||
import org.apache.cocoon.reading.AbstractReader;
|
|
||||||
import org.apache.commons.collections.ExtendedProperties;
|
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.solr.common.params.CommonParams;
|
|
||||||
import org.apache.solr.common.params.FacetParams;
|
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
|
||||||
import org.dspace.constants.Constants;
|
|
||||||
import org.dspace.core.ConfigurationManager;
|
|
||||||
import org.dspace.discovery.SolrServiceImpl;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class used to search in solr and return a json formatted string
|
|
||||||
*
|
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
|
||||||
* @author Mark Diggory (markd at atmire dot com)
|
|
||||||
* @author Ben Bosman (ben at atmire dot com)
|
|
||||||
*/
|
|
||||||
public class JSONSolrSearcher extends AbstractReader implements Recyclable {
|
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(JSONSolrSearcher.class);
|
|
||||||
/** These are all our parameters which can be used by this generator **/
|
|
||||||
private String query;
|
|
||||||
private String[] filterQueries;
|
|
||||||
private String[] facetFields;
|
|
||||||
private int facetLimit;
|
|
||||||
private String facetSort;
|
|
||||||
private int facetMinCount;
|
|
||||||
private String solrServerUrl;
|
|
||||||
private String jsonWrf;
|
|
||||||
|
|
||||||
|
|
||||||
/** The Cocoon response */
|
|
||||||
protected Response response;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
|
|
||||||
//Retrieve all the given parameters
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
|
||||||
this.response = ObjectModelHelper.getResponse(objectModel);
|
|
||||||
|
|
||||||
|
|
||||||
query = request.getParameter(CommonParams.Q);
|
|
||||||
if(query == null)
|
|
||||||
{
|
|
||||||
query = "*:*";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Retrieve all our filter queries
|
|
||||||
filterQueries = request.getParameterValues(CommonParams.FQ);
|
|
||||||
|
|
||||||
//Retrieve our facet fields
|
|
||||||
facetFields = request.getParameterValues(FacetParams.FACET_FIELD);
|
|
||||||
|
|
||||||
//Retrieve our facet limit (if any)
|
|
||||||
if(request.getParameter(FacetParams.FACET_LIMIT) != null){
|
|
||||||
try{
|
|
||||||
facetLimit = Integer.parseInt(request.getParameter(FacetParams.FACET_LIMIT));
|
|
||||||
}catch (Exception e){
|
|
||||||
//Should an invalid value be supplied use -1
|
|
||||||
facetLimit = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
facetLimit = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Retrieve our sorting value
|
|
||||||
facetSort = request.getParameter(FacetParams.FACET_SORT);
|
|
||||||
//Make sure we have a valid sorting value
|
|
||||||
if(!FacetParams.FACET_SORT_INDEX.equals(facetSort) && !FacetParams.FACET_SORT_COUNT.equals(facetSort))
|
|
||||||
{
|
|
||||||
facetSort = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Retrieve our facet min count
|
|
||||||
facetMinCount = 1;
|
|
||||||
try{
|
|
||||||
facetMinCount = Integer.parseInt(request.getParameter(FacetParams.FACET_MINCOUNT));
|
|
||||||
}catch (Exception e){
|
|
||||||
facetMinCount = 1;
|
|
||||||
}
|
|
||||||
jsonWrf = request.getParameter("json.wrf");
|
|
||||||
|
|
||||||
//Retrieve our discovery solr path
|
|
||||||
ExtendedProperties props = null;
|
|
||||||
//Method that will retrieve all the possible configs we have
|
|
||||||
|
|
||||||
props = ExtendedProperties.convertProperties(ConfigurationManager.getProperties());
|
|
||||||
|
|
||||||
InputStream is = null;
|
|
||||||
try {
|
|
||||||
File config = new File(props.getProperty("dspace.dir") + "/config/dspace-solr-search.cfg");
|
|
||||||
if (config.exists()) {
|
|
||||||
props.combine(new ExtendedProperties(config.getAbsolutePath()));
|
|
||||||
} else {
|
|
||||||
is = SolrServiceImpl.class.getResourceAsStream("dspace-solr-search.cfg");
|
|
||||||
ExtendedProperties defaults = new ExtendedProperties();
|
|
||||||
defaults.load(is);
|
|
||||||
props.combine(defaults);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
log.error("Error while retrieving solr url", e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(props.getProperty("solr.search.server") != null)
|
|
||||||
{
|
|
||||||
this.solrServerUrl = props.getProperty("solr.search.server").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate() throws IOException, SAXException, ProcessingException {
|
|
||||||
if(solrServerUrl == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
|
|
||||||
String solrRequestUrl = solrServerUrl + "/select";
|
|
||||||
|
|
||||||
//Add our default parameters
|
|
||||||
params.put(CommonParams.ROWS, "0");
|
|
||||||
params.put(CommonParams.WT, "json");
|
|
||||||
//We uwe json as out output type
|
|
||||||
params.put("json.nl", "map");
|
|
||||||
params.put("json.wrf", jsonWrf);
|
|
||||||
params.put(FacetParams.FACET, Boolean.TRUE.toString());
|
|
||||||
|
|
||||||
//Generate our json out of the given params
|
|
||||||
try
|
|
||||||
{
|
|
||||||
params.put(CommonParams.Q, URLEncoder.encode(query, Constants.DEFAULT_ENCODING));
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException uee)
|
|
||||||
{
|
|
||||||
//Should never occur
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.put(FacetParams.FACET_LIMIT, String.valueOf(facetLimit));
|
|
||||||
if(facetSort != null)
|
|
||||||
{
|
|
||||||
params.put(FacetParams.FACET_SORT, facetSort);
|
|
||||||
}
|
|
||||||
params.put(FacetParams.FACET_MINCOUNT, String.valueOf(facetMinCount));
|
|
||||||
|
|
||||||
solrRequestUrl = AbstractDSpaceTransformer.generateURL(solrRequestUrl, params);
|
|
||||||
if (facetFields != null || filterQueries != null) {
|
|
||||||
StringBuilder urlBuilder = new StringBuilder(solrRequestUrl);
|
|
||||||
if(facetFields != null){
|
|
||||||
|
|
||||||
//Add our facet fields
|
|
||||||
for (String facetField : facetFields) {
|
|
||||||
urlBuilder.append("&").append(FacetParams.FACET_FIELD).append("=");
|
|
||||||
|
|
||||||
//This class can only be used for autocomplete facet fields
|
|
||||||
if(!facetField.endsWith(".year") && !facetField.endsWith("_ac"))
|
|
||||||
{
|
|
||||||
urlBuilder.append(URLEncoder.encode(facetField + "_ac", Constants.DEFAULT_ENCODING));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
urlBuilder.append(URLEncoder.encode(facetField, Constants.DEFAULT_ENCODING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if(filterQueries != null){
|
|
||||||
for (String filterQuery : filterQueries) {
|
|
||||||
urlBuilder.append("&").append(CommonParams.FQ).append("=").append(URLEncoder.encode(filterQuery, Constants.DEFAULT_ENCODING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
solrRequestUrl = urlBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
GetMethod get = new GetMethod(solrRequestUrl);
|
|
||||||
new HttpClient().executeMethod(get);
|
|
||||||
String result = get.getResponseBodyAsString();
|
|
||||||
if(result != null){
|
|
||||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(result.getBytes("UTF-8"));
|
|
||||||
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
|
|
||||||
response.setHeader("Content-Length", String.valueOf(result.length()));
|
|
||||||
int length;
|
|
||||||
while ((length = inputStream.read(buffer)) > -1)
|
|
||||||
{
|
|
||||||
out.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error while getting json solr result for discovery search recommendation", e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -58,6 +58,7 @@ and searching the repository.
|
|||||||
<map:transformer name="SearchFacetFilter" src="org.dspace.app.xmlui.aspect.discovery.SearchFacetFilter"/>
|
<map:transformer name="SearchFacetFilter" src="org.dspace.app.xmlui.aspect.discovery.SearchFacetFilter"/>
|
||||||
<map:transformer name="FrontPageSearch" src="org.dspace.app.xmlui.aspect.discovery.SiteViewer"/>
|
<map:transformer name="FrontPageSearch" src="org.dspace.app.xmlui.aspect.discovery.SiteViewer"/>
|
||||||
<map:transformer name="SiteRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.SiteRecentSubmissions"/>
|
<map:transformer name="SiteRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.SiteRecentSubmissions"/>
|
||||||
|
<map:transformer name="SidebarFacetsTransformer" src="org.dspace.app.xmlui.aspect.discovery.SidebarFacetsTransformer"/>
|
||||||
|
|
||||||
|
|
||||||
<map:transformer name="CommunitySearch" src="org.dspace.app.xmlui.aspect.discovery.CommunitySearch"/>
|
<map:transformer name="CommunitySearch" src="org.dspace.app.xmlui.aspect.discovery.CommunitySearch"/>
|
||||||
@@ -69,7 +70,6 @@ and searching the repository.
|
|||||||
|
|
||||||
|
|
||||||
<map:transformer name="RelatedItems" src="org.dspace.app.xmlui.aspect.discovery.RelatedItems"/>
|
<map:transformer name="RelatedItems" src="org.dspace.app.xmlui.aspect.discovery.RelatedItems"/>
|
||||||
<map:transformer name="ItemFacets" src="org.dspace.app.xmlui.aspect.discovery.ItemFacets"/>
|
|
||||||
</map:transformers>
|
</map:transformers>
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +105,7 @@ and searching the repository.
|
|||||||
along with a list of top level communities in DSpace.
|
along with a list of top level communities in DSpace.
|
||||||
-->
|
-->
|
||||||
<map:match pattern="">
|
<map:match pattern="">
|
||||||
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<map:transform type="FrontPageSearch"/>
|
<map:transform type="FrontPageSearch"/>
|
||||||
|
|
||||||
<map:transform type="SiteRecentSubmissions"/>
|
<map:transform type="SiteRecentSubmissions"/>
|
||||||
@@ -124,7 +125,8 @@ and searching the repository.
|
|||||||
|
|
||||||
<!-- Search -->
|
<!-- Search -->
|
||||||
<map:match pattern="discover">
|
<map:match pattern="discover">
|
||||||
<map:transform type="SimpleSearch"/>
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
|
<map:transform type="SimpleSearch"/>
|
||||||
<map:transform type="IncludePageMeta">
|
<map:transform type="IncludePageMeta">
|
||||||
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/style.css"/>
|
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/style.css"/>
|
||||||
|
|
||||||
@@ -143,11 +145,6 @@ and searching the repository.
|
|||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
<!--<map:match pattern="simple-search">-->
|
|
||||||
<!--<map:transform type="SimpleSearch"/>-->
|
|
||||||
<!--<map:serialize type="xml"/>-->
|
|
||||||
<!--</map:match>-->
|
|
||||||
|
|
||||||
<!--<map:match pattern="browse-discovery">-->
|
<!--<map:match pattern="browse-discovery">-->
|
||||||
<!--<map:transform type="BrowseFacet"/>-->
|
<!--<map:transform type="BrowseFacet"/>-->
|
||||||
<!--<map:serialize type="xml"/>-->
|
<!--<map:serialize type="xml"/>-->
|
||||||
@@ -158,13 +155,6 @@ and searching the repository.
|
|||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
<!--
|
|
||||||
<map:match pattern="advanced-search">
|
|
||||||
<map:transform type="AdvancedSearch"/>
|
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Handle specific features -->
|
<!-- Handle specific features -->
|
||||||
<map:match pattern="handle/*/**">
|
<map:match pattern="handle/*/**">
|
||||||
|
|
||||||
@@ -180,7 +170,8 @@ and searching the repository.
|
|||||||
|
|
||||||
<!-- Simple search -->
|
<!-- Simple search -->
|
||||||
<map:match pattern="handle/*/*/discover">
|
<map:match pattern="handle/*/*/discover">
|
||||||
<map:transform type="SimpleSearch"/>
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
|
<map:transform type="SimpleSearch"/>
|
||||||
<map:transform type="IncludePageMeta">
|
<map:transform type="IncludePageMeta">
|
||||||
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/style.css"/>
|
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/style.css"/>
|
||||||
|
|
||||||
@@ -204,35 +195,26 @@ and searching the repository.
|
|||||||
<map:transform type="SearchFacetFilter"/>
|
<map:transform type="SearchFacetFilter"/>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
<!-- Simple search again, but this time they said it -->
|
|
||||||
<!--<map:match pattern="handle/*/*/simple-discover">-->
|
|
||||||
<!--<map:transform type="SimpleSearch"/>-->
|
|
||||||
<!--<map:serialize type="xml"/>-->
|
|
||||||
<!--</map:match>-->
|
|
||||||
|
|
||||||
<!-- Advanced search
|
|
||||||
<map:match pattern="handle/*/*/advanced-search">
|
|
||||||
<map:transform type="AdvancedSearch"/>
|
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
|
||||||
-->
|
|
||||||
</map:match>
|
</map:match>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
<map:match pattern="handle/*/*">
|
<map:match pattern="handle/*/*">
|
||||||
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
||||||
<map:match type="HandleTypeMatcher" pattern="community">
|
<map:match type="HandleTypeMatcher" pattern="community">
|
||||||
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<map:transform type="CommunitySearch"/>
|
<map:transform type="CommunitySearch"/>
|
||||||
<map:transform type="CommunityRecentSubmissions"/>
|
<map:transform type="CommunityRecentSubmissions"/>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
<map:match type="HandleTypeMatcher" pattern="collection">
|
<map:match type="HandleTypeMatcher" pattern="collection">
|
||||||
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<map:transform type="CollectionSearch"/>
|
<map:transform type="CollectionSearch"/>
|
||||||
<map:transform type="CollectionRecentSubmissions"/>
|
<map:transform type="CollectionRecentSubmissions"/>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
<map:match type="HandleTypeMatcher" pattern="item">
|
<map:match type="HandleTypeMatcher" pattern="item">
|
||||||
<map:transform type="ItemFacets"/>
|
<!--<map:transform type="SidebarFacetsTransformer"/>-->
|
||||||
|
<!--<map:transform type="ItemFacets"/>-->
|
||||||
<map:transform type="RelatedItems"/>
|
<map:transform type="RelatedItems"/>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<map:components>
|
<map:components>
|
||||||
|
|
||||||
<map:readers>
|
<map:readers>
|
||||||
<map:reader name="JSONSolrSearcher" src="org.dspace.app.xmlui.aspect.discovery.json.JSONSolrSearcher"/>
|
<map:reader name="JSONDiscoverySearcher" src="org.dspace.app.xmlui.aspect.discovery.json.JSONDiscoverySearcher"/>
|
||||||
</map:readers>
|
</map:readers>
|
||||||
|
|
||||||
<map:serializers>
|
<map:serializers>
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
<map:pipeline>
|
<map:pipeline>
|
||||||
|
|
||||||
<map:match pattern="**">
|
<map:match pattern="**">
|
||||||
<map:match pattern="searchSolr">
|
<map:match pattern="search">
|
||||||
<map:read type="JSONSolrSearcher" />
|
<map:read type="JSONDiscoverySearcher" />
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
|
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
</map:pipeline>
|
</map:pipeline>
|
||||||
</map:pipelines>
|
</map:pipelines>
|
||||||
|
|
||||||
</map:sitemap>
|
</map:sitemap>
|
||||||
|
@@ -11,7 +11,7 @@ var defaultFacets = new Array();
|
|||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
$(function () {
|
$(function () {
|
||||||
var searchUrl = $("input[name='solr-search-url']").val();
|
var searchUrl = $("input[name='discovery-json-search-url']").val();
|
||||||
Manager = new AjaxSolr.Manager({
|
Manager = new AjaxSolr.Manager({
|
||||||
solrUrl: searchUrl
|
solrUrl: searchUrl
|
||||||
});
|
});
|
||||||
@@ -82,9 +82,9 @@ var defaultFacets = new Array();
|
|||||||
if($(this).val() != '*'){
|
if($(this).val() != '*'){
|
||||||
var facetVal = $(this).val();
|
var facetVal = $(this).val();
|
||||||
//Only facet on autocomplete fields
|
//Only facet on autocomplete fields
|
||||||
if(!facetVal.match(/.year$/)){
|
// if(!facetVal.match(/.year$/)){
|
||||||
facetVal += '_ac';
|
// facetVal += '_ac';
|
||||||
}
|
// }
|
||||||
facetFields = [facetVal];
|
facetFields = [facetVal];
|
||||||
} else {
|
} else {
|
||||||
facetFields = defaultFacets;
|
facetFields = defaultFacets;
|
||||||
|
@@ -17,8 +17,7 @@ AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractFacetWidget.extend({
|
|||||||
|
|
||||||
var callback = function (response) {
|
var callback = function (response) {
|
||||||
var list = [];
|
var list = [];
|
||||||
for (var i = 0; i < self.fields.length; i++) {
|
for (var field in response.facet_counts.facet_fields) {
|
||||||
var field = self.fields[i];
|
|
||||||
for (var facet in response.facet_counts.facet_fields[field]) {
|
for (var facet in response.facet_counts.facet_fields[field]) {
|
||||||
list.push({
|
list.push({
|
||||||
field: field,
|
field: field,
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>dspace-discovery-provider</module>
|
<module>dspace-discovery-provider</module>
|
||||||
|
<module>dspace-discovery-solr</module>
|
||||||
<module>dspace-discovery-xmlui-api</module>
|
<module>dspace-discovery-xmlui-api</module>
|
||||||
<module>dspace-discovery-xmlui-webapp</module>
|
<module>dspace-discovery-xmlui-webapp</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
@@ -10,6 +10,7 @@ solr.facets.search=dc.contributor.author,dc.subject,dc.date.issued_dt
|
|||||||
solr.facets.site=dc.contributor.author,dc.subject,dc.date.issued_dt
|
solr.facets.site=dc.contributor.author,dc.subject,dc.date.issued_dt
|
||||||
solr.facets.community=dc.contributor.author,dc.subject,dc.date.issued_dt
|
solr.facets.community=dc.contributor.author,dc.subject,dc.date.issued_dt
|
||||||
solr.facets.collection=dc.contributor.author,dc.subject,dc.date.issued_dt
|
solr.facets.collection=dc.contributor.author,dc.subject,dc.date.issued_dt
|
||||||
|
#Item facets are not supported at the moment
|
||||||
# solr.facets.item=dc.contributor.author,dc.subject,dc.date.issued_dt
|
# solr.facets.item=dc.contributor.author,dc.subject,dc.date.issued_dt
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ solr.facets.collection=dc.contributor.author,dc.subject,dc.date.issued_dt
|
|||||||
#solr.browse.default.filterQuery=
|
#solr.browse.default.filterQuery=
|
||||||
|
|
||||||
# The filters which can be selected in the search form
|
# The filters which can be selected in the search form
|
||||||
solr.search.filters=dc.title, dc.contributor.author, dc.subject, dc.date.issued.year
|
solr.search.filters=dc.title, dc.contributor.author:full, dc.subject:full, dc.date.issued.year
|
||||||
|
|
||||||
# Indexed fields which can sorted on in our search
|
# Indexed fields which can sorted on in our search
|
||||||
solr.search.sort=dc.title, dc.date.issued_dt
|
solr.search.sort=dc.title, dc.date.issued_dt
|
||||||
@@ -46,4 +47,4 @@ solr.recent-submissions.size=5
|
|||||||
recent.submissions.sort-option=dc.date.accessioned_dt
|
recent.submissions.sort-option=dc.date.accessioned_dt
|
||||||
|
|
||||||
#Use the property below to limit the number of facet filters in the side of the search page
|
#Use the property below to limit the number of facet filters in the side of the search page
|
||||||
#search.facet.max=10
|
#search.facet.max=10
|
||||||
|
@@ -140,6 +140,12 @@
|
|||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-discovery-solr</artifactId>
|
||||||
|
<version>1.8.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
||||||
@@ -169,4 +175,4 @@
|
|||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -555,10 +555,14 @@
|
|||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-discovery-provider</artifactId>
|
<artifactId>dspace-discovery-provider</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-discovery-solr</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -475,6 +475,20 @@
|
|||||||
</analyzer>
|
</analyzer>
|
||||||
</fieldType>
|
</fieldType>
|
||||||
|
|
||||||
|
|
||||||
|
<!--This field is used for auto complete features in the discovery search-->
|
||||||
|
<fieldType name="dspaceAutoCompleteFull" class="solr.TextField" sortMissingLast="true" omitNorms="true">
|
||||||
|
<analyzer>
|
||||||
|
<!--Split everything up by space-->
|
||||||
|
<tokenizer class="solr.KeywordTokenizerFactory"/>
|
||||||
|
|
||||||
|
<!--Lower cases our values-->
|
||||||
|
<filter class="solr.LowerCaseFilterFactory" />
|
||||||
|
<!-- The TrimFilter removes any leading or trailing whitespace -->
|
||||||
|
<filter class="solr.TrimFilterFactory" />
|
||||||
|
</analyzer>
|
||||||
|
</fieldType>
|
||||||
|
|
||||||
<fieldType name="dspaceFilter" class="solr.TextField" sortMissingLast="true" omitNorms="true">
|
<fieldType name="dspaceFilter" class="solr.TextField" sortMissingLast="true" omitNorms="true">
|
||||||
<analyzer>
|
<analyzer>
|
||||||
<!--Treats the entire field as a single token, regardless of its content-->
|
<!--Treats the entire field as a single token, regardless of its content-->
|
||||||
@@ -546,6 +560,7 @@
|
|||||||
|
|
||||||
<!--Dynamic field used for search autocompletion-->
|
<!--Dynamic field used for search autocompletion-->
|
||||||
<dynamicField name="*_ac" type="dspaceAutoComplete" indexed="true" stored="true" omitNorms="true" multiValued="true"/>
|
<dynamicField name="*_ac" type="dspaceAutoComplete" indexed="true" stored="true" omitNorms="true" multiValued="true"/>
|
||||||
|
<dynamicField name="*_ac.full" type="dspaceAutoCompleteFull" indexed="true" stored="true" omitNorms="true" multiValued="true"/>
|
||||||
|
|
||||||
<!--Dynamic field used for sidebar filters-->
|
<!--Dynamic field used for sidebar filters-->
|
||||||
<dynamicField name="*_filter" type="dspaceFilter" indexed="true" stored="true" multiValued="true" omitNorms="true" />
|
<dynamicField name="*_filter" type="dspaceFilter" indexed="true" stored="true" multiValued="true" omitNorms="true" />
|
||||||
|
5
pom.xml
5
pom.xml
@@ -281,6 +281,11 @@
|
|||||||
<artifactId>dspace-discovery-provider</artifactId>
|
<artifactId>dspace-discovery-provider</artifactId>
|
||||||
<version>1.8.0-SNAPSHOT</version>
|
<version>1.8.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-discovery-solr</artifactId>
|
||||||
|
<version>1.8.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
<!-- DSpace third Party Dependencies -->
|
<!-- DSpace third Party Dependencies -->
|
||||||
|
|
||||||
<!-- Explicitly Specify Latest Version of Spring -->
|
<!-- Explicitly Specify Latest Version of Spring -->
|
||||||
|
Reference in New Issue
Block a user