Merge branch 'DS-1229'
Conflicts: dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/themes/Mirage/lib/css/style.css
@@ -490,6 +490,8 @@ public class AuthorizeManager
|
|||||||
rp.setRpType(type);
|
rp.setRpType(type);
|
||||||
|
|
||||||
rp.update();
|
rp.update();
|
||||||
|
|
||||||
|
o.updateLastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -543,6 +545,8 @@ public class AuthorizeManager
|
|||||||
rp.setRpType(type);
|
rp.setRpType(type);
|
||||||
|
|
||||||
rp.update();
|
rp.update();
|
||||||
|
|
||||||
|
o.updateLastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -805,6 +809,8 @@ public class AuthorizeManager
|
|||||||
// and write out new policy
|
// and write out new policy
|
||||||
drp.update();
|
drp.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dest.updateLastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -820,6 +826,8 @@ public class AuthorizeManager
|
|||||||
public static void removeAllPolicies(Context c, DSpaceObject o)
|
public static void removeAllPolicies(Context c, DSpaceObject o)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
|
o.updateLastModified();
|
||||||
|
|
||||||
// FIXME: authorization check?
|
// FIXME: authorization check?
|
||||||
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
||||||
+ "resource_type_id= ? AND resource_id= ? ",
|
+ "resource_type_id= ? AND resource_id= ? ",
|
||||||
@@ -882,6 +890,7 @@ public class AuthorizeManager
|
|||||||
public static void removePoliciesActionFilter(Context context,
|
public static void removePoliciesActionFilter(Context context,
|
||||||
DSpaceObject dso, int actionID) throws SQLException
|
DSpaceObject dso, int actionID) throws SQLException
|
||||||
{
|
{
|
||||||
|
dso.updateLastModified();
|
||||||
if (actionID == -1)
|
if (actionID == -1)
|
||||||
{
|
{
|
||||||
// remove all policies from object
|
// remove all policies from object
|
||||||
@@ -929,6 +938,8 @@ public class AuthorizeManager
|
|||||||
public static void removeGroupPolicies(Context c, DSpaceObject o, Group g)
|
public static void removeGroupPolicies(Context c, DSpaceObject o, Group g)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
|
o.updateLastModified();
|
||||||
|
|
||||||
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
||||||
+ "resource_type_id= ? AND resource_id= ? AND epersongroup_id= ? ",
|
+ "resource_type_id= ? AND resource_id= ? AND epersongroup_id= ? ",
|
||||||
o.getType(), o.getID(), g.getID());
|
o.getType(), o.getID(), g.getID());
|
||||||
@@ -950,6 +961,7 @@ public class AuthorizeManager
|
|||||||
public static void removeEPersonPolicies(Context c, DSpaceObject o, EPerson e)
|
public static void removeEPersonPolicies(Context c, DSpaceObject o, EPerson e)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
|
o.updateLastModified();
|
||||||
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
DatabaseManager.updateQuery(c, "DELETE FROM resourcepolicy WHERE "
|
||||||
+ "resource_type_id= ? AND resource_id= ? AND eperson_id= ? ",
|
+ "resource_type_id= ? AND resource_id= ? AND eperson_id= ? ",
|
||||||
o.getType(), o.getID(), e.getID());
|
o.getType(), o.getID(), e.getID());
|
||||||
|
@@ -180,6 +180,16 @@ public class ResourcePolicy
|
|||||||
*/
|
*/
|
||||||
public void delete() throws SQLException
|
public void delete() throws SQLException
|
||||||
{
|
{
|
||||||
|
if(getResourceID() != -1 && getResourceType() != -1)
|
||||||
|
{
|
||||||
|
//A policy for a DSpace Object has been modified, fire a modify event on the DSpace object
|
||||||
|
DSpaceObject dso = DSpaceObject.find(myContext, getResourceType(), getResourceID());
|
||||||
|
if(dso != null)
|
||||||
|
{
|
||||||
|
dso.updateLastModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: authorizations
|
// FIXME: authorizations
|
||||||
// Remove ourself
|
// Remove ourself
|
||||||
DatabaseManager.delete(myContext, myRow);
|
DatabaseManager.delete(myContext, myRow);
|
||||||
@@ -455,8 +465,15 @@ public class ResourcePolicy
|
|||||||
/**
|
/**
|
||||||
* Update the ResourcePolicy
|
* Update the ResourcePolicy
|
||||||
*/
|
*/
|
||||||
public void update() throws SQLException
|
public void update() throws SQLException, AuthorizeException {
|
||||||
{
|
if(getResourceID() != -1 && getResourceType() != -1){
|
||||||
|
//A policy for a DSpace Object has been modified, fire a modify event on the DSpace object
|
||||||
|
DSpaceObject dso = DSpaceObject.find(myContext, getResourceType(), getResourceID());
|
||||||
|
if(dso != null){
|
||||||
|
dso.updateLastModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Check authorisation
|
// FIXME: Check authorisation
|
||||||
DatabaseManager.update(myContext, myRow);
|
DatabaseManager.update(myContext, myRow);
|
||||||
}
|
}
|
||||||
|
@@ -384,6 +384,12 @@ public class BrowseItem extends DSpaceObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isArchived()
|
public boolean isArchived()
|
||||||
{
|
{
|
||||||
return in_archive;
|
return in_archive;
|
||||||
|
@@ -735,4 +735,11 @@ public class Bitstream extends DSpaceObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
//Also fire a modified event since the bitstream HAS been modified
|
||||||
|
bContext.addEvent(new Event(Event.MODIFY, Constants.BITSTREAM, getID(), null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -811,4 +811,10 @@ public class Bundle extends DSpaceObject
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1487,4 +1487,11 @@ public class Collection extends DSpaceObject
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
//Also fire a modified event since the collection HAS been modified
|
||||||
|
ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION, getID(), null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1282,4 +1282,11 @@ public class Community extends DSpaceObject
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
//Also fire a modified event since the community HAS been modified
|
||||||
|
ourContext.addEvent(new Event(Event.MODIFY, Constants.COMMUNITY, getID(), null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -161,4 +161,6 @@ public abstract class DSpaceObject
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void updateLastModified();
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.content;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -326,11 +327,18 @@ public class Item extends DSpaceObject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that updates the last modified date of the item
|
* Method that updates the last modified date of the item
|
||||||
* The modified boolean will be set to true and the actual date update will occur on item.update().
|
|
||||||
*/
|
*/
|
||||||
void updateLastModified()
|
public void updateLastModified()
|
||||||
{
|
{
|
||||||
modified = true;
|
try {
|
||||||
|
Date lastModified = new Timestamp(new Date().getTime());
|
||||||
|
itemRow.setColumn("last_modified", lastModified);
|
||||||
|
DatabaseManager.updateQuery(ourContext, "UPDATE item SET last_modified = ? WHERE item_id= ? ", lastModified, getID());
|
||||||
|
//Also fire a modified event since the item HAS been modified
|
||||||
|
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), null));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(LogManager.getHeader(ourContext, "Error while updating last modified timestamp", "Item: " + getID()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -105,6 +105,12 @@ public class Site extends DSpaceObject
|
|||||||
return ConfigurationManager.getProperty("dspace.name");
|
return ConfigurationManager.getProperty("dspace.name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public String getURL()
|
public String getURL()
|
||||||
{
|
{
|
||||||
return ConfigurationManager.getProperty("dspace.url");
|
return ConfigurationManager.getProperty("dspace.url");
|
||||||
|
@@ -1103,4 +1103,10 @@ public class EPerson extends DSpaceObject
|
|||||||
return getEmail();
|
return getEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1419,4 +1419,10 @@ public class Group extends DSpaceObject
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLastModified()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for one field that is to be highlighted
|
||||||
|
* Giving 0 as max chars ensures that the entire field is returned !
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoverHitHighlightingField {
|
||||||
|
|
||||||
|
public static final int UNLIMITED_FRAGMENT_LENGTH = 0;
|
||||||
|
|
||||||
|
private String field;
|
||||||
|
private int maxChars;
|
||||||
|
private int maxSnippets;
|
||||||
|
|
||||||
|
public DiscoverHitHighlightingField(String field, int maxChars, int maxSnippets)
|
||||||
|
{
|
||||||
|
this.field = field;
|
||||||
|
this.maxChars = maxChars;
|
||||||
|
this.maxSnippets = maxSnippets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getField()
|
||||||
|
{
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max number of characters that should be shown for a
|
||||||
|
* field containing a matching hit. e.g. If maxChars = 200
|
||||||
|
* and a hit is found in the full-text the 200 chars
|
||||||
|
* surrounding the hit will be shown
|
||||||
|
*/
|
||||||
|
public int getMaxChars()
|
||||||
|
{
|
||||||
|
return maxChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxSnippets()
|
||||||
|
{
|
||||||
|
return maxSnippets;
|
||||||
|
}
|
||||||
|
}
|
@@ -40,6 +40,7 @@ public class DiscoverQuery {
|
|||||||
private int facetLimit = -1;
|
private int facetLimit = -1;
|
||||||
private int facetMinCount = -1;
|
private int facetMinCount = -1;
|
||||||
private int facetOffset = 0;
|
private int facetOffset = 0;
|
||||||
|
private Map<String, DiscoverHitHighlightingField> hitHighlighting;
|
||||||
|
|
||||||
/** Used when you want to search for a specific field value **/
|
/** Used when you want to search for a specific field value **/
|
||||||
private List<String> searchFields;
|
private List<String> searchFields;
|
||||||
@@ -55,6 +56,7 @@ public class DiscoverQuery {
|
|||||||
this.facetFields = new ArrayList<DiscoverFacetField>();
|
this.facetFields = new ArrayList<DiscoverFacetField>();
|
||||||
this.facetQueries = new ArrayList<String>();
|
this.facetQueries = new ArrayList<String>();
|
||||||
this.searchFields = new ArrayList<String>();
|
this.searchFields = new ArrayList<String>();
|
||||||
|
this.hitHighlighting = new HashMap<String, DiscoverHitHighlightingField>();
|
||||||
//Use a linked hashmap since sometimes insertion order might matter
|
//Use a linked hashmap since sometimes insertion order might matter
|
||||||
this.properties = new LinkedHashMap<String, List<String>>();
|
this.properties = new LinkedHashMap<String, List<String>>();
|
||||||
}
|
}
|
||||||
@@ -239,10 +241,27 @@ public class DiscoverQuery {
|
|||||||
public void addProperty(String property, String value){
|
public void addProperty(String property, String value){
|
||||||
List<String> toAddList = properties.get(property);
|
List<String> toAddList = properties.get(property);
|
||||||
if(toAddList == null)
|
if(toAddList == null)
|
||||||
|
{
|
||||||
toAddList = new ArrayList<String>();
|
toAddList = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
toAddList.add(value);
|
toAddList.add(value);
|
||||||
|
|
||||||
properties.put(property, toAddList);
|
properties.put(property, toAddList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DiscoverHitHighlightingField getHitHighlightingField(String field)
|
||||||
|
{
|
||||||
|
return hitHighlighting.get(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DiscoverHitHighlightingField> getHitHighlightingFields()
|
||||||
|
{
|
||||||
|
return new ArrayList<DiscoverHitHighlightingField>(hitHighlighting.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHitHighlightingField(DiscoverHitHighlightingField hitHighlighting)
|
||||||
|
{
|
||||||
|
this.hitHighlighting.put(hitHighlighting.getField(), hitHighlighting);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,12 +25,15 @@ public class DiscoverResult {
|
|||||||
/** A map that contains all the documents sougth after, the key is a string representation of the DSpace object */
|
/** 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 Map<String, List<SearchDocument>> searchDocuments;
|
||||||
private int maxResults = -1;
|
private int maxResults = -1;
|
||||||
|
private int searchTime;
|
||||||
|
private Map<String, DSpaceObjectHighlightResult> highlightedResults;
|
||||||
|
|
||||||
|
|
||||||
public DiscoverResult() {
|
public DiscoverResult() {
|
||||||
dspaceObjects = new ArrayList<DSpaceObject>();
|
dspaceObjects = new ArrayList<DSpaceObject>();
|
||||||
facetResults = new LinkedHashMap<String, List<FacetResult>>();
|
facetResults = new LinkedHashMap<String, List<FacetResult>>();
|
||||||
searchDocuments = new LinkedHashMap<String, List<SearchDocument>>();
|
searchDocuments = new LinkedHashMap<String, List<SearchDocument>>();
|
||||||
|
highlightedResults = new HashMap<String, DSpaceObjectHighlightResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -66,6 +69,16 @@ public class DiscoverResult {
|
|||||||
this.maxResults = maxResults;
|
this.maxResults = maxResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSearchTime()
|
||||||
|
{
|
||||||
|
return searchTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchTime(int searchTime)
|
||||||
|
{
|
||||||
|
this.searchTime = searchTime;
|
||||||
|
}
|
||||||
|
|
||||||
public void addFacetResult(String facetField, FacetResult ...facetResults){
|
public void addFacetResult(String facetField, FacetResult ...facetResults){
|
||||||
List<FacetResult> facetValues = this.facetResults.get(facetField);
|
List<FacetResult> facetValues = this.facetResults.get(facetField);
|
||||||
if(facetValues == null)
|
if(facetValues == null)
|
||||||
@@ -84,6 +97,16 @@ public class DiscoverResult {
|
|||||||
return facetResults.get(facet) == null ? new ArrayList<FacetResult>() : facetResults.get(facet);
|
return facetResults.get(facet) == null ? new ArrayList<FacetResult>() : facetResults.get(facet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DSpaceObjectHighlightResult getHighlightedResults(DSpaceObject dso)
|
||||||
|
{
|
||||||
|
return highlightedResults.get(dso.getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHighlightedResult(DSpaceObject dso, DSpaceObjectHighlightResult highlightedResult)
|
||||||
|
{
|
||||||
|
this.highlightedResults.put(dso.getHandle(), highlightedResult);
|
||||||
|
}
|
||||||
|
|
||||||
public static final class FacetResult{
|
public static final class FacetResult{
|
||||||
private String asFilterQuery;
|
private String asFilterQuery;
|
||||||
private String displayedValue;
|
private String displayedValue;
|
||||||
@@ -108,6 +131,28 @@ public class DiscoverResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class DSpaceObjectHighlightResult
|
||||||
|
{
|
||||||
|
private DSpaceObject dso;
|
||||||
|
private Map<String, List<String>> highlightResults;
|
||||||
|
|
||||||
|
public DSpaceObjectHighlightResult(DSpaceObject dso, Map<String, List<String>> highlightResults)
|
||||||
|
{
|
||||||
|
this.dso = dso;
|
||||||
|
this.highlightResults = highlightResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DSpaceObject getDso()
|
||||||
|
{
|
||||||
|
return dso;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getHighlightResults(String metadataKey)
|
||||||
|
{
|
||||||
|
return highlightResults.get(metadataKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addSearchDocument(DSpaceObject dso, SearchDocument searchDocument){
|
public void addSearchDocument(DSpaceObject dso, SearchDocument searchDocument){
|
||||||
String dsoString = SearchDocument.getDspaceObjectStringRepresentation(dso);
|
String dsoString = SearchDocument.getDspaceObjectStringRepresentation(dso);
|
||||||
List<SearchDocument> docs = searchDocuments.get(dsoString);
|
List<SearchDocument> docs = searchDocuments.get(dsoString);
|
||||||
|
@@ -8,8 +8,9 @@
|
|||||||
package org.dspace.discovery;
|
package org.dspace.discovery;
|
||||||
|
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.discovery.configuration.DiscoverySortConfiguration;
|
import org.dspace.discovery.configuration.DiscoveryMoreLikeThisConfiguration;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -28,23 +29,13 @@ public interface SearchService {
|
|||||||
|
|
||||||
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query) throws SearchServiceException;
|
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query) throws SearchServiceException;
|
||||||
|
|
||||||
InputStream searchJSON(DiscoverQuery query, String jsonIdentifier) throws SearchServiceException;
|
InputStream searchJSON(Context context, DiscoverQuery query, String jsonIdentifier) throws SearchServiceException;
|
||||||
|
|
||||||
InputStream searchJSON(DiscoverQuery query, DSpaceObject dso, String jsonIdentifier) throws SearchServiceException;
|
InputStream searchJSON(Context context, DiscoverQuery query, DSpaceObject dso, String jsonIdentifier) throws SearchServiceException;
|
||||||
|
|
||||||
|
|
||||||
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
|
* Transforms the given string field and value into a filter query
|
||||||
* @param context the DSpace context
|
* @param context the DSpace context
|
||||||
@@ -53,7 +44,9 @@ public interface SearchService {
|
|||||||
* @return a filter query
|
* @return a filter query
|
||||||
* @throws SQLException ...
|
* @throws SQLException ...
|
||||||
*/
|
*/
|
||||||
DiscoverFilterQuery toFilterQuery(Context context, String field, String value) throws SQLException;
|
DiscoverFilterQuery toFilterQuery(Context context, String field, String operator, String value) throws SQLException;
|
||||||
|
|
||||||
|
List<Item> getRelatedItems(Context context, Item item, DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the metadata field of the given sort configuration into the indexed field which we can then use in our solr queries
|
* Transforms the metadata field of the given sort configuration into the indexed field which we can then use in our solr queries
|
||||||
|
@@ -7,18 +7,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.discovery.configuration;
|
package org.dspace.discovery.configuration;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public class DiscoveryConfiguration {
|
public class DiscoveryConfiguration implements InitializingBean{
|
||||||
|
|
||||||
/** The configuration for the sidebar facets **/
|
/** The configuration for the sidebar facets **/
|
||||||
private List<SidebarFacetConfiguration> sidebarFacets = new ArrayList<SidebarFacetConfiguration>();
|
private List<DiscoverySearchFilterFacet> sidebarFacets = new ArrayList<DiscoverySearchFilterFacet>();
|
||||||
|
|
||||||
/** The default filter queries which will be applied to any search & the recent submissions **/
|
/** The default filter queries which will be applied to any search & the recent submissions **/
|
||||||
private List<String> defaultFilterQueries;
|
private List<String> defaultFilterQueries;
|
||||||
@@ -32,6 +35,8 @@ public class DiscoveryConfiguration {
|
|||||||
private DiscoverySortConfiguration searchSortConfiguration;
|
private DiscoverySortConfiguration searchSortConfiguration;
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
private DiscoveryHitHighlightingConfiguration hitHighlightingConfiguration;
|
||||||
|
private DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
@@ -41,12 +46,12 @@ public class DiscoveryConfiguration {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SidebarFacetConfiguration> getSidebarFacets() {
|
public List<DiscoverySearchFilterFacet> getSidebarFacets() {
|
||||||
return sidebarFacets;
|
return sidebarFacets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Required
|
@Required
|
||||||
public void setSidebarFacets(List<SidebarFacetConfiguration> sidebarFacets) {
|
public void setSidebarFacets(List<DiscoverySearchFilterFacet> sidebarFacets) {
|
||||||
this.sidebarFacets = sidebarFacets;
|
this.sidebarFacets = sidebarFacets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,4 +93,46 @@ public class DiscoveryConfiguration {
|
|||||||
public void setSearchSortConfiguration(DiscoverySortConfiguration searchSortConfiguration) {
|
public void setSearchSortConfiguration(DiscoverySortConfiguration searchSortConfiguration) {
|
||||||
this.searchSortConfiguration = searchSortConfiguration;
|
this.searchSortConfiguration = searchSortConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHitHighlightingConfiguration(DiscoveryHitHighlightingConfiguration hitHighlightingConfiguration) {
|
||||||
|
this.hitHighlightingConfiguration = hitHighlightingConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryHitHighlightingConfiguration getHitHighlightingConfiguration() {
|
||||||
|
return hitHighlightingConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoreLikeThisConfiguration(DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration) {
|
||||||
|
this.moreLikeThisConfiguration = moreLikeThisConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryMoreLikeThisConfiguration getMoreLikeThisConfiguration() {
|
||||||
|
return moreLikeThisConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After all the properties are set check that the sidebar facets are a subset of our search filters
|
||||||
|
*
|
||||||
|
* @throws Exception throws an exception if this isn't the case
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
Collection missingSearchFilters = CollectionUtils.subtract(getSidebarFacets(), getSearchFilters());
|
||||||
|
if(CollectionUtils.isNotEmpty(missingSearchFilters))
|
||||||
|
{
|
||||||
|
StringBuilder error = new StringBuilder();
|
||||||
|
error.append("The following sidebar facet configurations are not present in the search filters list: ");
|
||||||
|
for (Object missingSearchFilter : missingSearchFilters)
|
||||||
|
{
|
||||||
|
DiscoverySearchFilter searchFilter = (DiscoverySearchFilter) missingSearchFilter;
|
||||||
|
error.append(searchFilter.getIndexFieldName()).append(" ");
|
||||||
|
|
||||||
|
}
|
||||||
|
error.append("all the sidebar facets MUST be a part of the search filters list.");
|
||||||
|
|
||||||
|
throw new DiscoveryConfigurationException(error.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that can be thrown if there are issues with the discovery configuration
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoveryConfigurationException extends Exception{
|
||||||
|
|
||||||
|
public DiscoveryConfigurationException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryConfigurationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryConfigurationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryConfigurationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@@ -16,7 +16,8 @@ public class DiscoveryConfigurationParameters {
|
|||||||
|
|
||||||
public static final String TYPE_TEXT = "text";
|
public static final String TYPE_TEXT = "text";
|
||||||
public static final String TYPE_DATE = "date";
|
public static final String TYPE_DATE = "date";
|
||||||
public static final String TYPE_AC = "date";
|
public static final String TYPE_HIERARCHICAL = "hierarchical";
|
||||||
|
public static final String TYPE_AC = "ac";
|
||||||
|
|
||||||
public static enum SORT {VALUE, COUNT}
|
public static enum SORT {VALUE, COUNT}
|
||||||
|
|
||||||
|
@@ -38,7 +38,7 @@ public class DiscoveryConfigurationService {
|
|||||||
System.out.println("Facets:");
|
System.out.println("Facets:");
|
||||||
DiscoveryConfiguration discoveryConfiguration = mainService.getMap().get(key);
|
DiscoveryConfiguration discoveryConfiguration = mainService.getMap().get(key);
|
||||||
for (int i = 0; i < discoveryConfiguration.getSidebarFacets().size(); i++) {
|
for (int i = 0; i < discoveryConfiguration.getSidebarFacets().size(); i++) {
|
||||||
SidebarFacetConfiguration sidebarFacet = discoveryConfiguration.getSidebarFacets().get(i);
|
DiscoverySearchFilterFacet sidebarFacet = discoveryConfiguration.getSidebarFacets().get(i);
|
||||||
System.out.println("\t" + sidebarFacet.getIndexFieldName());
|
System.out.println("\t" + sidebarFacet.getIndexFieldName());
|
||||||
for (int j = 0; j < sidebarFacet.getMetadataFields().size(); j++) {
|
for (int j = 0; j < sidebarFacet.getMetadataFields().size(); j++) {
|
||||||
String metadataField = sidebarFacet.getMetadataFields().get(j);
|
String metadataField = sidebarFacet.getMetadataFields().get(j);
|
||||||
@@ -49,7 +49,6 @@ public class DiscoveryConfigurationService {
|
|||||||
System.out.println("Search filters");
|
System.out.println("Search filters");
|
||||||
List<DiscoverySearchFilter> searchFilters = discoveryConfiguration.getSearchFilters();
|
List<DiscoverySearchFilter> searchFilters = discoveryConfiguration.getSearchFilters();
|
||||||
for (DiscoverySearchFilter searchFilter : searchFilters) {
|
for (DiscoverySearchFilter searchFilter : searchFilters) {
|
||||||
System.out.println("\t" + searchFilter.getIndexFieldName() + " full: " + searchFilter.isFullAutoComplete());
|
|
||||||
for (int i = 0; i < searchFilter.getMetadataFields().size(); i++) {
|
for (int i = 0; i < searchFilter.getMetadataFields().size(); i++) {
|
||||||
String metadataField = searchFilter.getMetadataFields().get(i);
|
String metadataField = searchFilter.getMetadataFields().get(i);
|
||||||
System.out.println("\t\t" + metadataField);
|
System.out.println("\t\t" + metadataField);
|
||||||
|
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration class that holds hit highlighting configuration for a single metadata field
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoveryHitHighlightFieldConfiguration
|
||||||
|
{
|
||||||
|
private String field;
|
||||||
|
private int maxSize = 0;
|
||||||
|
private int snippets = 3;
|
||||||
|
|
||||||
|
|
||||||
|
public String getField()
|
||||||
|
{
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setField(String field)
|
||||||
|
{
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxSize()
|
||||||
|
{
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxSize(int maxSize)
|
||||||
|
{
|
||||||
|
this.maxSize = maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum number of highlighted snippets to generate per field
|
||||||
|
* @param snippets the number of maximum snippets
|
||||||
|
*/
|
||||||
|
public void setSnippets(int snippets)
|
||||||
|
{
|
||||||
|
this.snippets = snippets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the maximum number of highlighted snippets to generate per field
|
||||||
|
*/
|
||||||
|
public int getSnippets()
|
||||||
|
{
|
||||||
|
return snippets;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that contains all the configuration concerning the hit highlighting in search resutls
|
||||||
|
* This class can be configured in the [dspace.dir]/config/spring/discovery/spring-dspace-addon-discovery-configuration-services.xml
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoveryHitHighlightingConfiguration
|
||||||
|
{
|
||||||
|
|
||||||
|
/* A list of metadata fields for which the hit highlighting is possible */
|
||||||
|
private List<DiscoveryHitHighlightFieldConfiguration> metadataFields;
|
||||||
|
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setMetadataFields(List<DiscoveryHitHighlightFieldConfiguration> metadataFields)
|
||||||
|
{
|
||||||
|
this.metadataFields = metadataFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DiscoveryHitHighlightFieldConfiguration> getMetadataFields()
|
||||||
|
{
|
||||||
|
return metadataFields;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that contains the more like this configuration on item pages
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoveryMoreLikeThisConfiguration {
|
||||||
|
private List<String> similarityMetadataFields;
|
||||||
|
private int minTermFrequency;
|
||||||
|
private int max;
|
||||||
|
private int minWordLength;
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setSimilarityMetadataFields(List<String> similarityMetadataFields)
|
||||||
|
{
|
||||||
|
this.similarityMetadataFields = similarityMetadataFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSimilarityMetadataFields()
|
||||||
|
{
|
||||||
|
return similarityMetadataFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setMinTermFrequency(int minTermFrequency)
|
||||||
|
{
|
||||||
|
this.minTermFrequency = minTermFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinTermFrequency()
|
||||||
|
{
|
||||||
|
return minTermFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setMax(int max)
|
||||||
|
{
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMax()
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinWordLength()
|
||||||
|
{
|
||||||
|
return minWordLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinWordLength(int minWordLength)
|
||||||
|
{
|
||||||
|
this.minWordLength = minWordLength;
|
||||||
|
}
|
||||||
|
}
|
@@ -16,10 +16,10 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class DiscoverySearchFilter {
|
public class DiscoverySearchFilter {
|
||||||
|
|
||||||
private String indexFieldName;
|
protected String indexFieldName;
|
||||||
private List<String> metadataFields;
|
protected List<String> metadataFields;
|
||||||
private boolean fullAutoComplete;
|
protected String type = DiscoveryConfigurationParameters.TYPE_TEXT;
|
||||||
private String type = DiscoveryConfigurationParameters.TYPE_TEXT;
|
public static final String FILTER_TYPE_DEFAULT = "default";
|
||||||
|
|
||||||
public String getIndexFieldName() {
|
public String getIndexFieldName() {
|
||||||
return indexFieldName;
|
return indexFieldName;
|
||||||
@@ -39,28 +39,29 @@ public class DiscoverySearchFilter {
|
|||||||
this.metadataFields = metadataFields;
|
this.metadataFields = metadataFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFullAutoComplete() {
|
|
||||||
return fullAutoComplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullAutoComplete(boolean fullAutoComplete) {
|
|
||||||
this.fullAutoComplete = fullAutoComplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type) {
|
public void setType(String type) throws DiscoveryConfigurationException {
|
||||||
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_TEXT)){
|
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_TEXT))
|
||||||
|
{
|
||||||
this.type = DiscoveryConfigurationParameters.TYPE_TEXT;
|
this.type = DiscoveryConfigurationParameters.TYPE_TEXT;
|
||||||
} else
|
} else
|
||||||
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_DATE)){
|
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_DATE))
|
||||||
|
{
|
||||||
this.type = DiscoveryConfigurationParameters.TYPE_DATE;
|
this.type = DiscoveryConfigurationParameters.TYPE_DATE;
|
||||||
|
} else
|
||||||
|
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL))
|
||||||
|
{
|
||||||
|
throw new DiscoveryConfigurationException("The " + type + " can't be used with a default side bar facet use the \"HierarchicalSidebarFacetConfiguration\" class instead.");
|
||||||
}else{
|
}else{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilterType(){
|
||||||
|
return FILTER_TYPE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An expanded class that allows a search filter to be used as a sidebar facet
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoverySearchFilterFacet extends DiscoverySearchFilter {
|
||||||
|
|
||||||
|
private static final int DEFAULT_FACET_LIMIT = 10;
|
||||||
|
private int facetLimit = -1;
|
||||||
|
private DiscoveryConfigurationParameters.SORT sortOrder = DiscoveryConfigurationParameters.SORT.COUNT;
|
||||||
|
public static final String FILTER_TYPE_FACET = "facet";
|
||||||
|
|
||||||
|
|
||||||
|
public int getFacetLimit()
|
||||||
|
{
|
||||||
|
if(facetLimit == -1){
|
||||||
|
return DEFAULT_FACET_LIMIT;
|
||||||
|
}else{
|
||||||
|
return facetLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFacetLimit(int facetLimit)
|
||||||
|
{
|
||||||
|
this.facetLimit = facetLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryConfigurationParameters.SORT getSortOrder()
|
||||||
|
{
|
||||||
|
return sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSortOrder(DiscoveryConfigurationParameters.SORT sortOrder)
|
||||||
|
{
|
||||||
|
this.sortOrder = sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilterType()
|
||||||
|
{
|
||||||
|
return FILTER_TYPE_FACET;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special sidebar facet configuration used for hierarchical facets
|
||||||
|
*
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class HierarchicalSidebarFacetConfiguration extends DiscoverySearchFilterFacet{
|
||||||
|
|
||||||
|
private String splitter;
|
||||||
|
private boolean skipFirstNodeLevel = true;
|
||||||
|
|
||||||
|
|
||||||
|
public HierarchicalSidebarFacetConfiguration() {
|
||||||
|
//Our default type is the hieracrhical, can be overridden by the configuration
|
||||||
|
this.type = DiscoveryConfigurationParameters.TYPE_HIERARCHICAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSplitter() {
|
||||||
|
return splitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setSplitter(String splitter) {
|
||||||
|
this.splitter = splitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSkipFirstNodeLevel() {
|
||||||
|
return skipFirstNodeLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkipFirstNodeLevel(boolean skipFirstNodeLevel) {
|
||||||
|
this.skipFirstNodeLevel = skipFirstNodeLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setType(String type) throws DiscoveryConfigurationException {
|
||||||
|
if(type.equalsIgnoreCase(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL)){
|
||||||
|
this.type = type;
|
||||||
|
}else{
|
||||||
|
throw new DiscoveryConfigurationException("The " + type + " can't be used with a hierarchical facet side bar facet use the \"DiscoverySearchFilterFacet\" class instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -9,6 +9,7 @@ package org.dspace.discovery;
|
|||||||
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +20,7 @@ import org.dspace.content.DSpaceObject;
|
|||||||
public class SolrServiceIndexOutputPlugin implements SolrServiceIndexPlugin{
|
public class SolrServiceIndexOutputPlugin implements SolrServiceIndexPlugin{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void additionalIndex(DSpaceObject dso, SolrInputDocument document) {
|
public void additionalIndex(Context context, DSpaceObject dso, SolrInputDocument document) {
|
||||||
System.out.println("Currently indexing: " + dso.getHandle());
|
System.out.println("Currently indexing: " + dso.getHandle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,13 +9,16 @@ package org.dspace.discovery;
|
|||||||
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
import org.dspace.content.DSpaceObject;
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indexing plugin used when indexing the communities/collections/items into DSpace
|
* Indexing plugin used when indexing the communities/collections/items into DSpace
|
||||||
*
|
*
|
||||||
* @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 Ben Bosman (ben at atmire dot com)
|
||||||
*/
|
*/
|
||||||
public interface SolrServiceIndexPlugin {
|
public interface SolrServiceIndexPlugin {
|
||||||
|
|
||||||
public void additionalIndex(DSpaceObject dso, SolrInputDocument document);
|
public void additionalIndex(Context context, DSpaceObject dso, SolrInputDocument document);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.LogManager;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restriction plugin that ensures that indexes all the resource policies.
|
||||||
|
* When a search is performed extra filter queries are added to retrieve only results to which the user has READ access
|
||||||
|
*
|
||||||
|
* @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 SolrServiceResourceRestrictionPlugin implements SolrServiceIndexPlugin, SolrServiceSearchPlugin{
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(SolrServiceResourceRestrictionPlugin.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void additionalIndex(Context context, DSpaceObject dso, SolrInputDocument document) {
|
||||||
|
try {
|
||||||
|
List<ResourcePolicy> policies = AuthorizeManager.getPoliciesActionFilter(context, dso, Constants.READ);
|
||||||
|
for (ResourcePolicy resourcePolicy : policies) {
|
||||||
|
String fieldValue;
|
||||||
|
if(resourcePolicy.getGroupID() != -1){
|
||||||
|
//We have a group add it to the value
|
||||||
|
fieldValue = "g" + resourcePolicy.getGroupID();
|
||||||
|
}else{
|
||||||
|
//We have an eperson add it to the value
|
||||||
|
fieldValue = "e" + resourcePolicy.getEPersonID();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addField("read", fieldValue);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(LogManager.getHeader(context, "Error while indexing resource policies", "DSpace object: (id " + dso.getID() + " type " + dso.getType() + ")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void additionalSearchParameters(Context context, DiscoverQuery discoveryQuery, SolrQuery solrQuery) {
|
||||||
|
StringBuilder resourceQuery = new StringBuilder();
|
||||||
|
//Always add the anonymous group id to the query
|
||||||
|
resourceQuery.append("read:(g0");
|
||||||
|
EPerson currentUser = context.getCurrentUser();
|
||||||
|
if(currentUser != null){
|
||||||
|
try {
|
||||||
|
resourceQuery.append(" OR e").append(currentUser.getID());
|
||||||
|
//Retrieve all the groups the current user is a member of !
|
||||||
|
Set<Integer> groupIds = Group.allMemberGroupIDs(context, currentUser);
|
||||||
|
for (Integer groupId : groupIds) {
|
||||||
|
resourceQuery.append(" OR g").append(groupId);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(LogManager.getHeader(context, "Error while adding resource policy information to query", "") ,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resourceQuery.append(")");
|
||||||
|
try {
|
||||||
|
if(AuthorizeManager.isAdmin(context)){
|
||||||
|
//Admins always have read access even if no policies are present !
|
||||||
|
resourceQuery.append(" OR (!read[* TO *])");
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(LogManager.getHeader(context, "Error while verifying if current user is admin !", ""), e);
|
||||||
|
}
|
||||||
|
solrQuery.addFilterQuery(resourceQuery.toString());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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.discovery;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin from which users can add additional search parameters for every search that occurs in discovery
|
||||||
|
*
|
||||||
|
* @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 interface SolrServiceSearchPlugin {
|
||||||
|
|
||||||
|
public void additionalSearchParameters(Context context, DiscoverQuery discoveryQuery, SolrQuery solrQuery);
|
||||||
|
}
|
@@ -11,8 +11,12 @@ 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.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.app.util.MetadataExposure;
|
||||||
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;
|
||||||
@@ -24,13 +28,14 @@ import org.dspace.authorize.AuthorizeException;
|
|||||||
import org.dspace.content.*;
|
import org.dspace.content.*;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.LogManager;
|
import org.dspace.core.LogManager;
|
||||||
import org.dspace.discovery.*;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||||
|
import org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration;
|
||||||
import org.dspace.discovery.configuration.DiscoverySortConfiguration;
|
import org.dspace.discovery.configuration.DiscoverySortConfiguration;
|
||||||
import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration;
|
import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration;
|
||||||
import org.dspace.handle.HandleManager;
|
import org.dspace.handle.HandleManager;
|
||||||
import org.dspace.sort.SortOption;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -54,22 +59,17 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
|
|
||||||
private static final Logger log = Logger.getLogger(AbstractSearch.class);
|
private static final Logger log = Logger.getLogger(AbstractSearch.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Language strings
|
* Language strings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final Message T_head1_community =
|
private static final Message T_head1_community =
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.head1_community");
|
message("xmlui.Discovery.AbstractSearch.head1_community");
|
||||||
|
|
||||||
private static final Message T_head1_collection =
|
private static final Message T_head1_collection =
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.head1_collection");
|
message("xmlui.Discovery.AbstractSearch.head1_collection");
|
||||||
|
|
||||||
private static final Message T_head1_none =
|
private static final Message T_head1_none =
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.head1_none");
|
message("xmlui.Discovery.AbstractSearch.head1_none");
|
||||||
|
|
||||||
private static final Message T_head2 =
|
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.head2");
|
|
||||||
|
|
||||||
private static final Message T_no_results =
|
private static final Message T_no_results =
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.no_results");
|
message("xmlui.ArtifactBrowser.AbstractSearch.no_results");
|
||||||
@@ -78,19 +78,13 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
message("xmlui.ArtifactBrowser.AbstractSearch.all_of_dspace");
|
message("xmlui.ArtifactBrowser.AbstractSearch.all_of_dspace");
|
||||||
|
|
||||||
private static final Message T_sort_by_relevance =
|
private static final Message T_sort_by_relevance =
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.sort_by.relevance");
|
message("xmlui.Discovery.AbstractSearch.sort_by.relevance");
|
||||||
|
|
||||||
private static final Message T_sort_by = message("xmlui.ArtifactBrowser.AbstractSearch.sort_by");
|
private static final Message T_sort_by = message("xmlui.Discovery.AbstractSearch.sort_by.head");
|
||||||
|
|
||||||
private static final Message T_order = message("xmlui.ArtifactBrowser.AbstractSearch.order");
|
private static final Message T_rpp = message("xmlui.Discovery.AbstractSearch.rpp");
|
||||||
private static final Message T_order_asc = message("xmlui.ArtifactBrowser.AbstractSearch.order.asc");
|
private static final Message T_result_head_3 = message("xmlui.Discovery.AbstractSearch.head3");
|
||||||
private static final Message T_order_desc = message("xmlui.ArtifactBrowser.AbstractSearch.order.desc");
|
private static final Message T_result_head_2 = message("xmlui.Discovery.AbstractSearch.head2");
|
||||||
|
|
||||||
private static final Message T_rpp = message("xmlui.ArtifactBrowser.AbstractSearch.rpp");
|
|
||||||
|
|
||||||
|
|
||||||
private static final Message T_sort_head = message("xmlui.Discovery.SimpleSearch.sort_head");
|
|
||||||
private static final Message T_sort_button = message("xmlui.Discovery.SimpleSearch.sort_apply");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached query results
|
* Cached query results
|
||||||
@@ -180,7 +174,7 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
List<DiscoverResult.FacetResult> facetValues = facetResults.get(facetField);
|
List<DiscoverResult.FacetResult> facetValues = facetResults.get(facetField);
|
||||||
for (DiscoverResult.FacetResult facetResult : facetValues)
|
for (DiscoverResult.FacetResult facetResult : facetValues)
|
||||||
{
|
{
|
||||||
validity.add(facetResult.getAsFilterQuery() + facetResult.getCount());
|
validity.add(facetField + facetResult.getAsFilterQuery() + facetResult.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +200,65 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
public abstract void addBody(Body body) throws SAXException, WingException,
|
public abstract void addBody(Body body) throws SAXException, WingException,
|
||||||
UIException, SQLException, IOException, AuthorizeException;
|
UIException, SQLException, IOException, AuthorizeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the main form that should be the only form that the user interface requires
|
||||||
|
* This form will be used for all discovery queries, filters, ....
|
||||||
|
* At the moment however this form is only used to track search result hits
|
||||||
|
* @param searchDiv the division to add the form to
|
||||||
|
*/
|
||||||
|
protected void buildMainForm(Division searchDiv) throws WingException, SQLException {
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
|
||||||
|
//We set our action to context path, since the eventual action will depend on which url we click on
|
||||||
|
Division mainForm = searchDiv.addInteractiveDivision("main-form", getBasicUrl(), Division.METHOD_POST, "");
|
||||||
|
|
||||||
|
String query = getQuery();
|
||||||
|
mainForm.addHidden("query").setValue(query);
|
||||||
|
|
||||||
|
Map<String, String[]> fqs = getParameterFilterQueries();
|
||||||
|
if (fqs != null)
|
||||||
|
{
|
||||||
|
for (String parameter : fqs.keySet())
|
||||||
|
{
|
||||||
|
String[] values = fqs.get(parameter);
|
||||||
|
if(values != null)
|
||||||
|
{
|
||||||
|
for (String value : values)
|
||||||
|
{
|
||||||
|
mainForm.addHidden(parameter).setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainForm.addHidden("rpp").setValue(getParameterRpp());
|
||||||
|
Hidden sort_by = mainForm.addHidden("sort_by");
|
||||||
|
if(!StringUtils.isBlank(request.getParameter("sort_by")))
|
||||||
|
{
|
||||||
|
sort_by.setValue(request.getParameter("sort_by"));
|
||||||
|
}else{
|
||||||
|
sort_by.setValue("score");
|
||||||
|
}
|
||||||
|
|
||||||
|
Hidden order = mainForm.addHidden("order");
|
||||||
|
if(getParameterOrder() != null)
|
||||||
|
{
|
||||||
|
order.setValue(request.getParameter("order"));
|
||||||
|
}else{
|
||||||
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
||||||
|
order.setValue(discoveryConfiguration.getSearchSortConfiguration().getDefaultSortOrder().toString());
|
||||||
|
}
|
||||||
|
if(!StringUtils.isBlank(request.getParameter("page")))
|
||||||
|
{
|
||||||
|
mainForm.addHidden("page").setValue(request.getParameter("page"));
|
||||||
|
}
|
||||||
|
//Optional redirect url !
|
||||||
|
mainForm.addHidden("redirectUrl");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getBasicUrl() throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach a division to the given search division named "search-results"
|
* Attach a division to the given search division named "search-results"
|
||||||
* which contains results for this search query.
|
* which contains results for this search query.
|
||||||
@@ -232,22 +285,36 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
Division results = search.addDivision("search-results", "primary");
|
Division results = search.addDivision("search-results", "primary");
|
||||||
|
buildSearchControls(results);
|
||||||
|
|
||||||
|
|
||||||
DSpaceObject searchScope = getScope();
|
DSpaceObject searchScope = getScope();
|
||||||
|
|
||||||
if (searchScope instanceof Community) {
|
int displayedResults;
|
||||||
Community community = (Community) searchScope;
|
long totalResults;
|
||||||
String communityName = community.getMetadata("name");
|
float searchTime;
|
||||||
results.setHead(T_head1_community.parameterize(communityName));
|
|
||||||
} else if (searchScope instanceof Collection) {
|
if(queryResults != null && 0 < queryResults.getTotalSearchResults())
|
||||||
Collection collection = (Collection) searchScope;
|
{
|
||||||
String collectionName = collection.getMetadata("name");
|
displayedResults = queryResults.getDspaceObjects().size();
|
||||||
results.setHead(T_head1_collection.parameterize(collectionName));
|
totalResults = queryResults.getTotalSearchResults();
|
||||||
} else {
|
searchTime = ((float) queryResults.getSearchTime() / 1000) % 60;
|
||||||
results.setHead(T_head1_none);
|
|
||||||
|
if (searchScope instanceof Community)
|
||||||
|
{
|
||||||
|
Community community = (Community) searchScope;
|
||||||
|
String communityName = community.getMetadata("name");
|
||||||
|
results.setHead(T_head1_community.parameterize(displayedResults, totalResults, communityName, searchTime));
|
||||||
|
} else if (searchScope instanceof Collection){
|
||||||
|
Collection collection = (Collection) searchScope;
|
||||||
|
String collectionName = collection.getMetadata("name");
|
||||||
|
results.setHead(T_head1_collection.parameterize(displayedResults, totalResults, collectionName, searchTime));
|
||||||
|
} else {
|
||||||
|
results.setHead(T_head1_none.parameterize(displayedResults, totalResults, searchTime));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryResults != null && 0< queryResults.getDspaceObjects().size())
|
if (queryResults != null && 0 < queryResults.getDspaceObjects().size())
|
||||||
{
|
{
|
||||||
|
|
||||||
// Pagination variables.
|
// Pagination variables.
|
||||||
@@ -262,12 +329,20 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
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);
|
||||||
//Check for facet queries ? If we have any add them
|
Map<String, String[]> filterQueryParams = getParameterFilterQueries();
|
||||||
String[] fqs = getParameterFilterQueries();
|
if(filterQueryParams != null)
|
||||||
if(fqs != null) {
|
{
|
||||||
StringBuilder maskBuilder = new StringBuilder(pageURLMask);
|
StringBuilder maskBuilder = new StringBuilder(pageURLMask);
|
||||||
for (String fq : fqs) {
|
for (String filterQueryParam : filterQueryParams.keySet())
|
||||||
maskBuilder.append("&fq=").append(fq);
|
{
|
||||||
|
String[] filterQueryValues = filterQueryParams.get(filterQueryParam);
|
||||||
|
if(filterQueryValues != null)
|
||||||
|
{
|
||||||
|
for (String filterQueryValue : filterQueryValues)
|
||||||
|
{
|
||||||
|
maskBuilder.append("&").append(filterQueryParam).append("=").append(filterQueryValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pageURLMask = maskBuilder.toString();
|
pageURLMask = maskBuilder.toString();
|
||||||
@@ -277,34 +352,62 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
lastItemIndex, currentPage, pagesTotal, pageURLMask);
|
lastItemIndex, currentPage, pagesTotal, pageURLMask);
|
||||||
|
|
||||||
// Look for any communities or collections in the mix
|
// Look for any communities or collections in the mix
|
||||||
ReferenceSet referenceSet = null;
|
org.dspace.app.xmlui.wing.element.List dspaceObjectsList = null;
|
||||||
|
|
||||||
|
// Put in palce top level search result list
|
||||||
|
dspaceObjectsList = results.addList("search-results-repository",
|
||||||
|
org.dspace.app.xmlui.wing.element.List.TYPE_DSO_LIST, "repository-search-results");
|
||||||
|
|
||||||
|
List<DSpaceObject> commCollList = new ArrayList<DSpaceObject>();
|
||||||
|
List<Item> itemList = new ArrayList<Item>();
|
||||||
for (DSpaceObject resultDso : queryResults.getDspaceObjects())
|
for (DSpaceObject resultDso : queryResults.getDspaceObjects())
|
||||||
{
|
{
|
||||||
if (resultDso instanceof Community || resultDso instanceof Collection) {
|
if(resultDso.getType() == Constants.COMMUNITY || resultDso.getType() == Constants.COLLECTION)
|
||||||
if (referenceSet == null) {
|
{
|
||||||
referenceSet = results.addReferenceSet("search-results-repository",
|
commCollList.add(resultDso);
|
||||||
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
}else
|
||||||
// Set a heading showing that we will be listing containers that matched:
|
if(resultDso.getType() == Constants.ITEM)
|
||||||
referenceSet.setHead(T_head2);
|
{
|
||||||
}
|
itemList.add((Item) resultDso);
|
||||||
if(resultDso != null){
|
}
|
||||||
referenceSet.addReference(resultDso);
|
}
|
||||||
|
|
||||||
|
if(CollectionUtils.isNotEmpty(commCollList))
|
||||||
|
{
|
||||||
|
org.dspace.app.xmlui.wing.element.List commCollWingList = dspaceObjectsList.addList("comm-coll-result-list");
|
||||||
|
commCollWingList.setHead(T_result_head_2);
|
||||||
|
for (DSpaceObject dso : commCollList)
|
||||||
|
{
|
||||||
|
DiscoverResult.DSpaceObjectHighlightResult highlightedResults = queryResults.getHighlightedResults(dso);
|
||||||
|
if(dso.getType() == Constants.COMMUNITY)
|
||||||
|
{
|
||||||
|
//Render our community !
|
||||||
|
org.dspace.app.xmlui.wing.element.List communityMetadata = commCollWingList.addList(dso.getHandle() + ":community");
|
||||||
|
|
||||||
|
renderCommunity((Community) dso, highlightedResults, communityMetadata);
|
||||||
|
}else
|
||||||
|
if(dso.getType() == Constants.COLLECTION)
|
||||||
|
{
|
||||||
|
//Render our collection !
|
||||||
|
org.dspace.app.xmlui.wing.element.List collectionMetadata = commCollWingList.addList(dso.getHandle() + ":collection");
|
||||||
|
|
||||||
|
renderCollection((Collection) dso, highlightedResults, collectionMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(CollectionUtils.isNotEmpty(itemList))
|
||||||
// Put in palce top level referenceset
|
|
||||||
referenceSet = results.addReferenceSet("search-results-repository",
|
|
||||||
ReferenceSet.TYPE_SUMMARY_LIST, null, "repository-search-results");
|
|
||||||
|
|
||||||
|
|
||||||
for (DSpaceObject resultDso : queryResults.getDspaceObjects())
|
|
||||||
{
|
{
|
||||||
if (resultDso instanceof Item)
|
org.dspace.app.xmlui.wing.element.List itemWingList = dspaceObjectsList.addList("item-result-list");
|
||||||
|
if(CollectionUtils.isNotEmpty(commCollList))
|
||||||
{
|
{
|
||||||
referenceSet.addReference(resultDso);
|
itemWingList.setHead(T_result_head_3);
|
||||||
|
|
||||||
|
}
|
||||||
|
for (Item resultDso : itemList)
|
||||||
|
{
|
||||||
|
DiscoverResult.DSpaceObjectHighlightResult highlightedResults = queryResults.getHighlightedResults(resultDso);
|
||||||
|
renderItem(itemWingList, resultDso, highlightedResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +417,239 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
//}// Empty query
|
//}// Empty query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the given item, all metadata is added to the given list, which metadata will be rendered where depends on the xsl
|
||||||
|
* @param dspaceObjectsList a list of DSpace objects
|
||||||
|
* @param item the DSpace item to be rendered
|
||||||
|
* @param highlightedResults the highlighted results
|
||||||
|
* @throws WingException
|
||||||
|
* @throws SQLException Database failure in services this calls
|
||||||
|
*/
|
||||||
|
protected void renderItem(org.dspace.app.xmlui.wing.element.List dspaceObjectsList, Item item, DiscoverResult.DSpaceObjectHighlightResult highlightedResults) throws WingException, SQLException {
|
||||||
|
org.dspace.app.xmlui.wing.element.List itemList = dspaceObjectsList.addList(item.getHandle() + ":item");
|
||||||
|
|
||||||
|
MetadataField[] metadataFields = MetadataField.findAll(context);
|
||||||
|
for (MetadataField metadataField : metadataFields)
|
||||||
|
{
|
||||||
|
//Retrieve the schema for this field
|
||||||
|
String schema = MetadataSchema.find(context, metadataField.getSchemaID()).getName();
|
||||||
|
//Check if our field isn't hidden
|
||||||
|
if (!MetadataExposure.isHidden(context, schema, metadataField.getElement(), metadataField.getQualifier()))
|
||||||
|
{
|
||||||
|
//Check if our metadata field is highlighted
|
||||||
|
StringBuilder metadataKey = new StringBuilder();
|
||||||
|
metadataKey.append(schema).append(".").append(metadataField.getElement());
|
||||||
|
if (metadataField.getQualifier() != null)
|
||||||
|
{
|
||||||
|
metadataKey.append(".").append(metadataField.getQualifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder itemName = new StringBuilder();
|
||||||
|
itemName.append(item.getHandle()).append(":").append(metadataKey.toString());
|
||||||
|
|
||||||
|
|
||||||
|
DCValue[] itemMetadata = item.getMetadata(schema, metadataField.getElement(), metadataField.getQualifier(), Item.ANY);
|
||||||
|
if(!ArrayUtils.isEmpty(itemMetadata))
|
||||||
|
{
|
||||||
|
org.dspace.app.xmlui.wing.element.List metadataFieldList = itemList.addList(itemName.toString());
|
||||||
|
for (DCValue metadataValue : itemMetadata)
|
||||||
|
{
|
||||||
|
String value = metadataValue.value;
|
||||||
|
addMetadataField(highlightedResults, metadataKey.toString(), metadataFieldList, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check our highlighted results, we may need to add non metadata (like our full text)
|
||||||
|
if(highlightedResults != null)
|
||||||
|
{
|
||||||
|
//Also add the full text snippet (if available !)
|
||||||
|
List<String> fullSnippets = highlightedResults.getHighlightResults("fulltext");
|
||||||
|
if(CollectionUtils.isNotEmpty(fullSnippets))
|
||||||
|
{
|
||||||
|
StringBuilder itemName = new StringBuilder();
|
||||||
|
itemName.append(item.getHandle()).append(":").append("fulltext");
|
||||||
|
|
||||||
|
org.dspace.app.xmlui.wing.element.List fullTextFieldList = itemList.addList(itemName.toString());
|
||||||
|
|
||||||
|
for (String snippet : fullSnippets)
|
||||||
|
{
|
||||||
|
addMetadataField(fullTextFieldList, snippet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the given collection, all collection metadata is added to the list
|
||||||
|
* @param collection the collection to be rendered
|
||||||
|
* @param highlightedResults the highlighted results
|
||||||
|
* @throws WingException
|
||||||
|
*/
|
||||||
|
protected void renderCollection(Collection collection, DiscoverResult.DSpaceObjectHighlightResult highlightedResults, org.dspace.app.xmlui.wing.element.List collectionMetadata) throws WingException {
|
||||||
|
|
||||||
|
String description = collection.getMetadata("introductory_text");
|
||||||
|
String description_abstract = collection.getMetadata("short_description");
|
||||||
|
String description_table = collection.getMetadata("side_bar_text");
|
||||||
|
String identifier_uri = "http://hdl.handle.net/" + collection.getHandle();
|
||||||
|
String provenance = collection.getMetadata("provenance_description");
|
||||||
|
String rights = collection.getMetadata("copyright_text");
|
||||||
|
String rights_license = collection.getMetadata("license");
|
||||||
|
String title = collection.getMetadata("name");
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(description))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description", collectionMetadata.addList(collection.getHandle() + ":dc.description"), description);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(description_abstract))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description.abstract", collectionMetadata.addList(collection.getHandle() + ":dc.description.abstract"), description_abstract);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(description_table))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description.tableofcontents", collectionMetadata.addList(collection.getHandle() + ":dc.description.tableofcontents"), description_table);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(identifier_uri))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.identifier.uri", collectionMetadata.addList(collection.getHandle() + ":dc.identifier.uri"), identifier_uri);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(provenance))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.provenance", collectionMetadata.addList(collection.getHandle() + ":dc.provenance"), provenance);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(rights))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.rights", collectionMetadata.addList(collection.getHandle() + ":dc.rights"), rights);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(rights_license))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.rights.license", collectionMetadata.addList(collection.getHandle() + ":dc.rights.license"), rights_license);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(title))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.title", collectionMetadata.addList(collection.getHandle() + ":dc.title"), title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the given collection, all collection metadata is added to the list
|
||||||
|
* @param community the community to be rendered
|
||||||
|
* @param highlightedResults the highlighted results
|
||||||
|
* @throws WingException
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected void renderCommunity(Community community, DiscoverResult.DSpaceObjectHighlightResult highlightedResults, org.dspace.app.xmlui.wing.element.List communityMetadata) throws WingException {
|
||||||
|
String description = community.getMetadata("introductory_text");
|
||||||
|
String description_abstract = community.getMetadata("short_description");
|
||||||
|
String description_table = community.getMetadata("side_bar_text");
|
||||||
|
String identifier_uri = "http://hdl.handle.net/" + community.getHandle();
|
||||||
|
String rights = community.getMetadata("copyright_text");
|
||||||
|
String title = community.getMetadata("name");
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(description))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description", communityMetadata.addList(community.getHandle() + ":dc.description"), description);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(description_abstract))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description.abstract", communityMetadata.addList(community.getHandle() + ":dc.description.abstract"), description_abstract);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(description_table))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.description.tableofcontents", communityMetadata.addList(community.getHandle() + ":dc.description.tableofcontents"), description_table);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(identifier_uri))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.identifier.uri", communityMetadata.addList(community.getHandle() + ":dc.identifier.uri"), identifier_uri);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(rights))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.rights", communityMetadata.addList(community.getHandle() + ":dc.rights"), rights);
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(title))
|
||||||
|
{
|
||||||
|
addMetadataField(highlightedResults, "dc.title", communityMetadata.addList(community.getHandle() + ":dc.title"), title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the current value to the wing list,
|
||||||
|
* @param highlightedResults the highlighted results
|
||||||
|
* @param metadataKey the metadata key {schema}.{element}.{qualifier}
|
||||||
|
* @param metadataFieldList the wing list we need to add the metadata value to
|
||||||
|
* @param value the metadata value
|
||||||
|
* @throws WingException
|
||||||
|
*/
|
||||||
|
protected void addMetadataField(DiscoverResult.DSpaceObjectHighlightResult highlightedResults, String metadataKey, org.dspace.app.xmlui.wing.element.List metadataFieldList, String value) throws WingException {
|
||||||
|
if(value == null){
|
||||||
|
//In the unlikely event that the value is null, do not attempt to render this
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(highlightedResults != null && highlightedResults.getHighlightResults(metadataKey) != null)
|
||||||
|
{
|
||||||
|
//Loop over all our highlighted results
|
||||||
|
for (String highlight : highlightedResults.getHighlightResults(metadataKey))
|
||||||
|
{
|
||||||
|
//If our non highlighted value matches our original one, ensure that the highlighted one is used
|
||||||
|
DiscoverHitHighlightingField highlightConfig = queryArgs.getHitHighlightingField(metadataKey);
|
||||||
|
//We might also have it configured for ALL !
|
||||||
|
if(highlightConfig == null)
|
||||||
|
{
|
||||||
|
highlightConfig = queryArgs.getHitHighlightingField("*");
|
||||||
|
}
|
||||||
|
switch (highlightConfig.getMaxChars())
|
||||||
|
{
|
||||||
|
case DiscoverHitHighlightingField.UNLIMITED_FRAGMENT_LENGTH:
|
||||||
|
//Exact match required
|
||||||
|
//\r is not indexed in solr & will cause issues
|
||||||
|
if(highlight.replaceAll("</?em>", "").equals(value.replace("\r", "")))
|
||||||
|
{
|
||||||
|
value = highlight;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//Partial match allowed, only render the highlighted part
|
||||||
|
if(value.contains(highlight.replaceAll("</?em>", "")))
|
||||||
|
{
|
||||||
|
value = highlight;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addMetadataField(metadataFieldList, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add our metadata value, this value will might contain the highlight ("<em></em>") tags, these will be removed & rendered as highlight wing fields.
|
||||||
|
* @param metadataFieldList the metadata list we need to add the value to
|
||||||
|
* @param value the metadata value to be rendered
|
||||||
|
* @throws WingException
|
||||||
|
*/
|
||||||
|
protected void addMetadataField(org.dspace.app.xmlui.wing.element.List metadataFieldList, String value) throws WingException {
|
||||||
|
//We need to put everything in <em> tags in a highlight !
|
||||||
|
org.dspace.app.xmlui.wing.element.Item metadataItem = metadataFieldList.addItem();
|
||||||
|
while(value.contains("<em>") && value.contains("</em>"))
|
||||||
|
{
|
||||||
|
if(0 < value.indexOf("<em>"))
|
||||||
|
{
|
||||||
|
//Add everything before the <em> !
|
||||||
|
metadataItem.addContent(value.substring(0, value.indexOf("<em>")));
|
||||||
|
}
|
||||||
|
metadataItem.addHighlight("highlight").addContent(StringUtils.substringBetween(value, "<em>", "</em>"));
|
||||||
|
|
||||||
|
value = StringUtils.substringAfter(value, "</em>");
|
||||||
|
|
||||||
|
}
|
||||||
|
if(0 < value.length())
|
||||||
|
{
|
||||||
|
metadataItem.addContent(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add options to the search scope field. This field determines in what
|
* Add options to the search scope field. This field determines in what
|
||||||
* communities or collections to search for the query.
|
* communities or collections to search for the query.
|
||||||
@@ -472,61 +808,15 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
queryArgs.setStart(0);
|
queryArgs.setStart(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(discoveryConfiguration.getHitHighlightingConfiguration() != null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Use mlt
|
|
||||||
// queryArgs.add("mlt", "true");
|
|
||||||
|
|
||||||
// The fields to use for similarity. NOTE: if possible, these should have a stored TermVector
|
|
||||||
// queryArgs.add("mlt.fl", "author");
|
|
||||||
|
|
||||||
// Minimum Term Frequency - the frequency below which terms will be ignored in the source doc.
|
|
||||||
// queryArgs.add("mlt.mintf", "1");
|
|
||||||
|
|
||||||
// Minimum Document Frequency - the frequency at which words will be ignored which do not occur in at least this many docs.
|
|
||||||
// queryArgs.add("mlt.mindf", "1");
|
|
||||||
|
|
||||||
//queryArgs.add("mlt.q", "");
|
|
||||||
|
|
||||||
// mlt.minwl
|
|
||||||
// minimum word length below which words will be ignored.
|
|
||||||
|
|
||||||
// mlt.maxwl
|
|
||||||
// maximum word length above which words will be ignored.
|
|
||||||
|
|
||||||
// mlt.maxqt
|
|
||||||
// maximum number of query terms that will be included in any generated query.
|
|
||||||
|
|
||||||
// mlt.maxntp
|
|
||||||
// maximum number of tokens to parse in each example doc field that is not stored with TermVector support.
|
|
||||||
|
|
||||||
// mlt.boost
|
|
||||||
// [true/false] set if the query will be boosted by the interesting term relevance.
|
|
||||||
|
|
||||||
// mlt.qf
|
|
||||||
// Query fields and their boosts using the same format as that used in DisMaxRequestHandler. These fields must also be specified in mlt.fl.
|
|
||||||
|
|
||||||
|
|
||||||
//filePost.addParameter("fl", "handle, "search.resourcetype")");
|
|
||||||
//filePost.addParameter("field", "search.resourcetype");
|
|
||||||
|
|
||||||
//Set the default limit to 11
|
|
||||||
/*
|
|
||||||
ClientUtils.escapeQueryChars(location)
|
|
||||||
//f.category.facet.limit=5
|
|
||||||
|
|
||||||
for(Enumeration en = request.getParameterNames(); en.hasMoreElements();)
|
|
||||||
{
|
{
|
||||||
String key = (String)en.nextElement();
|
List<DiscoveryHitHighlightFieldConfiguration> metadataFields = discoveryConfiguration.getHitHighlightingConfiguration().getMetadataFields();
|
||||||
if(key.endsWith(".facet.limit"))
|
for (DiscoveryHitHighlightFieldConfiguration fieldConfiguration : metadataFields)
|
||||||
{
|
{
|
||||||
filePost.addParameter(key, request.getParameter(key));
|
queryArgs.addHitHighlightingField(new DiscoverHitHighlightingField(fieldConfiguration.getField(), fieldConfiguration.getMaxSize(), fieldConfiguration.getSnippets()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
this.queryResults = SearchUtils.getSearchService().search(context, scope, queryArgs);
|
this.queryResults = SearchUtils.getSearchService().search(context, scope, queryArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,9 +826,12 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
* Returns a list of the filter queries for use in rendering pages, creating page more urls, ....
|
* Returns a list of the filter queries for use in rendering pages, creating page more urls, ....
|
||||||
* @return an array containing the filter queries
|
* @return an array containing the filter queries
|
||||||
*/
|
*/
|
||||||
protected String[] getParameterFilterQueries(){
|
protected Map<String, String[]> getParameterFilterQueries()
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
return ObjectModelHelper.getRequest(objectModel).getParameterValues("fq");
|
Map<String, String[]> result = new HashMap<String, String[]>();
|
||||||
|
result.put("fq", ObjectModelHelper.getRequest(objectModel).getParameterValues("fq"));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
@@ -659,89 +952,46 @@ public abstract class AbstractSearch extends AbstractDSpaceTransformer implement
|
|||||||
protected void buildSearchControls(Division div)
|
protected void buildSearchControls(Division div)
|
||||||
throws WingException, SQLException {
|
throws WingException, SQLException {
|
||||||
|
|
||||||
org.dspace.app.xmlui.wing.element.List controlsList = div.addList("search-controls", org.dspace.app.xmlui.wing.element.List.TYPE_FORM);
|
|
||||||
|
|
||||||
|
|
||||||
controlsList.setHead(T_sort_head);
|
|
||||||
//Table controlsTable = div.addTable("search-controls", 1, 4);
|
|
||||||
|
|
||||||
org.dspace.app.xmlui.wing.element.Item controlsItem = controlsList.addItem();
|
|
||||||
// Create a control for the number of records to display
|
|
||||||
controlsItem.addContent(T_rpp);
|
|
||||||
Select rppSelect = controlsItem.addSelect("rpp");
|
|
||||||
for (int i : RESULTS_PER_PAGE_PROGRESSION) {
|
|
||||||
rppSelect.addOption((i == getParameterRpp()), i, Integer.toString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cell groupCell = controlsRow.addCell();
|
|
||||||
try {
|
|
||||||
// Create a drop down of the different sort columns available
|
|
||||||
groupCell.addContent(T_group_by);
|
|
||||||
Select groupSelect = groupCell.addSelect("group_by");
|
|
||||||
groupSelect.addOption(false, "none", T_group_by_none);
|
|
||||||
|
|
||||||
|
|
||||||
String[] groups = {"publication_grp"};
|
|
||||||
for (String group : groups) {
|
|
||||||
groupSelect.addOption(group.equals(getParameterGroup()), group,
|
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.group_by." + group));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception se) {
|
|
||||||
throw new WingException("Unable to get group options", se);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Create a drop down of the different sort columns available
|
|
||||||
controlsItem.addContent(T_sort_by);
|
|
||||||
Select sortSelect = controlsItem.addSelect("sort_by");
|
|
||||||
sortSelect.addOption(false, "score", T_sort_by_relevance);
|
|
||||||
|
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
||||||
|
|
||||||
|
Division searchControlsGear = div.addDivision("masked-page-control").addDivision("search-controls-gear", "controls-gear-wrapper");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add sort by options, the gear will be rendered by a combination fo javascript & css
|
||||||
|
*/
|
||||||
|
String currentSort = getParameterSortBy();
|
||||||
|
org.dspace.app.xmlui.wing.element.List sortList = searchControlsGear.addList("sort-options", org.dspace.app.xmlui.wing.element.List.TYPE_SIMPLE, "gear-selection");
|
||||||
|
sortList.addItem("sort-head", "gear-head first").addContent(T_sort_by);
|
||||||
DiscoverySortConfiguration searchSortConfiguration = discoveryConfiguration.getSearchSortConfiguration();
|
DiscoverySortConfiguration searchSortConfiguration = discoveryConfiguration.getSearchSortConfiguration();
|
||||||
if(searchSortConfiguration != null){
|
|
||||||
for (DiscoverySortFieldConfiguration sortFieldConfiguration : searchSortConfiguration.getSortFields()) {
|
org.dspace.app.xmlui.wing.element.List sortOptions = sortList.addList("sort-selections");
|
||||||
|
boolean selected = ("score".equals(currentSort) || (currentSort == null && searchSortConfiguration.getDefaultSort() == null));
|
||||||
|
sortOptions.addItem("relevance", "gear-option" + (selected ? " gear-option-selected" : "")).addXref("sort_by=score&order=" + searchSortConfiguration.getDefaultSortOrder(), T_sort_by_relevance);
|
||||||
|
|
||||||
|
if(searchSortConfiguration.getSortFields() != null)
|
||||||
|
{
|
||||||
|
for (DiscoverySortFieldConfiguration sortFieldConfiguration : searchSortConfiguration.getSortFields())
|
||||||
|
{
|
||||||
String sortField = SearchUtils.getSearchService().toSortFieldIndex(sortFieldConfiguration.getMetadataField(), sortFieldConfiguration.getType());
|
String sortField = SearchUtils.getSearchService().toSortFieldIndex(sortFieldConfiguration.getMetadataField(), sortFieldConfiguration.getType());
|
||||||
|
|
||||||
String currentSort = getParameterSortBy();
|
boolean selectedAsc = ((sortField.equals(currentSort) && "asc".equals(getParameterOrder())) || (sortFieldConfiguration.equals(searchSortConfiguration.getDefaultSort())) && DiscoverySortConfiguration.SORT_ORDER.asc.equals(searchSortConfiguration.getDefaultSortOrder()));
|
||||||
sortSelect.addOption((sortField.equals(currentSort) || sortFieldConfiguration.equals(searchSortConfiguration.getDefaultSort())), sortField,
|
boolean selectedDesc= ((sortField.equals(currentSort) && "desc".equals(getParameterOrder())) || (sortFieldConfiguration.equals(searchSortConfiguration.getDefaultSort())) && DiscoverySortConfiguration.SORT_ORDER.desc.equals(searchSortConfiguration.getDefaultSortOrder()));
|
||||||
message("xmlui.ArtifactBrowser.AbstractSearch.sort_by." + sortField));
|
String sortFieldParam = "sort_by=" + sortField + "&order=";
|
||||||
|
sortOptions.addItem(sortField, "gear-option" + (selectedAsc ? " gear-option-selected" : "")).addXref(sortFieldParam + "asc", message("xmlui.Discovery.AbstractSearch.sort_by." + sortField + "_asc"));
|
||||||
|
sortOptions.addItem(sortField, "gear-option" + (selectedDesc ? " gear-option-selected" : "")).addXref(sortFieldParam + "desc", message("xmlui.Discovery.AbstractSearch.sort_by." + sortField + "_desc"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a control to changing ascending / descending order
|
//Add the rows per page
|
||||||
controlsItem.addContent(T_order);
|
sortList.addItem("rpp-head", "gear-head").addContent(T_rpp);
|
||||||
Select orderSelect = controlsItem.addSelect("order");
|
org.dspace.app.xmlui.wing.element.List rppOptions = sortList.addList("rpp-selections");
|
||||||
|
for (int i : RESULTS_PER_PAGE_PROGRESSION)
|
||||||
String parameterOrder = getParameterOrder();
|
{
|
||||||
if(parameterOrder == null && searchSortConfiguration != null) {
|
rppOptions.addItem("rpp-" + i, "gear-option" + (i == getParameterRpp() ? " gear-option-selected" : "")).addXref("rpp=" + i, Integer.toString(i));
|
||||||
parameterOrder = searchSortConfiguration.getDefaultSortOrder().toString();
|
|
||||||
}
|
}
|
||||||
orderSelect.addOption(SortOption.ASCENDING.equalsIgnoreCase(parameterOrder), SortOption.ASCENDING, T_order_asc);
|
|
||||||
orderSelect.addOption(SortOption.DESCENDING.equalsIgnoreCase(parameterOrder), SortOption.DESCENDING, T_order_desc);
|
|
||||||
|
|
||||||
controlsItem.addButton("submit_sort").setValue(T_sort_button);
|
|
||||||
|
|
||||||
// Create a control for the number of authors per item to display
|
|
||||||
// FIXME This is currently disabled, as the supporting functionality
|
|
||||||
// is not currently present in xmlui
|
|
||||||
//if (isItemBrowse(info))
|
|
||||||
//{
|
|
||||||
// controlsForm.addContent(T_etal);
|
|
||||||
// Select etalSelect = controlsForm.addSelect(BrowseParams.ETAL);
|
|
||||||
//
|
|
||||||
// etalSelect.addOption((info.getEtAl() < 0), 0, T_etal_all);
|
|
||||||
// etalSelect.addOption(1 == info.getEtAl(), 1, Integer.toString(1));
|
|
||||||
//
|
|
||||||
// for (int i = 5; i <= 50; i += 5)
|
|
||||||
// {
|
|
||||||
// etalSelect.addOption(i == info.getEtAl(), i, Integer.toString(i));
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.cocoon.environment.Request;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.discovery.SearchService;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||||
|
* @author Ben Bosman (ben at atmire dot com)
|
||||||
|
* @author Mark Diggory (markd at atmire dot com)
|
||||||
|
*/
|
||||||
|
public class DiscoveryUIUtils {
|
||||||
|
|
||||||
|
private static SearchService searchService = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
DSpace dspace = new DSpace();
|
||||||
|
searchService = dspace.getServiceManager().getServiceByName(SearchService.class.getName(),SearchService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of the filter queries for use in rendering pages, creating page more urls, ....
|
||||||
|
* @return an array containing the filter queries
|
||||||
|
*/
|
||||||
|
public static Map<String, String[]> getParameterFilterQueries(Request request) {
|
||||||
|
Map<String, String[]> fqs = new HashMap<String, String[]>();
|
||||||
|
|
||||||
|
List<String> filterTypes = getRepeatableParameters(request, "filtertype");
|
||||||
|
List<String> filterOperators = getRepeatableParameters(request, "filter_relational_operator");
|
||||||
|
List<String> filterValues = getRepeatableParameters(request, "filter");
|
||||||
|
|
||||||
|
for (int i = 0; i < filterTypes.size(); i++) {
|
||||||
|
String filterType = filterTypes.get(i);
|
||||||
|
String filterValue = filterValues.get(i);
|
||||||
|
String filterOperator = filterOperators.get(i);
|
||||||
|
|
||||||
|
fqs.put("filtertype_" + i, new String[]{filterType});
|
||||||
|
fqs.put("filter_relational_operator_" + i, new String[]{filterOperator});
|
||||||
|
fqs.put("filter_" + i, new String[]{filterValue});
|
||||||
|
}
|
||||||
|
return fqs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the filter queries for use by discovery
|
||||||
|
* @return an array containing the filter queries
|
||||||
|
*/
|
||||||
|
public static String[] getFilterQueries(Request request, Context context) {
|
||||||
|
try {
|
||||||
|
List<String> allFilterQueries = new ArrayList<String>();
|
||||||
|
List<String> filterTypes = getRepeatableParameters(request, "filtertype");
|
||||||
|
List<String> filterOperators = getRepeatableParameters(request, "filter_relational_operator");
|
||||||
|
List<String> filterValues = getRepeatableParameters(request, "filter");
|
||||||
|
|
||||||
|
for (int i = 0; i < filterTypes.size(); i++) {
|
||||||
|
String filterType = filterTypes.get(i);
|
||||||
|
String filterOperator = filterOperators.get(i);
|
||||||
|
String filterValue = filterValues.get(i);
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(filterValue)){
|
||||||
|
allFilterQueries.add(searchService.toFilterQuery(context, (filterType.equals("*") ? "" : filterType), filterOperator, filterValue).getFilterQuery());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allFilterQueries.toArray(new String[allFilterQueries.size()]);
|
||||||
|
}
|
||||||
|
catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getRepeatableParameters(Request request, String prefix){
|
||||||
|
TreeMap<String, String> result = new TreeMap<String, String>();
|
||||||
|
|
||||||
|
Enumeration parameterNames = request.getParameterNames();
|
||||||
|
while (parameterNames.hasMoreElements()) {
|
||||||
|
String parameter = (String) parameterNames.nextElement();
|
||||||
|
if(parameter.startsWith(prefix)){
|
||||||
|
result.put(parameter, request.getParameter(parameter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ArrayList<String>(result.values());
|
||||||
|
}
|
||||||
|
}
|
@@ -10,20 +10,18 @@ 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.commons.collections.CollectionUtils;
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
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.wing.Message;
|
||||||
import org.dspace.app.xmlui.wing.WingException;
|
import org.dspace.app.xmlui.wing.WingException;
|
||||||
import org.dspace.app.xmlui.wing.element.*;
|
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.discovery.DiscoverQuery;
|
|
||||||
import org.dspace.discovery.DiscoverResult;
|
|
||||||
import org.dspace.discovery.SearchUtils;
|
import org.dspace.discovery.SearchUtils;
|
||||||
|
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays related items to the currently viewable item
|
* Displays related items to the currently viewable item
|
||||||
@@ -34,23 +32,15 @@ import org.dspace.discovery.SearchServiceException;
|
|||||||
*/
|
*/
|
||||||
public class RelatedItems extends AbstractDSpaceTransformer
|
public class RelatedItems extends AbstractDSpaceTransformer
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Cached query results
|
private static final Message T_head = message("xmlui.Discovery.RelatedItems.head");
|
||||||
*/
|
private static final Message T_related_help = message("xmlui.Discovery.RelatedItems.help");
|
||||||
protected DiscoverResult queryResults;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached query arguments
|
* Display items related to the given item
|
||||||
*/
|
|
||||||
protected DiscoverQuery queryArgs;
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(RelatedItems.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a single item
|
|
||||||
*/
|
*/
|
||||||
public void addBody(Body body) throws SAXException, WingException,
|
public void addBody(Body body) throws SAXException, WingException,
|
||||||
UIException, SQLException, IOException, AuthorizeException
|
SQLException, IOException, AuthorizeException
|
||||||
{
|
{
|
||||||
|
|
||||||
DSpaceObject dspaceObject = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dspaceObject = HandleUtil.obtainHandle(objectModel);
|
||||||
@@ -59,109 +49,34 @@ public class RelatedItems extends AbstractDSpaceTransformer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Item item = (Item) dspaceObject;
|
Item item = (Item) dspaceObject;
|
||||||
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(item);
|
||||||
|
|
||||||
try {
|
if(discoveryConfiguration != null && discoveryConfiguration.getMoreLikeThisConfiguration() != null)
|
||||||
performSearch(item);
|
|
||||||
} catch (SearchServiceException e) {
|
|
||||||
log.error(e.getMessage(),e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the collection viewer division.
|
|
||||||
|
|
||||||
|
|
||||||
if (this.queryResults != null) {
|
|
||||||
// TODO: develop this !
|
|
||||||
/*
|
|
||||||
NamedList nList = this.queryResults.getResponse();
|
|
||||||
|
|
||||||
SimpleOrderedMap<SolrDocumentList> mlt = (SimpleOrderedMap<SolrDocumentList>)nList.get("moreLikeThis");
|
|
||||||
|
|
||||||
//home.addPara(nList.toString());
|
|
||||||
|
|
||||||
if(mlt != null && 0 < mlt.size())
|
|
||||||
{
|
|
||||||
//TODO: also make sure if an item is unresolved we do not end up with an empty referenceset !
|
|
||||||
List<DSpaceObject> dsos = new ArrayList<DSpaceObject>();
|
|
||||||
for(Map.Entry<String,SolrDocumentList> entry : mlt)
|
|
||||||
{
|
|
||||||
//org.dspace.app.xmlui.wing.element.List mltList = mltDiv.addList(key);
|
|
||||||
|
|
||||||
//mltList.setHead(key);
|
|
||||||
|
|
||||||
for(SolrDocument doc : entry.getValue())
|
|
||||||
{
|
|
||||||
try{
|
|
||||||
dsos.add(SearchUtils.findDSpaceObject(context, doc));
|
|
||||||
}catch(Exception e){
|
|
||||||
log.error(LogManager.getHeader(context, "Error while resolving related item doc to dso", "Main item: " + item.getID()));
|
|
||||||
}
|
|
||||||
//mltList.addItem().addContent(doc.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(0 < dsos.size()){
|
|
||||||
Division home = body.addDivision("test", "secondary related");
|
|
||||||
|
|
||||||
String name = "Related Items";
|
|
||||||
|
|
||||||
//if (name == null || name.length() == 0)
|
|
||||||
// home.setHead(T_untitled);
|
|
||||||
//else
|
|
||||||
home.setHead(name);
|
|
||||||
|
|
||||||
Division mltDiv = home.addDivision("item-related", "secondary related");
|
|
||||||
|
|
||||||
mltDiv.setHead("Items By Author:");
|
|
||||||
|
|
||||||
ReferenceSet set = mltDiv.addReferenceSet(
|
|
||||||
"item-related-items", ReferenceSet.TYPE_SUMMARY_LIST,
|
|
||||||
null, "related-items");
|
|
||||||
|
|
||||||
for (DSpaceObject dso : dsos) {
|
|
||||||
set.addReference(dso);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void performSearch(DSpaceObject dso) throws SearchServiceException {
|
|
||||||
|
|
||||||
if(queryResults != null)
|
|
||||||
{
|
{
|
||||||
return;
|
java.util.List<Item> relatedItems = SearchUtils.getSearchService().getRelatedItems(context, item, discoveryConfiguration.getMoreLikeThisConfiguration());
|
||||||
|
if(CollectionUtils.isNotEmpty(relatedItems))
|
||||||
|
{
|
||||||
|
Division mltDiv = body.addDivision("item-related-container").addDivision("item-related", "secondary related");
|
||||||
|
mltDiv.setHead(T_head);
|
||||||
|
|
||||||
|
mltDiv.addPara(T_related_help);
|
||||||
|
|
||||||
|
ReferenceSet set = mltDiv.addReferenceSet(
|
||||||
|
"item-related-items", ReferenceSet.TYPE_SUMMARY_LIST,
|
||||||
|
null, "related-items");
|
||||||
|
|
||||||
|
for (DSpaceObject dso : relatedItems)
|
||||||
|
{
|
||||||
|
set.addReference(dso);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
this.queryArgs = getQueryArgs(getView());
|
|
||||||
this.queryArgs.setMaxResults(1);
|
|
||||||
this.queryArgs.add("fl","author,handle");
|
|
||||||
this.queryArgs.add("mlt","true");
|
|
||||||
this.queryArgs.add("mlt.fl","author,handle");
|
|
||||||
this.queryArgs.add("mlt.mindf","1");
|
|
||||||
this.queryArgs.add("mlt.mintf","1");
|
|
||||||
this.queryArgs.setQuery("handle:" + dso.getHandle());
|
|
||||||
this.queryArgs.setRows(1);
|
|
||||||
*/
|
|
||||||
//queryResults = SearchUtils.getSearchService().search(context, queryArgs);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getView()
|
|
||||||
{
|
|
||||||
return "item";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recycle
|
* Recycle
|
||||||
*/
|
*/
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
this.queryArgs = null;
|
|
||||||
this.queryResults = null;
|
|
||||||
super.recycle();
|
super.recycle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,13 +27,10 @@ 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.core.Context;
|
|
||||||
import org.dspace.discovery.*;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||||
import org.dspace.discovery.configuration.SidebarFacetConfiguration;
|
|
||||||
import org.dspace.handle.HandleManager;
|
import org.dspace.handle.HandleManager;
|
||||||
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;
|
||||||
|
|
||||||
@@ -77,15 +74,12 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
private int DEFAULT_PAGE_SIZE = 10;
|
private int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
|
||||||
private ConfigurationService config = null;
|
|
||||||
|
|
||||||
private SearchService searchService = null;
|
private SearchService searchService = null;
|
||||||
private static final Message T_go = message("xmlui.general.go");
|
private static final Message T_go = message("xmlui.general.go");
|
||||||
|
|
||||||
public SearchFacetFilter() {
|
public SearchFacetFilter() {
|
||||||
|
|
||||||
DSpace dspace = new DSpace();
|
DSpace dspace = new DSpace();
|
||||||
config = dspace.getConfigurationService();
|
|
||||||
searchService = dspace.getServiceManager().getServiceByName(SearchService.class.getName(),SearchService.class);
|
searchService = dspace.getServiceManager().getServiceByName(SearchService.class.getName(),SearchService.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -146,7 +140,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
||||||
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
||||||
validity.add(facetValue.getAsFilterQuery() + facetValue.getCount());
|
validity.add(facetField + facetValue.getAsFilterQuery() + facetValue.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +185,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
queryArgs.setMaxResults(0);
|
queryArgs.setMaxResults(0);
|
||||||
|
|
||||||
queryArgs.addFilterQueries(getDiscoveryFilterQueries());
|
queryArgs.addFilterQueries(DiscoveryUIUtils.getFilterQueries(request, context));
|
||||||
|
|
||||||
|
|
||||||
//Set the default limit to 11
|
//Set the default limit to 11
|
||||||
@@ -317,11 +311,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
Table singleTable = results.addTable("browse-by-" + facetField + "-results", (int) (queryResults.getDspaceObjects().size() + 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 = Arrays.asList(DiscoveryUIUtils.getFilterQueries(request, context));
|
||||||
if(request.getParameterValues("fq") != null)
|
|
||||||
{
|
|
||||||
filterQueries = Arrays.asList(request.getParameterValues("fq"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int end = values.size();
|
int end = values.size();
|
||||||
@@ -341,7 +331,7 @@ 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, SQLException {
|
throws WingException, SQLException, UnsupportedEncodingException {
|
||||||
String action;
|
String action;
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
if(dso != null){
|
if(dso != null){
|
||||||
@@ -359,9 +349,14 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
for(Map.Entry<String, String> param : params.entrySet()){
|
for(Map.Entry<String, String> param : params.entrySet()){
|
||||||
jump.addHidden(param.getKey()).setValue(param.getValue());
|
jump.addHidden(param.getKey()).setValue(param.getValue());
|
||||||
}
|
}
|
||||||
String[] filterQueries = getParameterFilterQueries();
|
Map<String, String[]> filterQueries = DiscoveryUIUtils.getParameterFilterQueries(request);
|
||||||
for (String filterQuery : filterQueries) {
|
for (String parameter : filterQueries.keySet())
|
||||||
jump.addHidden("fq").setValue(filterQuery);
|
{
|
||||||
|
for (int i = 0; i < filterQueries.get(parameter).length; i++)
|
||||||
|
{
|
||||||
|
String value = filterQueries.get(parameter)[i];
|
||||||
|
jump.addHidden(parameter).setValue(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//We cannot create a filter for dates
|
//We cannot create a filter for dates
|
||||||
@@ -394,7 +389,6 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
|
|
||||||
private void renderFacetField(SearchFilterParam browseParams, DSpaceObject dso, String facetField, Table singleTable, List<String> filterQueries, DiscoverResult.FacetResult 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.getDisplayedValue();
|
String displayedValue = value.getDisplayedValue();
|
||||||
String filterQuery = value.getAsFilterQuery();
|
|
||||||
// if(field.getGap() != null){
|
// if(field.getGap() != null){
|
||||||
// //We have a date get the year so we can display it
|
// //We have a date get the year so we can display it
|
||||||
// DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
// DateFormat simpleDateformat = new SimpleDateFormat("yyyy");
|
||||||
@@ -405,7 +399,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
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(searchService.toFilterQuery(context, facetField, "equals", displayedValue).getFilterQuery())){
|
||||||
cell.addContent(displayedValue + " (" + value.getCount() + ")");
|
cell.addContent(displayedValue + " (" + value.getCount() + ")");
|
||||||
} else {
|
} else {
|
||||||
//Add the basics
|
//Add the basics
|
||||||
@@ -415,13 +409,15 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
//Add already existing filter queries
|
//Add already existing filter queries
|
||||||
url = addFilterQueriesToUrl(url);
|
url = addFilterQueriesToUrl(url);
|
||||||
//Last add the current filter query
|
//Last add the current filter query
|
||||||
url += "&fq=" + URLEncoder.encode(filterQuery, "UTF-8");
|
url += "&filtertype=" + facetField;
|
||||||
|
url += "&filter_relational_operator=equals";
|
||||||
|
url += "&filter=" + URLEncoder.encode(displayedValue, "UTF-8");
|
||||||
cell.addXref(url, displayedValue + " (" + value.getCount() + ")"
|
cell.addXref(url, displayedValue + " (" + value.getCount() + ")"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNextPageURL(SearchFilterParam browseParams, Request request) {
|
private String getNextPageURL(SearchFilterParam browseParams, Request request) throws UnsupportedEncodingException, UIException {
|
||||||
int offSet = Util.getIntParameter(request, SearchFilterParam.OFFSET);
|
int offSet = Util.getIntParameter(request, SearchFilterParam.OFFSET);
|
||||||
if (offSet == -1)
|
if (offSet == -1)
|
||||||
{
|
{
|
||||||
@@ -433,7 +429,6 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
parameters.putAll(browseParams.getControlParameters());
|
parameters.putAll(browseParams.getControlParameters());
|
||||||
parameters.put(SearchFilterParam.OFFSET, String.valueOf(offSet + DEFAULT_PAGE_SIZE));
|
parameters.put(SearchFilterParam.OFFSET, String.valueOf(offSet + DEFAULT_PAGE_SIZE));
|
||||||
|
|
||||||
//TODO: correct comm/collection url
|
|
||||||
// Add the filter queries
|
// Add the filter queries
|
||||||
String url = generateURL("search-filter", parameters);
|
String url = generateURL("search-filter", parameters);
|
||||||
url = addFilterQueriesToUrl(url);
|
url = addFilterQueriesToUrl(url);
|
||||||
@@ -441,7 +436,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPreviousPageURL(SearchFilterParam browseParams, Request request) {
|
private String getPreviousPageURL(SearchFilterParam browseParams, Request request) throws UnsupportedEncodingException, UIException {
|
||||||
//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 == queryArgs.getFacetOffset() && Util.getIntParameter(request, "offset") == -1)
|
if (0 == queryArgs.getFacetOffset() && Util.getIntParameter(request, "offset") == -1)
|
||||||
{
|
{
|
||||||
@@ -459,7 +454,6 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
parameters.putAll(browseParams.getControlParameters());
|
parameters.putAll(browseParams.getControlParameters());
|
||||||
parameters.put(SearchFilterParam.OFFSET, String.valueOf(offset - DEFAULT_PAGE_SIZE));
|
parameters.put(SearchFilterParam.OFFSET, String.valueOf(offset - DEFAULT_PAGE_SIZE));
|
||||||
|
|
||||||
//TODO: correct comm/collection url
|
|
||||||
// Add the filter queries
|
// Add the filter queries
|
||||||
String url = generateURL("search-filter", parameters);
|
String url = generateURL("search-filter", parameters);
|
||||||
url = addFilterQueriesToUrl(url);
|
url = addFilterQueriesToUrl(url);
|
||||||
@@ -477,74 +471,25 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
|||||||
super.recycle();
|
super.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String addFilterQueriesToUrl(String url){
|
public String addFilterQueriesToUrl(String url) throws UIException {
|
||||||
String[] fqs = getParameterFilterQueries();
|
Map<String, String[]> fqs = DiscoveryUIUtils.getParameterFilterQueries(ObjectModelHelper.getRequest(objectModel));
|
||||||
if (fqs != null) {
|
if (fqs != null)
|
||||||
|
{
|
||||||
StringBuilder urlBuilder = new StringBuilder(url);
|
StringBuilder urlBuilder = new StringBuilder(url);
|
||||||
for (String fq : fqs) {
|
for (String parameter : fqs.keySet())
|
||||||
urlBuilder.append("&fq=").append(fq);
|
{
|
||||||
|
for (int i = 0; i < fqs.get(parameter).length; i++)
|
||||||
|
{
|
||||||
|
String value = fqs.get(parameter)[i];
|
||||||
|
urlBuilder.append("&").append(parameter).append("=").append(encodeForURL(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return urlBuilder.toString();
|
return urlBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected String[] getParameterFilterQueries() {
|
|
||||||
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")));
|
|
||||||
}
|
|
||||||
|
|
||||||
//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
|
|
||||||
*/
|
|
||||||
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;
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ 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.commons.lang.StringUtils;
|
||||||
import org.apache.excalibur.source.SourceValidity;
|
import org.apache.excalibur.source.SourceValidity;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
@@ -28,14 +29,14 @@ import org.dspace.core.LogManager;
|
|||||||
import org.dspace.discovery.*;
|
import org.dspace.discovery.*;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||||
import org.dspace.discovery.configuration.SidebarFacetConfiguration;
|
import org.dspace.discovery.configuration.DiscoverySearchFilterFacet;
|
||||||
import org.dspace.handle.HandleManager;
|
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;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URLEncoder;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@@ -134,7 +135,7 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
|
|
||||||
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResults().get(facetField);
|
||||||
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
for (DiscoverResult.FacetResult facetValue : facetValues) {
|
||||||
val.add(facetValue.getAsFilterQuery() + facetValue.getCount());
|
val.add(facetField + facetValue.getAsFilterQuery() + facetValue.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,9 +152,9 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
|
|
||||||
public void performSearch() throws SearchServiceException, UIException, SQLException {
|
public void performSearch() throws SearchServiceException, UIException, SQLException {
|
||||||
DSpaceObject dso = getScope();
|
DSpaceObject dso = getScope();
|
||||||
queryArgs = getQueryArgs(context, dso, getAllFilterQueries());
|
|
||||||
//If we are on a search page performing a search a query may be used
|
|
||||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
queryArgs = getQueryArgs(context, dso, DiscoveryUIUtils.getFilterQueries(request, context));
|
||||||
|
//If we are on a search page performing a search a query may be used
|
||||||
String query = request.getParameter("query");
|
String query = request.getParameter("query");
|
||||||
if(query != null && !"".equals(query)){
|
if(query != null && !"".equals(query)){
|
||||||
queryArgs.setQuery(query);
|
queryArgs.setQuery(query);
|
||||||
@@ -179,22 +180,16 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
|
|
||||||
if (this.queryResults != null) {
|
if (this.queryResults != null) {
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
java.util.List<String> fqs = new ArrayList<String>();
|
java.util.List<String> fqs = Arrays.asList(DiscoveryUIUtils.getFilterQueries(request, context));
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
||||||
java.util.List<SidebarFacetConfiguration> facets = discoveryConfiguration.getSidebarFacets();
|
java.util.List<DiscoverySearchFilterFacet> facets = discoveryConfiguration.getSidebarFacets();
|
||||||
|
|
||||||
if (facets != null && 0 < facets.size()) {
|
if (facets != null && 0 < facets.size()) {
|
||||||
|
|
||||||
List browse = null;
|
List browse = null;
|
||||||
|
|
||||||
for (SidebarFacetConfiguration field : facets) {
|
for (DiscoverySearchFilterFacet field : facets) {
|
||||||
//Retrieve our values
|
//Retrieve our values
|
||||||
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResult(field.getIndexFieldName());
|
java.util.List<DiscoverResult.FacetResult> facetValues = queryResults.getFacetResult(field.getIndexFieldName());
|
||||||
//Check if we are dealing with a date, sometimes the facet values arrive as dates !
|
//Check if we are dealing with a date, sometimes the facet values arrive as dates !
|
||||||
@@ -224,6 +219,10 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
|
|
||||||
if (!iter.hasNext())
|
if (!iter.hasNext())
|
||||||
{
|
{
|
||||||
|
//When we have an hierarchical facet always show the view more they may want to filter the children of the top nodes
|
||||||
|
if(field.getType().equals(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL)){
|
||||||
|
addViewMoreUrl(filterValsList, dso, request, field.getIndexFieldName());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +232,7 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
String displayedValue = value.getDisplayedValue();
|
String displayedValue = value.getDisplayedValue();
|
||||||
String filterQuery = value.getAsFilterQuery();
|
String filterQuery = value.getAsFilterQuery();
|
||||||
|
|
||||||
if (fqs.contains(filterQuery)) {
|
if (fqs.contains(getSearchService().toFilterQuery(context, field.getIndexFieldName(), "equals", value.getDisplayedValue()).getFilterQuery())) {
|
||||||
filterValsList.addItem(Math.random() + "", "selected").addContent(displayedValue + " (" + value.getCount() + ")");
|
filterValsList.addItem(Math.random() + "", "selected").addContent(displayedValue + " (" + value.getCount() + ")");
|
||||||
} else {
|
} else {
|
||||||
String paramsQuery = retrieveParameters(request);
|
String paramsQuery = retrieveParameters(request);
|
||||||
@@ -243,15 +242,15 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
(dso == null ? "" : "/handle/" + dso.getHandle()) +
|
||||||
"/discover?" +
|
"/discover?" +
|
||||||
paramsQuery +
|
paramsQuery +
|
||||||
"fq=" +
|
"filtertype=" + field.getIndexFieldName() +
|
||||||
URLEncoder.encode(filterQuery, "UTF-8"),
|
"&filter_relational_operator=equals" +
|
||||||
|
"&filter=" + encodeForURL(filterQuery),
|
||||||
displayedValue + " (" + value.getCount() + ")"
|
displayedValue + " (" + value.getCount() + ")"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Show a view more url should there be more values, unless we have a date
|
//Show a view more url should there be more values, unless we have a date
|
||||||
if (i == shownFacets - 1 && !field.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)/*&& facetField.getGap() == null*/) {
|
if (i == shownFacets - 1 && !field.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)/*&& facetField.getGap() == null*/) {
|
||||||
|
|
||||||
addViewMoreUrl(filterValsList, dso, request, field.getIndexFieldName());
|
addViewMoreUrl(filterValsList, dso, request, field.getIndexFieldName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,26 +265,42 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
* @param request the cocoon request
|
* @param request the cocoon request
|
||||||
* @return the parameters used on this page
|
* @return the parameters used on this page
|
||||||
*/
|
*/
|
||||||
private String retrieveParameters(Request request) {
|
private String retrieveParameters(Request request) throws UnsupportedEncodingException, UIException {
|
||||||
StringBuffer result = new StringBuffer();
|
java.util.List<String> parameters = new ArrayList<String>();
|
||||||
Enumeration keys = request.getParameterNames();
|
if(StringUtils.isNotBlank(request.getParameter("query"))){
|
||||||
if(keys != null){
|
parameters.add("query=" + encodeForURL(request.getParameter("query")));
|
||||||
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();
|
|
||||||
|
if(StringUtils.isNotBlank(request.getParameter("scope"))){
|
||||||
|
parameters.add("scope=" + request.getParameter("scope"));
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(request.getParameter("sort_by"))){
|
||||||
|
parameters.add("sort_by=" + request.getParameter("sort_by"));
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(request.getParameter("order"))){
|
||||||
|
parameters.add("order=" + request.getParameter("order"));
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(request.getParameter("rpp"))){
|
||||||
|
parameters.add("rpp=" + request.getParameter("rpp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String[]> parameterFilterQueries = DiscoveryUIUtils.getParameterFilterQueries(request);
|
||||||
|
for(String parameter : parameterFilterQueries.keySet()){
|
||||||
|
for (int i = 0; i < parameterFilterQueries.get(parameter).length; i++) {
|
||||||
|
String value = parameterFilterQueries.get(parameter)[i];
|
||||||
|
parameters.add(parameter + "=" + encodeForURL(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Join all our parameters by using an "&" sign
|
||||||
|
String parametersString = StringUtils.join(parameters.toArray(new String[parameters.size()]), "&");
|
||||||
|
if(StringUtils.isNotEmpty(parametersString)){
|
||||||
|
parametersString += "&";
|
||||||
|
}
|
||||||
|
return parametersString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addViewMoreUrl(List facet, DSpaceObject dso, Request request, String fieldName) throws WingException {
|
private void addViewMoreUrl(List facet, DSpaceObject dso, Request request, String fieldName) throws WingException, UnsupportedEncodingException {
|
||||||
String parameters = retrieveParameters(request);
|
String parameters = retrieveParameters(request);
|
||||||
facet.addItem().addXref(
|
facet.addItem().addXref(
|
||||||
contextPath +
|
contextPath +
|
||||||
@@ -300,7 +315,7 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
DiscoverQuery queryArgs = new DiscoverQuery();
|
DiscoverQuery queryArgs = new DiscoverQuery();
|
||||||
|
|
||||||
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(scope);
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(scope);
|
||||||
java.util.List<SidebarFacetConfiguration> facets = discoveryConfiguration.getSidebarFacets();
|
java.util.List<DiscoverySearchFilterFacet> facets = discoveryConfiguration.getSidebarFacets();
|
||||||
|
|
||||||
log.info("facets for scope, " + scope + ": " + (facets != null ? facets.size() : null));
|
log.info("facets for scope, " + scope + ": " + (facets != null ? facets.size() : null));
|
||||||
|
|
||||||
@@ -317,7 +332,7 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
|
|
||||||
/** enable faceting of search results */
|
/** enable faceting of search results */
|
||||||
if (facets != null){
|
if (facets != null){
|
||||||
for (SidebarFacetConfiguration facet : facets) {
|
for (DiscoverySearchFilterFacet facet : facets) {
|
||||||
if(facet.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)){
|
if(facet.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)){
|
||||||
String dateFacet = facet.getIndexFieldName() + ".year";
|
String dateFacet = facet.getIndexFieldName() + ".year";
|
||||||
try{
|
try{
|
||||||
@@ -447,50 +462,13 @@ public class SidebarFacetsTransformer extends AbstractDSpaceTransformer implemen
|
|||||||
int facetLimit = facet.getFacetLimit();
|
int facetLimit = facet.getFacetLimit();
|
||||||
//Add one to our facet limit to make sure that if we have more then the shown facets that we show our show more url
|
//Add one to our facet limit to make sure that if we have more then the shown facets that we show our show more url
|
||||||
facetLimit++;
|
facetLimit++;
|
||||||
queryArgs.addFacetField(new DiscoverFacetField(facet.getIndexFieldName(), DiscoveryConfigurationParameters.TYPE_TEXT, facetLimit, facet.getSortOrder()));
|
queryArgs.addFacetField(new DiscoverFacetField(facet.getIndexFieldName(), facet.getType(), facetLimit, facet.getSortOrder()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return queryArgs;
|
return queryArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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("")){
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the current scope. This may be derived from the current url
|
* 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
|
* handle if present or the scope parameter is given. If no scope is
|
||||||
|
@@ -10,12 +10,11 @@ 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.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.cocoon.caching.CacheableProcessingComponent;
|
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.commons.lang.StringUtils;
|
||||||
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
|
||||||
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;
|
||||||
@@ -55,21 +54,24 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
message("xmlui.ArtifactBrowser.SimpleSearch.trail");
|
message("xmlui.ArtifactBrowser.SimpleSearch.trail");
|
||||||
|
|
||||||
private static final Message T_search_scope =
|
private static final Message T_search_scope =
|
||||||
message("xmlui.ArtifactBrowser.SimpleSearch.search_scope");
|
message("xmlui.Discovery.SimpleSearch.search_scope");
|
||||||
|
|
||||||
private static final Message T_head =
|
private static final Message T_head =
|
||||||
message("xmlui.ArtifactBrowser.SimpleSearch.head");
|
message("xmlui.ArtifactBrowser.SimpleSearch.head");
|
||||||
|
|
||||||
private static final Message T_search_label =
|
// private static final Message T_search_label =
|
||||||
message("xmlui.discovery.SimpleSearch.search_label");
|
// message("xmlui.discovery.SimpleSearch.search_label");
|
||||||
|
|
||||||
private static final Message T_go =
|
private static final Message T_go = message("xmlui.general.go");
|
||||||
message("xmlui.general.go");
|
|
||||||
private static final Message T_filter_label = message("xmlui.Discovery.SimpleSearch.filter_head");
|
private static final Message T_filter_label = message("xmlui.Discovery.SimpleSearch.filter_head");
|
||||||
private static final Message T_filter_help = message("xmlui.Discovery.SimpleSearch.filter_help");
|
private static final Message T_filter_help = message("xmlui.Discovery.SimpleSearch.filter_help");
|
||||||
private static final Message T_add_filter = message("xmlui.Discovery.SimpleSearch.filter_add");
|
private static final String T_filter_new_filters = "xmlui.Discovery.AbstractSearch.filters.controls.new-filters.head";
|
||||||
private static final Message T_filter_apply = message("xmlui.Discovery.SimpleSearch.filter_apply");
|
private static final Message T_filter_controls_apply = message("xmlui.Discovery.AbstractSearch.filters.controls.apply-filters");
|
||||||
private static final Message T_FILTERS_SELECTED = message("xmlui.ArtifactBrowser.SimpleSearch.filter.selected");
|
private static final Message T_filter_controls_add = message("xmlui.Discovery.AbstractSearch.filters.controls.add-filter");
|
||||||
|
private static final Message T_filter_controls_remove = message("xmlui.Discovery.AbstractSearch.filters.controls.remove-filter");
|
||||||
|
private static final Message T_filters_show = message("xmlui.Discovery.AbstractSearch.filters.display");
|
||||||
|
private static final Message T_filter_contain = message("xmlui.Discovery.SimpleSearch.filter.contains");
|
||||||
|
private static final Message T_filter_equals = message("xmlui.Discovery.SimpleSearch.filter.equals");
|
||||||
|
|
||||||
private SearchService searchService = null;
|
private SearchService searchService = null;
|
||||||
|
|
||||||
@@ -117,15 +119,18 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
}
|
}
|
||||||
search.addHidden("contextpath").setValue(contextPath);
|
search.addHidden("contextpath").setValue(contextPath);
|
||||||
|
|
||||||
String[] fqs = getFilterQueries();
|
Map<String, String[]> fqs = getParameterFilterQueries();
|
||||||
|
|
||||||
Division mainSearchDiv = search.addInteractiveDivision("general-query",
|
Division searchBoxDivision = search.addDivision("discovery-search-box", "discoverySearchBox");
|
||||||
"discover", Division.METHOD_GET, "discover-search-box search");
|
|
||||||
|
Division mainSearchDiv = searchBoxDivision.addInteractiveDivision("general-query",
|
||||||
|
"discover", Division.METHOD_GET, "discover-search-box");
|
||||||
|
|
||||||
List searchList = mainSearchDiv.addList("primary-search", List.TYPE_FORM);
|
List searchList = mainSearchDiv.addList("primary-search", List.TYPE_FORM);
|
||||||
|
|
||||||
searchList.setHead(T_search_label);
|
// searchList.setHead(T_search_label);
|
||||||
if (variableScope()) {
|
if (variableScope())
|
||||||
|
{
|
||||||
Select scope = searchList.addItem().addSelect("scope");
|
Select scope = searchList.addItem().addSelect("scope");
|
||||||
scope.setLabel(T_search_scope);
|
scope.setLabel(T_search_scope);
|
||||||
buildScopeList(scope);
|
buildScopeList(scope);
|
||||||
@@ -134,106 +139,74 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
Item searchBoxItem = searchList.addItem();
|
Item searchBoxItem = searchList.addItem();
|
||||||
Text text = searchBoxItem.addText("query");
|
Text text = searchBoxItem.addText("query");
|
||||||
text.setValue(queryString);
|
text.setValue(queryString);
|
||||||
text.setSize(75);
|
searchBoxItem.addButton("submit", "search-icon").setValue(T_go);
|
||||||
searchBoxItem.addButton("submit").setValue(T_go);
|
|
||||||
addHiddenFormFields("search", request, fqs, mainSearchDiv);
|
|
||||||
|
|
||||||
|
|
||||||
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(dso);
|
||||||
java.util.List<DiscoverySearchFilter> filterFields = discoveryConfiguration.getSearchFilters();
|
java.util.List<DiscoverySearchFilter> filterFields = discoveryConfiguration.getSearchFilters();
|
||||||
if(0 < fqs.length || 0 < filterFields.size()){
|
java.util.List<String> filterTypes = DiscoveryUIUtils.getRepeatableParameters(request, "filtertype");
|
||||||
Division searchFiltersDiv = search.addInteractiveDivision("search-filters",
|
java.util.List<String> filterOperators = DiscoveryUIUtils.getRepeatableParameters(request, "filter_relational_operator");
|
||||||
"discover", Division.METHOD_GET, "discover-search-box search");
|
java.util.List<String> filterValues = DiscoveryUIUtils.getRepeatableParameters(request, "filter");
|
||||||
|
|
||||||
List secondarySearchList = searchFiltersDiv.addList("secondary-search", List.TYPE_FORM);
|
if(0 < filterFields.size() && filterTypes.size() == 0)
|
||||||
secondarySearchList.setHead(T_filter_label);
|
{
|
||||||
|
//Display the add filters url ONLY if we have no filters selected & fitlers can be added
|
||||||
|
searchList.addItem().addXref("display-filters", T_filters_show);
|
||||||
|
}
|
||||||
|
addHiddenFormFields("search", request, fqs, mainSearchDiv);
|
||||||
|
|
||||||
|
|
||||||
|
if(0 < filterFields.size())
|
||||||
|
{
|
||||||
|
Division searchFiltersDiv = searchBoxDivision.addInteractiveDivision("search-filters",
|
||||||
|
"discover", Division.METHOD_GET, "discover-filters-box " + (0 < filterTypes.size() ? "" : "hidden"));
|
||||||
|
|
||||||
|
Division filtersWrapper = searchFiltersDiv.addDivision("discovery-filters-wrapper");
|
||||||
|
filtersWrapper.setHead(T_filter_label);
|
||||||
|
filtersWrapper.addPara(T_filter_help);
|
||||||
|
Table filtersTable = filtersWrapper.addTable("discovery-filters", 1, 4, "discovery-filters");
|
||||||
|
|
||||||
|
|
||||||
// queryList.addItem().addContent("Filters");
|
|
||||||
//If we have any filters, show them
|
//If we have any filters, show them
|
||||||
if(fqs.length > 0){
|
if(filterTypes.size() > 0)
|
||||||
//if(filters != null && filters.size() > 0){
|
{
|
||||||
Item item = secondarySearchList.addItem("used-filters", "used-filters-list");
|
|
||||||
|
|
||||||
|
for (int i = 0; i < filterTypes.size(); i++)
|
||||||
|
{
|
||||||
|
String filterType = filterTypes.get(i);
|
||||||
|
String filterValue = filterValues.get(i);
|
||||||
|
String filterOperator = filterOperators.get(i);
|
||||||
|
|
||||||
// Composite composite = item.addComposite("facet-controls");
|
if(StringUtils.isNotBlank(filterValue))
|
||||||
|
{
|
||||||
// composite.setLabel(T_FILTERS_SELECTED);
|
Row row = filtersTable.addRow("used-filters-" + i, Row.ROLE_DATA, "search-filter used-filter");
|
||||||
|
addFilterRow(filterFields, i, row, filterType, filterOperator, filterValue);
|
||||||
|
|
||||||
for (int i = 0; i < fqs.length; i++) {
|
|
||||||
String filterQuery = fqs[i];
|
|
||||||
DiscoverFilterQuery fq = searchService.toFilterQuery(context, filterQuery);
|
|
||||||
|
|
||||||
// CheckBox box = item.addCheckBox("fq");
|
|
||||||
CheckBox box = item.addCheckBox("fq");
|
|
||||||
if(i == 0){
|
|
||||||
box.setLabel(T_FILTERS_SELECTED);
|
|
||||||
}
|
}
|
||||||
Option option = box.addOption(true, fq.getFilterQuery());
|
|
||||||
String field = fq.getField();
|
|
||||||
option.addContent(message("xmlui.ArtifactBrowser.SimpleSearch.filter." + field));
|
|
||||||
|
|
||||||
//We have a filter query get the display value
|
|
||||||
//Check for a range query
|
|
||||||
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
|
||||||
Matcher matcher = pattern.matcher(fq.getDisplayedValue());
|
|
||||||
boolean hasPattern = matcher.find();
|
|
||||||
if (hasPattern) {
|
|
||||||
String[] years = matcher.group(0).replace("[", "").replace("]", "").split(" TO ");
|
|
||||||
option.addContent(": " + years[0] + " - " + years[1]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
option.addContent(": " + fq.getDisplayedValue());
|
|
||||||
}
|
}
|
||||||
secondarySearchList.addItem().addButton("submit_update_filters", "update-filters").setValue(T_filter_apply);
|
filtersTable.addRow(Row.ROLE_HEADER).addCell("", Cell.ROLE_HEADER, 1, 4, "new-filter-header").addContent(message(T_filter_new_filters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int index = filterTypes.size() + 1;
|
||||||
|
Row row = filtersTable.addRow("filter-new-" + index, Row.ROLE_DATA, "search-filter");
|
||||||
|
|
||||||
if(0 < filterFields.size()){
|
addFilterRow(filterFields, index, row, null, null, null);
|
||||||
//We have at least one filter so add our filter box
|
|
||||||
Item item = secondarySearchList.addItem("search-filter-list", "search-filter-list");
|
|
||||||
Composite filterComp = item.addComposite("search-filter-controls");
|
|
||||||
filterComp.setLabel(T_add_filter);
|
|
||||||
filterComp.setHelp(T_filter_help);
|
|
||||||
|
|
||||||
// filterComp.setLabel("");
|
Row filterControlsItem = filtersTable.addRow("filter-controls", Row.ROLE_DATA, "apply-filter");
|
||||||
|
filterControlsItem.addCell(1, 3).addContent("");
|
||||||
Select select = filterComp.addSelect("filtertype");
|
filterControlsItem.addCell().addButton("submit_apply_filter", "discovery-apply-filter-button").setValue(T_filter_controls_apply);
|
||||||
|
|
||||||
//For each field found (at least one) add options
|
|
||||||
for (DiscoverySearchFilter searchFilter : filterFields) {
|
|
||||||
select.addOption(searchFilter.getIndexFieldName(), message("xmlui.ArtifactBrowser.SimpleSearch.filter." + searchFilter.getIndexFieldName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add a box so we can search for our value
|
|
||||||
filterComp.addText("filter").setSize(30);
|
|
||||||
|
|
||||||
//And last add an add button
|
|
||||||
filterComp.enableAddOperation();
|
|
||||||
}
|
|
||||||
|
|
||||||
addHiddenFormFields("filter", request, fqs, searchFiltersDiv);
|
addHiddenFormFields("filter", request, fqs, searchFiltersDiv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Division searchControlsDiv = search.addInteractiveDivision("search-controls",
|
|
||||||
"discover", Division.METHOD_GET, "discover-sort-box search");
|
|
||||||
|
|
||||||
buildSearchControls(searchControlsDiv);
|
|
||||||
addHiddenFormFields("sort", request, fqs, searchControlsDiv);
|
|
||||||
|
|
||||||
|
|
||||||
// query.addPara(null, "button-list").addButton("submit").setValue(T_go);
|
// query.addPara(null, "button-list").addButton("submit").setValue(T_go);
|
||||||
|
|
||||||
// Build the DRI Body
|
// Build the DRI Body
|
||||||
//Division results = body.addDivision("results", "primary");
|
//Division results = body.addDivision("results", "primary");
|
||||||
//results.setHead(T_head);
|
//results.setHead(T_head);
|
||||||
|
buildMainForm(search);
|
||||||
|
|
||||||
// Add the result division
|
// Add the result division
|
||||||
try {
|
try {
|
||||||
@@ -244,61 +217,49 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected void addFilterRow(java.util.List<DiscoverySearchFilter> filterFields, int index, Row row, String selectedFilterType, String relationalOperator, String value) throws WingException {
|
||||||
* Returns a list of the filter queries for use in rendering pages, creating page more urls, ....
|
Select select = row.addCell("", Cell.ROLE_DATA, "selection").addSelect("filtertype_" + index);
|
||||||
* @return an array containing the filter queries
|
|
||||||
*/
|
|
||||||
protected String[] getParameterFilterQueries() {
|
|
||||||
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")));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Have we added a filter using the UI
|
//For each field found (at least one) add options
|
||||||
if(request.getParameter("filter") != null && !"".equals(request.getParameter("filter")))
|
for (DiscoverySearchFilter searchFilter : filterFields)
|
||||||
{
|
{
|
||||||
fqs.add((request.getParameter("filtertype")) + ":" + request.getParameter("filter"));
|
select.addOption(StringUtils.equals(searchFilter.getIndexFieldName(), selectedFilterType), searchFilter.getIndexFieldName(), message("xmlui.ArtifactBrowser.SimpleSearch.filter." + searchFilter.getIndexFieldName()));
|
||||||
}
|
}
|
||||||
return fqs.toArray(new String[fqs.size()]);
|
Select typeSelect = row.addCell("", Cell.ROLE_DATA, "selection").addSelect("filter_relational_operator_" + index);
|
||||||
|
typeSelect.addOption(StringUtils.equals(relationalOperator, "contains"), "contains", T_filter_contain);
|
||||||
|
typeSelect.addOption(StringUtils.equals(relationalOperator, "equals"), "equals", T_filter_equals);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Add a box so we can search for our value
|
||||||
|
row.addCell("", Cell.ROLE_DATA, "discovery-filter-input-cell").addText("filter_" + index, "discovery-filter-input").setValue(value == null ? "" : value);
|
||||||
|
|
||||||
|
//And last add an add button
|
||||||
|
Cell buttonsCell = row.addCell("filter-controls_" + index, Cell.ROLE_DATA, "filter-controls");
|
||||||
|
buttonsCell.addButton("add-filter_" + index, "filter-control filter-add").setValue(T_filter_controls_add);
|
||||||
|
buttonsCell.addButton("remove-filter_" + index, "filter-control filter-remove").setValue(T_filter_controls_remove);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getBasicUrl() throws SQLException {
|
||||||
|
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||||
|
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
|
||||||
|
|
||||||
|
return request.getContextPath() + (dso == null ? "" : "/handle/" + dso.getHandle()) + "/discover";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, String[]> getParameterFilterQueries(){
|
||||||
|
return DiscoveryUIUtils.getParameterFilterQueries(ObjectModelHelper.getRequest(objectModel));
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns all the filter queries for use by discovery
|
* 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[] getFilterQueries() {
|
protected String[] getFilterQueries() {
|
||||||
try {
|
return DiscoveryUIUtils.getFilterQueries(ObjectModelHelper.getRequest(objectModel), context);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -375,7 +336,7 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
* @param division the division that requires the hidden fields
|
* @param division the division that requires the hidden fields
|
||||||
* @throws WingException will never occur
|
* @throws WingException will never occur
|
||||||
*/
|
*/
|
||||||
private void addHiddenFormFields(String type, Request request, String[] fqs, Division division) throws WingException {
|
private void addHiddenFormFields(String type, Request request, Map<String, String[]> fqs, Division division) throws WingException {
|
||||||
if(type.equals("filter") || type.equals("sort")){
|
if(type.equals("filter") || type.equals("sort")){
|
||||||
if(request.getParameter("query") != null){
|
if(request.getParameter("query") != null){
|
||||||
division.addHidden("query").setValue(request.getParameter("query"));
|
division.addHidden("query").setValue(request.getParameter("query"));
|
||||||
@@ -386,9 +347,14 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Add the filter queries, current search settings so these remain saved when performing a new search !
|
//Add the filter queries, current search settings so these remain saved when performing a new search !
|
||||||
if(type.equals("search") || type.equals("sort")){
|
if(type.equals("search") || type.equals("sort"))
|
||||||
for (String fq : fqs) {
|
{
|
||||||
division.addHidden("fq").setValue(fq);
|
for (String parameter : fqs.keySet())
|
||||||
|
{
|
||||||
|
String[] values = fqs.get(parameter);
|
||||||
|
for (String value : values) {
|
||||||
|
division.addHidden(parameter).setValue(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,7 +26,6 @@ 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;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -118,7 +117,7 @@ public class JSONDiscoverySearcher extends AbstractReader implements Recyclable
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Context context = ContextUtil.obtainContext(objectModel);
|
Context context = ContextUtil.obtainContext(objectModel);
|
||||||
JSONStream = getSearchService().searchJSON(queryArgs, getScope(context, objectModel), jsonWrf);
|
JSONStream = getSearchService().searchJSON(context, queryArgs, getScope(context, objectModel), jsonWrf);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error while retrieving JSON string for Discovery auto complete", e);
|
log.error("Error while retrieving JSON string for Discovery auto complete", e);
|
||||||
}
|
}
|
||||||
|
@@ -85,7 +85,6 @@
|
|||||||
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.title">Title</message>
|
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.title">Title</message>
|
||||||
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.subject">Subject</message>
|
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.subject">Subject</message>
|
||||||
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.dateIssued">Date issued</message>
|
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.dateIssued">Date issued</message>
|
||||||
<message key="xmlui.ArtifactBrowser.SimpleSearch.filter.selected">Selected filters</message>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -102,9 +101,23 @@
|
|||||||
|
|
||||||
<message key="xmlui.Discovery.AbstractSearch.startswith">Starts with</message>
|
<message key="xmlui.Discovery.AbstractSearch.startswith">Starts with</message>
|
||||||
<message key="xmlui.Discovery.AbstractSearch.startswith.help">Or enter first few letters:</message>
|
<message key="xmlui.Discovery.AbstractSearch.startswith.help">Or enter first few letters:</message>
|
||||||
|
|
||||||
<message key="xmlui.ArtifactBrowser.AbstractSearch.sort_by.dc.title_sort">Title</message>
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.head">Sort Options:</message>
|
||||||
<message key="xmlui.ArtifactBrowser.AbstractSearch.sort_by.dc.date.issued_dt">Issue Date</message>
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.relevance">Relevance</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.dc.title_sort_desc">Title Desc</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.dc.date.issued_dt_desc">Issue Date Desc</message>
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.dc.title_sort_asc">Title Asc</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.sort_by.dc.date.issued_dt_asc">Issue Date Asc</message>
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.rpp">Results Per Page:</message>
|
||||||
|
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.filters.controls.add-filter">Add Filter</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.filters.controls.apply-filters">Apply</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.filters.controls.remove-filter">Remove</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.filters.controls.new-filters.head">New Filters:</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.filters.display">Add filters</message>
|
||||||
|
|
||||||
<message key="xmlui.discovery.SearchFacetFilter.no-results">No filter values found</message>
|
<message key="xmlui.discovery.SearchFacetFilter.no-results">No filter values found</message>
|
||||||
|
|
||||||
@@ -112,13 +125,22 @@
|
|||||||
<message key="xmlui.discovery.AbstractFiltersTransformer.filters.view-more">... View More</message>
|
<message key="xmlui.discovery.AbstractFiltersTransformer.filters.view-more">... View More</message>
|
||||||
|
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.SimpleSearch.search_scope">Search</message>
|
||||||
<message key="xmlui.discovery.SimpleSearch.search_label">Search</message>
|
<message key="xmlui.discovery.SimpleSearch.search_label">Search</message>
|
||||||
<message key="xmlui.Discovery.SimpleSearch.filter_head">Filters</message>
|
<message key="xmlui.Discovery.SimpleSearch.filter_head">Filters</message>
|
||||||
<message key="xmlui.Discovery.SimpleSearch.filter_add">Add Filters</message>
|
|
||||||
<message key="xmlui.Discovery.SimpleSearch.filter_help">Use filters to refine the search results.</message>
|
<message key="xmlui.Discovery.SimpleSearch.filter_help">Use filters to refine the search results.</message>
|
||||||
<message key="xmlui.Discovery.SimpleSearch.filter_apply">Update filters</message>
|
|
||||||
|
|
||||||
<message key="xmlui.Discovery.SimpleSearch.sort_head">Sort options</message>
|
<message key="xmlui.Discovery.SimpleSearch.filter.contains">Contains</message>
|
||||||
<message key="xmlui.Discovery.SimpleSearch.sort_apply">Apply</message>
|
<message key="xmlui.Discovery.SimpleSearch.filter.equals">Equals</message>
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.RelatedItems.head">Related items</message>
|
||||||
|
<message key="xmlui.Discovery.RelatedItems.help">Showing items related by title, author, creator and subject.</message>
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.head1_community">Showing {0} out of a total of {1} results for community: {2}. <span class="searchTime">({3} seconds)</span></message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.head1_collection">Showing {0} out of a total of {1} results for collection: {2}. <span class="searchTime">({3} seconds)</span></message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.head1_none">Showing {0} out of a total of {1} results. <span class="searchTime">({2} seconds)</span></message>
|
||||||
|
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.head2">Communities or Collections matching your query</message>
|
||||||
|
<message key="xmlui.Discovery.AbstractSearch.head3">Items matching your query</message>
|
||||||
|
|
||||||
</catalogue>
|
</catalogue>
|
||||||
|
@@ -1,214 +1,196 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
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 available online at
|
||||||
|
|
||||||
http://www.dspace.org/license/
|
http://www.dspace.org/license/
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
The ArtifactBrowser Aspect is responsible for browsing communities /
|
The ArtifactBrowser Aspect is responsible for browsing communities /
|
||||||
collections / items / and bitstreams, viewing an individual item,
|
collections / items / and bitstreams, viewing an individual item,
|
||||||
and searching the repository.
|
and searching the repository.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
|
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
|
||||||
<map:components>
|
<map:components>
|
||||||
|
|
||||||
|
|
||||||
<map:transformers>
|
<map:transformers>
|
||||||
|
|
||||||
<map:transformer name="Navigation" src="org.dspace.app.xmlui.aspect.discovery.Navigation"/>
|
<map:transformer name="Navigation" src="org.dspace.app.xmlui.aspect.discovery.Navigation"/>
|
||||||
<map:transformer name="SimpleSearch" src="org.dspace.app.xmlui.aspect.discovery.SimpleSearch"/>
|
<map:transformer name="SimpleSearch" src="org.dspace.app.xmlui.aspect.discovery.SimpleSearch"/>
|
||||||
<map:transformer name="BrowseFacet" src="org.dspace.app.xmlui.aspect.discovery.BrowseFacet"/>
|
<map:transformer name="BrowseFacet" src="org.dspace.app.xmlui.aspect.discovery.BrowseFacet"/>
|
||||||
<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="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"/>
|
||||||
<map:transformer name="CommunityRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.CommunityRecentSubmissions"/>
|
<map:transformer name="CommunityRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.CommunityRecentSubmissions"/>
|
||||||
|
|
||||||
|
|
||||||
<map:transformer name="CollectionSearch" src="org.dspace.app.xmlui.aspect.discovery.CollectionSearch"/>
|
<map:transformer name="CollectionSearch" src="org.dspace.app.xmlui.aspect.discovery.CollectionSearch"/>
|
||||||
<map:transformer name="CollectionRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.CollectionRecentSubmissions"/>
|
<map:transformer name="CollectionRecentSubmissions" src="org.dspace.app.xmlui.aspect.discovery.CollectionRecentSubmissions"/>
|
||||||
|
|
||||||
|
|
||||||
<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="RestrictedItem" src="org.dspace.app.xmlui.aspect.artifactbrowser.RestrictedItem"/>
|
<map:transformer name="RestrictedItem" src="org.dspace.app.xmlui.aspect.artifactbrowser.RestrictedItem"/>
|
||||||
</map:transformers>
|
</map:transformers>
|
||||||
|
|
||||||
|
|
||||||
<map:matchers default="wildcard">
|
<map:matchers default="wildcard">
|
||||||
<map:matcher name="HandleTypeMatcher" src="org.dspace.app.xmlui.aspect.general.HandleTypeMatcher"/>
|
<map:matcher name="HandleTypeMatcher" src="org.dspace.app.xmlui.aspect.general.HandleTypeMatcher"/>
|
||||||
<map:matcher name="HandleAuthorizedMatcher" src="org.dspace.app.xmlui.aspect.general.HandleAuthorizedMatcher"/>
|
<map:matcher name="HandleAuthorizedMatcher" src="org.dspace.app.xmlui.aspect.general.HandleAuthorizedMatcher"/>
|
||||||
</map:matchers>
|
</map:matchers>
|
||||||
<map:selectors>
|
<map:selectors>
|
||||||
<map:selector name="AuthenticatedSelector" src="org.dspace.app.xmlui.aspect.general.AuthenticatedSelector"/>
|
<map:selector name="AuthenticatedSelector" src="org.dspace.app.xmlui.aspect.general.AuthenticatedSelector"/>
|
||||||
</map:selectors>
|
</map:selectors>
|
||||||
|
|
||||||
</map:components>
|
</map:components>
|
||||||
<map:pipelines>
|
<map:pipelines>
|
||||||
<map:pipeline>
|
<map:pipeline>
|
||||||
|
|
||||||
|
|
||||||
<map:generate/>
|
<map:generate/>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Add the basic navigation content to everypage. This includes:
|
Add the basic navigation content to everypage. This includes:
|
||||||
|
|
||||||
1) Metadata about the current page (really just what the current
|
1) Metadata about the current page (really just what the current
|
||||||
context path is)
|
context path is)
|
||||||
2) Navigation links to browse the repository.
|
2) Navigation links to browse the repository.
|
||||||
- This includes links that are relative to the currently
|
- This includes links that are relative to the currently
|
||||||
selected community or collection.
|
selected community or collection.
|
||||||
3) Metadata about the search urls.
|
3) Metadata about the search urls.
|
||||||
-->
|
-->
|
||||||
<map:transform type="Navigation"/>
|
<map:transform type="Navigation"/>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Display the DSpace homepage. This includes the news.xml file
|
Display the DSpace homepage. This includes the news.xml file
|
||||||
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="SidebarFacetsTransformer"/>
|
||||||
<map:transform type="FrontPageSearch"/>
|
<map:transform type="FrontPageSearch"/>
|
||||||
|
|
||||||
<map:transform type="SiteRecentSubmissions"/>
|
<map:transform type="SiteRecentSubmissions"/>
|
||||||
|
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match>
|
</map:match>
|
||||||
|
|
||||||
|
|
||||||
<!-- List all communities & collections in DSpace
|
<!-- List all communities & collections in DSpace
|
||||||
<map:match pattern="community-list">
|
<map:match pattern="community-list">
|
||||||
<map:transform type="CommunityBrowser">
|
<map:transform type="CommunityBrowser">
|
||||||
<map:parameter name="depth" value="999"/>
|
<map:parameter name="depth" value="999"/>
|
||||||
</map:transform>
|
</map:transform>
|
||||||
<map:serialize type="xml"/>
|
<map:serialize type="xml"/>
|
||||||
</map:match> -->
|
</map:match> -->
|
||||||
|
|
||||||
|
|
||||||
<!-- Search -->
|
<!-- Search -->
|
||||||
<map:match pattern="discover">
|
<map:match pattern="discover">
|
||||||
<map:transform type="SidebarFacetsTransformer"/>
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<map:transform type="SimpleSearch"/>
|
<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/discovery-style.css"/>
|
||||||
|
|
||||||
<map:parameter name="javascript.static#1" value="loadJQuery.js"/>
|
<map:parameter name="javascript.static#1" value="loadJQuery.js"/>
|
||||||
<map:parameter name="javascript.static#2" value="static/js/discovery/core/Core.js"/>
|
<map:parameter name="javascript.static#2" value="static/js/discovery/search-controls.js"/>
|
||||||
<map:parameter name="javascript.static#3" value="static/js/discovery/core/AbstractManager.js"/>
|
</map:transform>
|
||||||
<map:parameter name="javascript.static#4" value="static/js/discovery/core/Parameter.js"/>
|
<map:serialize type="xml"/>
|
||||||
<map:parameter name="javascript.static#5" value="static/js/discovery/core/ParameterStore.js"/>
|
</map:match>
|
||||||
<map:parameter name="javascript.static#6" value="static/js/discovery/core/AbstractWidget.js"/>
|
|
||||||
<map:parameter name="javascript.static#7" value="static/js/discovery/core/AbstractFacetWidget.js"/>
|
<!--<map:match pattern="browse-discovery">-->
|
||||||
<map:parameter name="javascript.static#8" value="static/js/discovery/managers/Manager.jquery.js"/>
|
<!--<map:transform type="BrowseFacet"/>-->
|
||||||
<map:parameter name="javascript.static#9" value="static/js/jquery/jquery.autocomplete.js"/>
|
<!--<map:serialize type="xml"/>-->
|
||||||
<map:parameter name="javascript.static#10" value="static/js/discovery/widgets/AutocompleteWidget.js"/>
|
<!--</map:match>-->
|
||||||
<map:parameter name="javascript.static#11" value="static/js/discovery/search/search.js"/>
|
|
||||||
</map:transform>
|
<map:match pattern="search-filter">
|
||||||
<map:serialize type="xml"/>
|
<map:transform type="SearchFacetFilter"/>
|
||||||
</map:match>
|
<map:serialize type="xml"/>
|
||||||
|
</map:match>
|
||||||
<!--<map:match pattern="browse-discovery">-->
|
|
||||||
<!--<map:transform type="BrowseFacet"/>-->
|
<!-- Handle specific features -->
|
||||||
<!--<map:serialize type="xml"/>-->
|
<map:match pattern="handle/*/**">
|
||||||
<!--</map:match>-->
|
|
||||||
|
<!-- Scoped browse by features -->
|
||||||
<map:match pattern="search-filter">
|
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
||||||
<map:transform type="SearchFacetFilter"/>
|
<map:match type="HandleTypeMatcher" pattern="community,collection">
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
<!-- Browse (by anything) -->
|
||||||
|
<!--<map:match pattern="handle/*/*/browse-discovery">-->
|
||||||
<!-- Handle specific features -->
|
<!--<map:transform type="BrowseFacet"/>-->
|
||||||
<map:match pattern="handle/*/**">
|
<!--<map:serialize type="xml"/>-->
|
||||||
|
<!--</map:match>-->
|
||||||
<!-- Scoped browse by features -->
|
|
||||||
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
<!-- Simple search -->
|
||||||
<map:match type="HandleTypeMatcher" pattern="community,collection">
|
<map:match pattern="handle/*/*/discover">
|
||||||
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<!-- Browse (by anything) -->
|
<map:transform type="SimpleSearch"/>
|
||||||
<!--<map:match pattern="handle/*/*/browse-discovery">-->
|
<map:transform type="IncludePageMeta">
|
||||||
<!--<map:transform type="BrowseFacet"/>-->
|
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/discovery-style.css"/>
|
||||||
<!--<map:serialize type="xml"/>-->
|
|
||||||
<!--</map:match>-->
|
<map:parameter name="javascript.static#1" value="loadJQuery.js"/>
|
||||||
|
<map:parameter name="javascript.static#2" value="static/js/discovery/search-controls.js"/>
|
||||||
<!-- Simple search -->
|
</map:transform>
|
||||||
<map:match pattern="handle/*/*/discover">
|
<map:serialize type="xml"/>
|
||||||
<map:transform type="SidebarFacetsTransformer"/>
|
</map:match>
|
||||||
<map:transform type="SimpleSearch"/>
|
|
||||||
<map:transform type="IncludePageMeta">
|
|
||||||
<map:parameter name="stylesheet.screen.discovery#1" value="../../static/css/discovery/style.css"/>
|
<map:match pattern="handle/*/*/search-filter">
|
||||||
|
<map:transform type="SearchFacetFilter"/>
|
||||||
<map:parameter name="javascript.static#1" value="loadJQuery.js"/>
|
<map:serialize type="xml"/>
|
||||||
<map:parameter name="javascript.static#2" value="static/js/discovery/core/Core.js"/>
|
</map:match>
|
||||||
<map:parameter name="javascript.static#3" value="static/js/discovery/core/AbstractManager.js"/>
|
</map:match>
|
||||||
<map:parameter name="javascript.static#4" value="static/js/discovery/core/Parameter.js"/>
|
</map:match>
|
||||||
<map:parameter name="javascript.static#5" value="static/js/discovery/core/ParameterStore.js"/>
|
|
||||||
<map:parameter name="javascript.static#6" value="static/js/discovery/core/AbstractWidget.js"/>
|
<map:match pattern="handle/*/*">
|
||||||
<map:parameter name="javascript.static#7" value="static/js/discovery/core/AbstractFacetWidget.js"/>
|
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
||||||
<map:parameter name="javascript.static#8" value="static/js/discovery/managers/Manager.jquery.js"/>
|
<map:match type="HandleTypeMatcher" pattern="community">
|
||||||
<map:parameter name="javascript.static#9" value="static/js/jquery/jquery.autocomplete.js"/>
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
<map:parameter name="javascript.static#10" value="static/js/discovery/widgets/AutocompleteWidget.js"/>
|
<map:transform type="CommunitySearch"/>
|
||||||
<map:parameter name="javascript.static#11" value="static/js/discovery/search/search.js"/>
|
<map:transform type="CommunityRecentSubmissions"/>
|
||||||
</map:transform>
|
<map:serialize type="xml"/>
|
||||||
<map:serialize type="xml"/>
|
</map:match>
|
||||||
</map:match>
|
<map:match type="HandleTypeMatcher" pattern="collection">
|
||||||
|
<map:transform type="SidebarFacetsTransformer"/>
|
||||||
|
<map:transform type="CollectionSearch"/>
|
||||||
<map:match pattern="handle/*/*/search-filter">
|
<map:transform type="CollectionRecentSubmissions"/>
|
||||||
<map:transform type="SearchFacetFilter"/>
|
<map:serialize type="xml"/>
|
||||||
<map:serialize type="xml"/>
|
</map:match>
|
||||||
</map:match>
|
<map:match type="HandleTypeMatcher" pattern="item">
|
||||||
</map:match>
|
<!--<map:transform type="SidebarFacetsTransformer"/>-->
|
||||||
</map:match>
|
<!--<map:transform type="ItemFacets"/>-->
|
||||||
|
<map:transform type="RelatedItems"/>
|
||||||
<map:match pattern="handle/*/*">
|
<map:serialize type="xml"/>
|
||||||
<map:match type="HandleAuthorizedMatcher" pattern="READ">
|
</map:match>
|
||||||
<map:match type="HandleTypeMatcher" pattern="community">
|
</map:match>
|
||||||
<map:transform type="SidebarFacetsTransformer"/>
|
|
||||||
<map:transform type="CommunitySearch"/>
|
<map:match type="HandleAuthorizedMatcher" pattern="!READ">
|
||||||
<map:transform type="CommunityRecentSubmissions"/>
|
<map:transform type="RestrictedItem">
|
||||||
<map:serialize type="xml"/>
|
<map:parameter name="header" value="xmlui.ArtifactBrowser.RestrictedItem.auth_header"/>
|
||||||
</map:match>
|
<map:parameter name="message" value="xmlui.ArtifactBrowser.RestrictedItem.auth_message"/>
|
||||||
<map:match type="HandleTypeMatcher" pattern="collection">
|
</map:transform>
|
||||||
<map:transform type="SidebarFacetsTransformer"/>
|
<map:serialize type="xml"/>
|
||||||
<map:transform type="CollectionSearch"/>
|
</map:match>
|
||||||
<map:transform type="CollectionRecentSubmissions"/>
|
</map:match>
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
|
||||||
<map:match type="HandleTypeMatcher" pattern="item">
|
</map:match> <!-- End match handle/*/** -->
|
||||||
<!--<map:transform type="SidebarFacetsTransformer"/>-->
|
|
||||||
<!--<map:transform type="ItemFacets"/>-->
|
<!-- Not a URL we care about, so just pass it on. -->
|
||||||
<map:transform type="RelatedItems"/>
|
<map:serialize type="xml"/>
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
</map:pipeline>
|
||||||
</map:match>
|
|
||||||
|
|
||||||
<map:match type="HandleAuthorizedMatcher" pattern="!READ">
|
</map:pipelines>
|
||||||
<map:transform type="RestrictedItem">
|
</map:sitemap>
|
||||||
<map:parameter name="header" value="xmlui.ArtifactBrowser.RestrictedItem.auth_header"/>
|
|
||||||
<map:parameter name="message" value="xmlui.ArtifactBrowser.RestrictedItem.auth_message"/>
|
|
||||||
</map:transform>
|
|
||||||
<map:serialize type="xml"/>
|
|
||||||
</map:match>
|
|
||||||
</map:match>
|
|
||||||
|
|
||||||
|
|
||||||
</map:match> <!-- End match handle/*/** -->
|
|
||||||
|
|
||||||
<!-- Not a URL we care about, so just pass it on. -->
|
|
||||||
<map:serialize type="xml"/>
|
|
||||||
|
|
||||||
</map:pipeline>
|
|
||||||
|
|
||||||
|
|
||||||
</map:pipelines>
|
|
||||||
</map:sitemap>
|
|
||||||
|
@@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* 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/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Discovery control gears start
|
||||||
|
**/
|
||||||
|
|
||||||
|
div.controls-gear-wrapper{
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.controls-gear-wrapper .discovery-controls-gear{
|
||||||
|
padding: 3px 24px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection{
|
||||||
|
margin: 0 2px 0 0;
|
||||||
|
list-style: none;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
z-index: 999;
|
||||||
|
border: 1px solid #EBEBEB;
|
||||||
|
padding: 0;
|
||||||
|
/*Hidden by default*/
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bottom ul.gear-selection {
|
||||||
|
/*Css to ensure that the bottom gear selection list is shown on TOP of the button */
|
||||||
|
bottom: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gear-icon{
|
||||||
|
height: 25px;
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.rgba.boxshadow ul.gear-selection{
|
||||||
|
-webkit-box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
-moz-box-shadow: 2px 2px 10px rgba(0,0,0,0.2);
|
||||||
|
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection ul {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-head{
|
||||||
|
padding: 5px;
|
||||||
|
border-top: 1px solid #EBEBEB;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-head.first{
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option{
|
||||||
|
padding: 5px 5px 5px 25px;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option:hover{
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option a{
|
||||||
|
color: #444444;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Discovery control gears end
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
table.discovery-filters td.discovery-filter-input-cell input{
|
||||||
|
width: 98%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters tr.search-filter.used-filter input.filter-add
|
||||||
|
{
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchTime{
|
||||||
|
font-size: 80%;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input#aspect_discovery_SimpleSearch_field_query{
|
||||||
|
height: 25px;
|
||||||
|
font-size: 18px;
|
||||||
|
float: left;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.search-icon{
|
||||||
|
height: 33px;
|
||||||
|
float: left;
|
||||||
|
margin-left: 5px;
|
||||||
|
display: block;
|
||||||
|
width: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#aspect_discovery_SimpleSearch_div_search-results ul{
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#aspect_discovery_SimpleSearch_div_search-results ul li{
|
||||||
|
list-style: none;
|
||||||
|
}
|
@@ -1,56 +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/
|
|
||||||
*/
|
|
||||||
.ac_results {
|
|
||||||
padding: 0px;
|
|
||||||
border: 1px solid black;
|
|
||||||
background-color: white;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 99999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ac_results ul {
|
|
||||||
width: 100%;
|
|
||||||
list-style-position: outside;
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ac_results li {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 2px 5px;
|
|
||||||
cursor: default;
|
|
||||||
display: block;
|
|
||||||
text-align:left;
|
|
||||||
/*
|
|
||||||
if width will be 100% horizontal scrollbar will apear
|
|
||||||
when scroll mode will be used
|
|
||||||
*/
|
|
||||||
/*width: 100%;*/
|
|
||||||
font: menu;
|
|
||||||
font-size: 12px;
|
|
||||||
/*
|
|
||||||
it is very important, if line-height not setted or setted
|
|
||||||
in relative units scroll will be broken in firefox
|
|
||||||
*/
|
|
||||||
line-height: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ac_loading {
|
|
||||||
/*background: white url('indicator.gif') right center no-repeat;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.ac_odd {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ac_over {
|
|
||||||
background-color: #0A246A;
|
|
||||||
color: white;
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
Portions of this AJAX Solr are licensed under the Apache License (ASL) v2.0.
|
|
||||||
|
|
||||||
===
|
|
||||||
|
|
||||||
Copyright 2009 Evolving Web Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
@@ -1,133 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Baseclass for all facet widgets.
|
|
||||||
*
|
|
||||||
* @class AbstractFacetWidget
|
|
||||||
* @augments AjaxSolr.AbstractWidget
|
|
||||||
*/
|
|
||||||
AjaxSolr.AbstractFacetWidget = AjaxSolr.AbstractWidget.extend(
|
|
||||||
/** @lends AjaxSolr.AbstractFacetWidget.prototype */
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The field to facet on.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
field: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Boolean} Whether any filter queries have been set using this
|
|
||||||
* widget's facet field.
|
|
||||||
*/
|
|
||||||
isEmpty: function () {
|
|
||||||
return !this.manager.store.find('fq', new RegExp('^-?' + this.field + ':'));
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a filter query.
|
|
||||||
*
|
|
||||||
* @returns {Boolean} Whether a filter query was added.
|
|
||||||
*/
|
|
||||||
add: function (value) {
|
|
||||||
return this.changeSelection(function () {
|
|
||||||
return this.manager.store.addByValue('fq', this.fq(value));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a filter query.
|
|
||||||
*
|
|
||||||
* @returns {Boolean} Whether a filter query was removed.
|
|
||||||
*/
|
|
||||||
remove: function (value) {
|
|
||||||
return this.changeSelection(function () {
|
|
||||||
return this.manager.store.removeByValue('fq', this.fq(value));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all filter queries using the widget's facet field.
|
|
||||||
*
|
|
||||||
* @returns {Boolean} Whether a filter query was removed.
|
|
||||||
*/
|
|
||||||
clear: function () {
|
|
||||||
return this.changeSelection(function () {
|
|
||||||
return this.manager.store.removeByValue('fq', new RegExp('^-?' + this.field + ':'));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for selection functions.
|
|
||||||
*
|
|
||||||
* @param {Function} Selection function to call.
|
|
||||||
* @returns {Boolean} Whether the selection changed.
|
|
||||||
*/
|
|
||||||
changeSelection: function (func) {
|
|
||||||
changed = func.apply(this);
|
|
||||||
if (changed) {
|
|
||||||
this.afterChangeSelection();
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method is executed after the filter queries change.</p>
|
|
||||||
*/
|
|
||||||
afterChangeSelection: function () {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String} value The value.
|
|
||||||
* @returns {Function} Sends a request to Solr if it successfully adds a
|
|
||||||
* filter query with the given value.
|
|
||||||
*/
|
|
||||||
clickHandler: function (value) {
|
|
||||||
var self = this;
|
|
||||||
return function () {
|
|
||||||
if (self.add(value)) {
|
|
||||||
self.manager.doRequest(0);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String} value The value.
|
|
||||||
* @returns {Function} Sends a request to Solr if it successfully removes a
|
|
||||||
* filter query with the given value.
|
|
||||||
*/
|
|
||||||
unclickHandler: function (value) {
|
|
||||||
var self = this;
|
|
||||||
return function () {
|
|
||||||
if (self.remove(value)) {
|
|
||||||
self.manager.doRequest(0);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String} value The facet value.
|
|
||||||
* @param {Boolean} exclude Whether to exclude this fq parameter value.
|
|
||||||
* @returns {String} An fq parameter value.
|
|
||||||
*/
|
|
||||||
fq: function (value, exclude) {
|
|
||||||
// If the field value has a space or a colon in it, wrap it in quotes,
|
|
||||||
// unless it is a range query.
|
|
||||||
if (value.match(/[ :]/) && !value.match(/[\[\{]\S+ TO \S+[\]\}]/)) {
|
|
||||||
value = '"' + value + '"';
|
|
||||||
}
|
|
||||||
return (exclude ? '-' : '') + this.field + ':' + value;
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,189 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Manager acts as the controller in a Model-View-Controller framework. All
|
|
||||||
* public calls should be performed on the manager object.
|
|
||||||
*
|
|
||||||
* @param properties A map of fields to set. Refer to the list of public fields.
|
|
||||||
* @class AbstractManager
|
|
||||||
*/
|
|
||||||
AjaxSolr.AbstractManager = AjaxSolr.Class.extend(
|
|
||||||
/** @lends AjaxSolr.AbstractManager.prototype */
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The fully-qualified URL of the Solr application. You must include the
|
|
||||||
* trailing slash. Do not include the path to any Solr servlet.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
* @default "http://localhost:8983/solr/"
|
|
||||||
*/
|
|
||||||
solrUrl: 'http://localhost:8983/solr/',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we want to proxy queries through a script, rather than send queries
|
|
||||||
* to Solr directly, set this field to the fully-qualified URL of the script.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
proxyUrl: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default Solr servlet.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
* @default "select"
|
|
||||||
*/
|
|
||||||
servlet: 'select',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The most recent response from Solr.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Object
|
|
||||||
* @default {}
|
|
||||||
*/
|
|
||||||
response: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of all registered widgets. For internal use only.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Object
|
|
||||||
* @default {}
|
|
||||||
*/
|
|
||||||
widgets: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parameter store for the manager and its widgets. For internal use only.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Object
|
|
||||||
*/
|
|
||||||
store: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether <tt>init()</tt> has been called yet. For internal use only.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Boolean
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
initialized: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method should be called after the store and the widgets have been
|
|
||||||
* added. It should initialize the widgets and the store, and do any other
|
|
||||||
* one-time initializations, e.g., perform the first request to Solr.</p>
|
|
||||||
*
|
|
||||||
* <p>If no store has been set, it sets the store to the basic <tt>
|
|
||||||
* AjaxSolr.ParameterStore</tt>.</p>
|
|
||||||
*/
|
|
||||||
init: function () {
|
|
||||||
this.initialized = true;
|
|
||||||
if (this.store === null) {
|
|
||||||
this.setStore(new AjaxSolr.ParameterStore());
|
|
||||||
}
|
|
||||||
this.store.load(false);
|
|
||||||
for (var widgetId in this.widgets) {
|
|
||||||
this.widgets[widgetId].init();
|
|
||||||
}
|
|
||||||
this.store.init();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the manager's parameter store.
|
|
||||||
*
|
|
||||||
* @param {AjaxSolr.ParameterStore} store
|
|
||||||
*/
|
|
||||||
setStore: function (store) {
|
|
||||||
store.manager = this;
|
|
||||||
this.store = store;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a widget to the manager.
|
|
||||||
*
|
|
||||||
* @param {AjaxSolr.AbstractWidget} widget
|
|
||||||
*/
|
|
||||||
addWidget: function (widget) {
|
|
||||||
widget.manager = this;
|
|
||||||
this.widgets[widget.id] = widget;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the Solr parameters to be sent to Solr and sends a request to Solr.
|
|
||||||
*
|
|
||||||
* @param {Boolean} [start] The Solr start offset parameter.
|
|
||||||
* @param {String} [servlet] The Solr servlet to send the request to.
|
|
||||||
*/
|
|
||||||
doRequest: function (start, servlet) {
|
|
||||||
if (this.initialized === false) {
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
// Allow non-pagination widgets to reset the offset parameter.
|
|
||||||
if (start !== undefined) {
|
|
||||||
this.store.get('start').val(start);
|
|
||||||
}
|
|
||||||
if (servlet === undefined) {
|
|
||||||
servlet = this.servlet;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.store.save();
|
|
||||||
|
|
||||||
for (var widgetId in this.widgets) {
|
|
||||||
this.widgets[widgetId].beforeRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.executeRequest(servlet);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>Sends the request to Solr, i.e. to <code>this.solrUrl</code> or <code>
|
|
||||||
* this.proxyUrl</code>, and receives Solr's response. It should send <code>
|
|
||||||
* this.store.string()</code> as the Solr query, and it should pass Solr's
|
|
||||||
* response to <code>handleResponse()</code> for handling.</p>
|
|
||||||
*
|
|
||||||
* <p>See <tt>managers/Manager.jquery.js</tt> for a jQuery implementation.</p>
|
|
||||||
*
|
|
||||||
* @param {String} servlet The Solr servlet to send the request to.
|
|
||||||
* @throws If not defined in child implementation.
|
|
||||||
*/
|
|
||||||
executeRequest: function (servlet) {
|
|
||||||
throw 'Abstract method executeRequest must be overridden in a subclass.';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is executed after the Solr response data arrives. Allows each
|
|
||||||
* widget to handle Solr's response separately.
|
|
||||||
*
|
|
||||||
* @param {Object} data The Solr response.
|
|
||||||
*/
|
|
||||||
handleResponse: function (data) {
|
|
||||||
this.response = data;
|
|
||||||
|
|
||||||
for (var widgetId in this.widgets) {
|
|
||||||
this.widgets[widgetId].afterRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,70 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Baseclass for all widgets.
|
|
||||||
*
|
|
||||||
* Provides abstract hooks for child classes.
|
|
||||||
*
|
|
||||||
* @param properties A map of fields to set. May be new or public fields.
|
|
||||||
* @class AbstractWidget
|
|
||||||
*/
|
|
||||||
AjaxSolr.AbstractWidget = AjaxSolr.Class.extend(
|
|
||||||
/** @lends AjaxSolr.AbstractWidget.prototype */
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A unique identifier of this widget.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
id: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The CSS selector for this widget's target HTML element, e.g. a specific
|
|
||||||
* <tt>div</tt> or <tt>ul</tt>. A Widget is usually implemented to perform
|
|
||||||
* all its UI changes relative to its target HTML element.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
target: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reference to the widget's manager. For internal use only.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type AjaxSolr.AbstractManager
|
|
||||||
*/
|
|
||||||
manager: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method should do any necessary one-time initializations.</p>
|
|
||||||
*/
|
|
||||||
init: function () {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method is executed before the Solr request is sent.</p>
|
|
||||||
*/
|
|
||||||
beforeRequest: function () {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method is executed after the Solr response is received.</p>
|
|
||||||
*/
|
|
||||||
afterRequest: function () {}
|
|
||||||
});
|
|
@@ -1,233 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @namespace A unique namespace for the AJAX Solr library.
|
|
||||||
*/
|
|
||||||
AjaxSolr = function () {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @namespace Baseclass for all classes
|
|
||||||
*/
|
|
||||||
AjaxSolr.Class = function () {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class 'extends' itself into a subclass.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @param properties The properties of the subclass.
|
|
||||||
* @returns A function that represents the subclass.
|
|
||||||
*/
|
|
||||||
AjaxSolr.Class.extend = function (properties) {
|
|
||||||
var klass = this; // Safari dislikes 'class'
|
|
||||||
// The subclass is just a function that when called, instantiates itself.
|
|
||||||
// Nothing is _actually_ shared between _instances_ of the same class.
|
|
||||||
var subClass = function (options) {
|
|
||||||
// 'this' refers to the subclass, which starts life as an empty object.
|
|
||||||
// Add its parent's properties, its own properties, and any passed options.
|
|
||||||
AjaxSolr.extend(this, new klass(options), properties, options);
|
|
||||||
}
|
|
||||||
// Allow the subclass to extend itself into further subclasses.
|
|
||||||
subClass.extend = this.extend;
|
|
||||||
return subClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @static
|
|
||||||
* @param {Object} obj Any object.
|
|
||||||
* @returns {Number} the number of properties on an object.
|
|
||||||
* @see http://stackoverflow.com/questions/5223/length-of-javascript-associative-array
|
|
||||||
*/
|
|
||||||
AjaxSolr.size = function (obj) {
|
|
||||||
var size = 0;
|
|
||||||
for (var key in obj) {
|
|
||||||
if (obj.hasOwnProperty(key)) {
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @static
|
|
||||||
* @param foo A value.
|
|
||||||
* @param bar A value.
|
|
||||||
* @returns {Boolean} Whether the two given values are equal.
|
|
||||||
*/
|
|
||||||
AjaxSolr.equals = function (foo, bar) {
|
|
||||||
if (AjaxSolr.isArray(foo) && AjaxSolr.isArray(bar)) {
|
|
||||||
if (foo.length !== bar.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (var i = 0, l = foo.length; i < l; i++) {
|
|
||||||
if (foo[i] !== bar[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (AjaxSolr.isRegExp(foo) && AjaxSolr.isString(bar)) {
|
|
||||||
return bar.match(foo);
|
|
||||||
}
|
|
||||||
else if (AjaxSolr.isRegExp(bar) && AjaxSolr.isString(foo)) {
|
|
||||||
return foo.match(bar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return foo === bar;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @static
|
|
||||||
* @param value A value.
|
|
||||||
* @param array An array.
|
|
||||||
* @returns {Boolean} Whether value exists in the array.
|
|
||||||
*/
|
|
||||||
AjaxSolr.inArray = function (value, array) {
|
|
||||||
if (array) {
|
|
||||||
for (var i = 0, l = array.length; i < l; i++) {
|
|
||||||
if (AjaxSolr.equals(array[i], value)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A copy of MooTools' Array.flatten function.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @see http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools.js
|
|
||||||
*/
|
|
||||||
AjaxSolr.flatten = function(array) {
|
|
||||||
var ret = [];
|
|
||||||
for (var i = 0, l = array.length; i < l; i++) {
|
|
||||||
ret = ret.concat(AjaxSolr.isArray(array[i]) ? AjaxSolr.flatten(array[i]) : array[i]);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A copy of jQuery's jQuery.grep function.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @see http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js
|
|
||||||
*/
|
|
||||||
AjaxSolr.grep = function(array, callback) {
|
|
||||||
var ret = [];
|
|
||||||
for (var i = 0, l = array.length; i < l; i++) {
|
|
||||||
if (!callback(array[i], i) === false) {
|
|
||||||
ret.push(array[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent to Ruby's Array#compact.
|
|
||||||
*/
|
|
||||||
AjaxSolr.compact = function(array) {
|
|
||||||
return AjaxSolr.grep(array, function (item) {
|
|
||||||
return item.toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can't use toString.call(obj) === "[object Array]", as it may return
|
|
||||||
* "[xpconnect wrapped native prototype]", which is undesirable.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
|
|
||||||
* @see http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js
|
|
||||||
*/
|
|
||||||
AjaxSolr.isArray = function (obj) {
|
|
||||||
return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param obj Any object.
|
|
||||||
* @returns {Boolean} Whether the object is a RegExp object.
|
|
||||||
*/
|
|
||||||
AjaxSolr.isRegExp = function (obj) {
|
|
||||||
return obj != null && (typeof obj == 'object' || typeof obj == 'function') && 'ignoreCase' in obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param obj Any object.
|
|
||||||
* @returns {Boolean} Whether the object is a String object.
|
|
||||||
*/
|
|
||||||
AjaxSolr.isString = function (obj) {
|
|
||||||
return obj != null && typeof obj == 'string';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define theme functions to separate, as much as possible, your HTML from your
|
|
||||||
* JavaScript. Theme functions provided by AJAX Solr are defined in the
|
|
||||||
* AjaxSolr.theme.prototype namespace, e.g. AjaxSolr.theme.prototype.select_tag.
|
|
||||||
*
|
|
||||||
* To override a theme function provided by AJAX Solr, define a function of the
|
|
||||||
* same name in the AjaxSolr.theme namespace, e.g. AjaxSolr.theme.select_tag.
|
|
||||||
*
|
|
||||||
* To retrieve the HTML output by AjaxSolr.theme.prototype.select_tag(...), call
|
|
||||||
* AjaxSolr.theme('select_tag', ...).
|
|
||||||
*
|
|
||||||
* @param {String} func
|
|
||||||
* The name of the theme function to call.
|
|
||||||
* @param ...
|
|
||||||
* Additional arguments to pass along to the theme function.
|
|
||||||
* @returns
|
|
||||||
* Any data the theme function returns. This could be a plain HTML string,
|
|
||||||
* but also a complex object.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @throws Exception if the theme function is not defined.
|
|
||||||
* @see http://cvs.drupal.org/viewvc.py/drupal/drupal/misc/drupal.js?revision=1.58
|
|
||||||
*/
|
|
||||||
AjaxSolr.theme = function (func) {
|
|
||||||
for (var i = 1, args = []; i < arguments.length; i++) {
|
|
||||||
args.push(arguments[i]);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (AjaxSolr.theme[func] || AjaxSolr.theme.prototype[func]).apply(this, args);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (console && console.log) {
|
|
||||||
console.log('Theme function "' + func + '" is not defined.');
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simplified version of jQuery's extend function.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @see http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js
|
|
||||||
*/
|
|
||||||
AjaxSolr.extend = function () {
|
|
||||||
var target = arguments[0] || {}, i = 1, length = arguments.length, options;
|
|
||||||
for (; i < length; i++) {
|
|
||||||
if ((options = arguments[i]) != null) {
|
|
||||||
for (var name in options) {
|
|
||||||
var src = target[name], copy = options[name];
|
|
||||||
if (target === copy) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (copy && typeof copy == 'object' && !copy.nodeType) {
|
|
||||||
target[name] = AjaxSolr.extend(src || (copy.length != null ? [] : {}), copy);
|
|
||||||
}
|
|
||||||
else if (copy !== undefined) {
|
|
||||||
target[name] = copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
};
|
|
@@ -1,168 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a Solr parameter.
|
|
||||||
*
|
|
||||||
* @param properties A map of fields to set. Refer to the list of public fields.
|
|
||||||
* @class Parameter
|
|
||||||
*/
|
|
||||||
AjaxSolr.Parameter = AjaxSolr.Class.extend(
|
|
||||||
/** @lends AjaxSolr.Parameter.prototype */
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The parameter's name.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
name: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parameter's value.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
value: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parameter's local parameters.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Object
|
|
||||||
* @default {}
|
|
||||||
*/
|
|
||||||
locals: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value. If called with an argument, sets the value.
|
|
||||||
*
|
|
||||||
* @param {String|Number|String[]|Number[]} [value] The value to set.
|
|
||||||
* @returns The value.
|
|
||||||
*/
|
|
||||||
val: function (value) {
|
|
||||||
if (value === undefined) {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of a local parameter. If called with a second argument,
|
|
||||||
* sets the value of a local parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the local parameter.
|
|
||||||
* @param {String|Number|String[]|Number[]} [value] The value to set.
|
|
||||||
* @returns The value.
|
|
||||||
*/
|
|
||||||
local: function (name, value) {
|
|
||||||
if (value === undefined) {
|
|
||||||
return this.locals[name];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.locals[name] = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a local parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the local parameter.
|
|
||||||
*/
|
|
||||||
remove: function (name) {
|
|
||||||
delete this.locals[name];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Solr parameter as a query string key-value pair.
|
|
||||||
*
|
|
||||||
* <p>IE6 calls the default toString() if you write <tt>store.toString()
|
|
||||||
* </tt>. So, we need to choose another name for toString().</p>
|
|
||||||
*/
|
|
||||||
string: function () {
|
|
||||||
var pairs = [];
|
|
||||||
|
|
||||||
for (var name in this.locals) {
|
|
||||||
if (this.locals[name]) {
|
|
||||||
pairs.push(name + '=' + encodeURIComponent(this.locals[name]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var prefix = pairs.length ? '{!' + pairs.join('%20') + '}' : '';
|
|
||||||
|
|
||||||
if (this.value) {
|
|
||||||
return this.name + '=' + prefix + this.valueString(this.value);
|
|
||||||
}
|
|
||||||
// For dismax request handlers, if the q parameter has local params, the
|
|
||||||
// q parameter must be set to a non-empty value. In case the q parameter
|
|
||||||
// is empty, use the q.alt parameter, which accepts wildcards.
|
|
||||||
else if (this.name == 'q') {
|
|
||||||
return 'q.alt=' + prefix + encodeURIComponent('*.*');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a string formed by calling string().
|
|
||||||
*
|
|
||||||
* @param {String} str The string to parse.
|
|
||||||
*/
|
|
||||||
parseString: function (str) {
|
|
||||||
var param = str.match(/^([^=]+)=(?:\{!([^\}]*)\})?(.*)$/);
|
|
||||||
if (param) {
|
|
||||||
var matches;
|
|
||||||
|
|
||||||
while (matches = /([^\s=]+)=(\S*)/g.exec(decodeURIComponent(param[2]))) {
|
|
||||||
this.locals[matches[1]] = decodeURIComponent(matches[2]);
|
|
||||||
param[2] = param[2].replace(matches[0], ''); // Safari's exec seems not to do this on its own
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param[1] == 'q.alt') {
|
|
||||||
this.name = 'q';
|
|
||||||
// if q.alt is present, assume it is because q was empty, as above
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.name = param[1];
|
|
||||||
this.value = this.parseValueString(param[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value as a URL-encoded string.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String|Number|String[]|Number[]} value The value.
|
|
||||||
* @returns {String} The URL-encoded string.
|
|
||||||
*/
|
|
||||||
valueString: function (value) {
|
|
||||||
value = AjaxSolr.isArray(value) ? value.join(',') : value;
|
|
||||||
return encodeURIComponent(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a URL-encoded string to return the value.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} str The URL-encoded string.
|
|
||||||
* @returns {Array} The value.
|
|
||||||
*/
|
|
||||||
parseValueString: function (str) {
|
|
||||||
str = decodeURIComponent(str);
|
|
||||||
return str.indexOf(',') == -1 ? str : str.split(',');
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,361 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ParameterStore, as its name suggests, stores Solr parameters. Widgets
|
|
||||||
* expose some of these parameters to the user. Whenever the user changes the
|
|
||||||
* values of these parameters, the state of the application changes. In order to
|
|
||||||
* allow the user to move back and forth between these states with the browser's
|
|
||||||
* Back and Forward buttons, and to bookmark these states, each state needs to
|
|
||||||
* be stored. The easiest method is to store the exposed parameters in the URL
|
|
||||||
* hash (see the <tt>ParameterHashStore</tt> class). However, you may implement
|
|
||||||
* your own storage method by extending this class.
|
|
||||||
*
|
|
||||||
* <p>For a list of possible parameters, please consult the links below.</p>
|
|
||||||
*
|
|
||||||
* @see http://wiki.apache.org/solr/CoreQueryParameters
|
|
||||||
* @see http://wiki.apache.org/solr/CommonQueryParameters
|
|
||||||
* @see http://wiki.apache.org/solr/SimpleFacetParameters
|
|
||||||
* @see http://wiki.apache.org/solr/HighlightingParameters
|
|
||||||
* @see http://wiki.apache.org/solr/MoreLikeThis
|
|
||||||
* @see http://wiki.apache.org/solr/SpellCheckComponent
|
|
||||||
* @see http://wiki.apache.org/solr/StatsComponent
|
|
||||||
* @see http://wiki.apache.org/solr/TermsComponent
|
|
||||||
* @see http://wiki.apache.org/solr/TermVectorComponent
|
|
||||||
* @see http://wiki.apache.org/solr/LocalParams
|
|
||||||
*
|
|
||||||
* @param properties A map of fields to set. Refer to the list of public fields.
|
|
||||||
* @class ParameterStore
|
|
||||||
*/
|
|
||||||
AjaxSolr.ParameterStore = AjaxSolr.Class.extend(
|
|
||||||
/** @lends AjaxSolr.ParameterStore.prototype */
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The names of the exposed parameters. Any parameters that your widgets
|
|
||||||
* expose to the user, directly or indirectly, should be listed here.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @public
|
|
||||||
* @type String[]
|
|
||||||
* @default []
|
|
||||||
*/
|
|
||||||
exposed: [],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Solr parameters.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type Object
|
|
||||||
* @default {}
|
|
||||||
*/
|
|
||||||
params: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reference to the parameter store's manager. For internal use only.
|
|
||||||
*
|
|
||||||
* @field
|
|
||||||
* @private
|
|
||||||
* @type AjaxSolr.AbstractManager
|
|
||||||
*/
|
|
||||||
manager: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>This method should do any necessary one-time initializations.</p>
|
|
||||||
*/
|
|
||||||
init: function () {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some Solr parameters may be specified multiple times. It is easiest to
|
|
||||||
* hard-code a list of such parameters. You may change the list by passing
|
|
||||||
* <code>{ multiple: /pattern/ }</code> as an argument to the constructor of
|
|
||||||
* this class or one of its children, e.g.:
|
|
||||||
*
|
|
||||||
* <p><code>new ParameterStore({ multiple: /pattern/ })</code>
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @returns {Boolean} Whether the parameter may be specified multiple times.
|
|
||||||
*/
|
|
||||||
isMultiple: function (name) {
|
|
||||||
return name.match(/^(?:bf|bq|facet\.date|facet\.date\.other|facet\.field|facet\.query|fq|pf|qf)$/);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a parameter. If the parameter doesn't exist, creates it.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @returns {AjaxSolr.Parameter|AjaxSolr.Parameter[]} The parameter.
|
|
||||||
*/
|
|
||||||
get: function (name) {
|
|
||||||
if (this.params[name] === undefined) {
|
|
||||||
var param = new AjaxSolr.Parameter({ name: name });
|
|
||||||
if (this.isMultiple(name)) {
|
|
||||||
this.params[name] = [ param ];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.params[name] = param;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.params[name];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the parameter may be specified multiple times, returns the values of
|
|
||||||
* all identically-named parameters. If the parameter may be specified only
|
|
||||||
* once, returns the value of that parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @returns {String[]|Number[]} The value(s) of the parameter.
|
|
||||||
*/
|
|
||||||
values: function (name) {
|
|
||||||
if (this.params[name] !== undefined) {
|
|
||||||
if (this.isMultiple(name)) {
|
|
||||||
var values = [];
|
|
||||||
for (var i = 0, l = this.params[name].length; i < l; i++) {
|
|
||||||
values.push(this.params[name][i].val());
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return [ this.params[name].val() ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the parameter may be specified multiple times, adds the given parameter
|
|
||||||
* to the list of identically-named parameters, unless one already exists with
|
|
||||||
* the same value. If it may be specified only once, replaces the parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @param {AjaxSolr.Parameter} [param] The parameter.
|
|
||||||
* @returns {AjaxSolr.Parameter|Boolean} The parameter, or false.
|
|
||||||
*/
|
|
||||||
add: function (name, param) {
|
|
||||||
if (param === undefined) {
|
|
||||||
param = new AjaxSolr.Parameter({ name: name });
|
|
||||||
}
|
|
||||||
if (this.isMultiple(name)) {
|
|
||||||
if (this.params[name] === undefined) {
|
|
||||||
this.params[name] = [ param ];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (AjaxSolr.inArray(param.val(), this.values(name)) == -1) {
|
|
||||||
this.params[name].push(param);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.params[name] = param;
|
|
||||||
}
|
|
||||||
return param;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @param {Number} [index] The index of the parameter.
|
|
||||||
*/
|
|
||||||
remove: function (name, index) {
|
|
||||||
if (index === undefined) {
|
|
||||||
delete this.params[name];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.params[name].splice(index, 1);
|
|
||||||
if (this.params[name].length == 0) {
|
|
||||||
delete this.params[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all parameters with matching values.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @param {String|Number|String[]|Number[]|RegExp} value The value.
|
|
||||||
* @returns {String|Number[]} The indices of the parameters found.
|
|
||||||
*/
|
|
||||||
find: function (name, value) {
|
|
||||||
if (this.params[name] !== undefined) {
|
|
||||||
if (this.isMultiple(name)) {
|
|
||||||
var indices = [];
|
|
||||||
for (var i = 0, l = this.params[name].length; i < l; i++) {
|
|
||||||
if (AjaxSolr.equals(this.params[name][i].val(), value)) {
|
|
||||||
indices.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return indices.length ? indices : false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (AjaxSolr.equals(this.params[name].val(), value)) {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the parameter may be specified multiple times, creates a parameter using
|
|
||||||
* the given name and value, and adds it to the list of identically-named
|
|
||||||
* parameters, unless one already exists with the same value. If it may be
|
|
||||||
* specified only once, replaces the parameter.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @param {String|Number|String[]|Number[]} value The value.
|
|
||||||
* @returns {AjaxSolr.Parameter|Boolean} The parameter, or false.
|
|
||||||
*/
|
|
||||||
addByValue: function (name, value) {
|
|
||||||
if (this.isMultiple(name) && AjaxSolr.isArray(value)) {
|
|
||||||
var ret = [];
|
|
||||||
for (var i = 0, l = value.length; i < l; i++) {
|
|
||||||
ret.push(this.add(name, new AjaxSolr.Parameter({ name: name, value: value[i] })));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return this.add(name, new AjaxSolr.Parameter({ name: name, value: value }))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes any parameter with a matching value.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the parameter.
|
|
||||||
* @param {String|Number|String[]|Number[]|RegExp} value The value.
|
|
||||||
* @returns {String|Number[]} The indices deleted.
|
|
||||||
*/
|
|
||||||
removeByValue: function (name, value) {
|
|
||||||
var indices = this.find(name, value);
|
|
||||||
if (indices) {
|
|
||||||
if (AjaxSolr.isArray(indices)) {
|
|
||||||
for (var i = indices.length - 1; i >= 0; i--) {
|
|
||||||
this.remove(name, indices[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.remove(indices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return indices;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Solr parameters as a query string.
|
|
||||||
*
|
|
||||||
* <p>IE6 calls the default toString() if you write <tt>store.toString()
|
|
||||||
* </tt>. So, we need to choose another name for toString().</p>
|
|
||||||
*/
|
|
||||||
string: function () {
|
|
||||||
var params = [];
|
|
||||||
for (var name in this.params) {
|
|
||||||
if (this.isMultiple(name)) {
|
|
||||||
for (var i = 0, l = this.params[name].length; i < l; i++) {
|
|
||||||
params.push(this.params[name][i].string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
params.push(this.params[name].string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return AjaxSolr.compact(params).join('&');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a query string into Solr parameters.
|
|
||||||
*
|
|
||||||
* @param {String} str The string to parse.
|
|
||||||
*/
|
|
||||||
parseString: function (str) {
|
|
||||||
var pairs = str.split('&');
|
|
||||||
for (var i = 0, l = pairs.length; i < l; i++) {
|
|
||||||
if (pairs[i]) { // ignore leading, trailing, and consecutive &'s
|
|
||||||
var param = new AjaxSolr.Parameter();
|
|
||||||
param.parseString(pairs[i]);
|
|
||||||
this.add(param.name, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exposed parameters as a query string.
|
|
||||||
*
|
|
||||||
* @returns {String} A string representation of the exposed parameters.
|
|
||||||
*/
|
|
||||||
exposedString: function () {
|
|
||||||
var params = [];
|
|
||||||
for (var i = 0, l = this.exposed.length; i < l; i++) {
|
|
||||||
if (this.params[this.exposed[i]] !== undefined) {
|
|
||||||
if (this.isMultiple(this.exposed[i])) {
|
|
||||||
for (var j = 0, m = this.params[this.exposed[i]].length; j < m; j++) {
|
|
||||||
params.push(this.params[this.exposed[i]][j].string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
params.push(this.params[this.exposed[i]].string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return AjaxSolr.compact(params).join('&');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the values of the exposed parameters.
|
|
||||||
*/
|
|
||||||
exposedReset: function () {
|
|
||||||
for (var i = 0, l = this.exposed.length; i < l; i++) {
|
|
||||||
this.remove(this.exposed[i]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the values of exposed parameters from persistent storage. It is
|
|
||||||
* necessary, in most cases, to reset the values of exposed parameters before
|
|
||||||
* setting the parameters to the values in storage. This is to ensure that a
|
|
||||||
* parameter whose name is not present in storage is properly reset.
|
|
||||||
*
|
|
||||||
* @param {Boolean} [reset=true] Whether to reset the exposed parameters.
|
|
||||||
* before loading new values from persistent storage. Default: true.
|
|
||||||
*/
|
|
||||||
load: function (reset) {
|
|
||||||
if (reset === undefined) {
|
|
||||||
reset = true;
|
|
||||||
}
|
|
||||||
if (reset) {
|
|
||||||
this.exposedReset();
|
|
||||||
}
|
|
||||||
this.parseString(this.storedString());
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>Stores the values of the exposed parameters in persistent storage. This
|
|
||||||
* method should usually be called before each Solr request.</p>
|
|
||||||
*/
|
|
||||||
save: function () {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract hook for child implementations.
|
|
||||||
*
|
|
||||||
* <p>Returns the string to parse from persistent storage.</p>
|
|
||||||
*
|
|
||||||
* @returns {String} The string from persistent storage.
|
|
||||||
*/
|
|
||||||
storedString: function () {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,28 +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/
|
|
||||||
*/
|
|
||||||
// $Id$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see http://wiki.apache.org/solr/SolJSON#JSON_specific_parameters
|
|
||||||
* @class Manager
|
|
||||||
* @augments AjaxSolr.AbstractManager
|
|
||||||
*/
|
|
||||||
AjaxSolr.Manager = AjaxSolr.AbstractManager.extend(
|
|
||||||
/** @lends AjaxSolr.Manager.prototype */
|
|
||||||
{
|
|
||||||
executeRequest: function (servlet) {
|
|
||||||
var self = this;
|
|
||||||
if (this.proxyUrl) {
|
|
||||||
jQuery.post(this.proxyUrl, { query: this.store.string() }, function (data) { self.handleResponse(data); }, 'json');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// jQuery.getJSON(this.solrUrl + servlet + '?' + this.store.string() + '&wt=json&json.wrf=?', {}, function (data) { self.handleResponse(data); });
|
|
||||||
jQuery.getJSON(this.solrUrl + '?' + this.store.string() + '&wt=json&json.wrf=?', {}, function (data) { self.handleResponse(data); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* 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/
|
||||||
|
*/
|
||||||
|
(function ($) {
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
initializeGear();
|
||||||
|
initializeFilters();
|
||||||
|
});
|
||||||
|
|
||||||
|
function initializeGear(){
|
||||||
|
var gearControlsDivs = $('div#aspect_discovery_SimpleSearch_div_search-controls-gear');
|
||||||
|
jQuery.each(gearControlsDivs, function(index, value) {
|
||||||
|
var gearControlsDiv = $(value);
|
||||||
|
var gearControls = gearControlsDiv.find('ul#aspect_discovery_SimpleSearch_list_sort-options');
|
||||||
|
var gearButton = $('<button class="discovery-controls-gear ds-button-field"><div class="gear-icon"> </div></button>');
|
||||||
|
|
||||||
|
gearButton.click(function(){
|
||||||
|
if(gearControls.is(':visible')){
|
||||||
|
gearControls.hide();
|
||||||
|
}else{
|
||||||
|
gearControls.show();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
//Disable the default click
|
||||||
|
gearControls.find('li.gear-option,li.gear-option a').click(function(event){
|
||||||
|
//Ensure that our html click isn't called !
|
||||||
|
event.stopPropagation();
|
||||||
|
var $link = $(this);
|
||||||
|
var listItem;
|
||||||
|
if($link.is('li')){
|
||||||
|
listItem = $link;
|
||||||
|
}else{
|
||||||
|
listItem = $link.parents('li:first');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if this option is currently selected, if so skip the next stuff
|
||||||
|
if(listItem.hasClass('gear-option-selected')){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!$link.attr('href')){
|
||||||
|
$link = $link.find('a');
|
||||||
|
}
|
||||||
|
//Retrieve the params we are to fill in in our main form
|
||||||
|
var params = $link.attr('href').split('&');
|
||||||
|
|
||||||
|
var mainForm = $('form#aspect_discovery_SimpleSearch_div_main-form');
|
||||||
|
//Split them & fill in in the main form, when done submit the main form !
|
||||||
|
for(var i = 0; i < params.length; i++){
|
||||||
|
var param = params[i].split('=')[0];
|
||||||
|
var value = params[i].split('=')[1];
|
||||||
|
|
||||||
|
mainForm.find('input[name="' + param + '"]').val(value);
|
||||||
|
}
|
||||||
|
//Clear the page param
|
||||||
|
mainForm.find('input[name="page"]').val('1');
|
||||||
|
|
||||||
|
mainForm.submit();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
gearButton.prependTo(gearControlsDiv);
|
||||||
|
gearControls.hide();
|
||||||
|
|
||||||
|
$('html').click(function() {
|
||||||
|
//Hide the menus if visible
|
||||||
|
if(gearControls.is(':visible')){
|
||||||
|
gearControls.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeFilters(){
|
||||||
|
//Initialize the show filters link
|
||||||
|
$('a[href="display-filters"]').click(function(){
|
||||||
|
var filtersForm = $('form#aspect_discovery_SimpleSearch_div_search-filters');
|
||||||
|
filtersForm.show();
|
||||||
|
filtersForm.css('visibility', 'visible');
|
||||||
|
$(this).hide();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('input[name^="add-filter_"]').click(function(){
|
||||||
|
addFilterRow();
|
||||||
|
|
||||||
|
//Disable "normal" button actions
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$('input[name^=remove-filter_]').click(function(){
|
||||||
|
removeFilterRow($(this));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
//Disable the enter key !
|
||||||
|
$('input[name^=filter_][type=text]').keypress(function(event){
|
||||||
|
if(event.which == 13){
|
||||||
|
//Entered pressed, do NOT submit the form, add a new filter instead !
|
||||||
|
addFilterRow();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFilterRow(button){
|
||||||
|
var parentRow = button.parents('tr:first');
|
||||||
|
|
||||||
|
//Check if we are removing a new filter AND our last new filter at that, if so removes values instead of the row
|
||||||
|
if(parentRow.is('[id^="aspect_discovery_SimpleSearch_row_filter-new-"]')
|
||||||
|
&& parentRow.parents('table:first').find('tr[id^="aspect_discovery_SimpleSearch_row_filter-new-"]').length == 1){
|
||||||
|
//Hide ourselves & clear our values!
|
||||||
|
parentRow.find('input[type=text]", select').val('');
|
||||||
|
}else{
|
||||||
|
parentRow.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFilterRow(){
|
||||||
|
var previousFilterRow = $('tr#aspect_discovery_SimpleSearch_row_filter-controls').prev();
|
||||||
|
//Duplicate our element & give it a new index !
|
||||||
|
var newFilterRow = previousFilterRow.clone();
|
||||||
|
//Alter the html to update the index
|
||||||
|
var rowIdentifier = newFilterRow.attr('id');
|
||||||
|
var oldIndex = parseInt(rowIdentifier.substr(rowIdentifier.lastIndexOf('-')+1, rowIdentifier.length));
|
||||||
|
//Add one to the index !
|
||||||
|
var newIndex = oldIndex + 1;
|
||||||
|
//Update the index of all inputs & our list
|
||||||
|
newFilterRow.attr('id', newFilterRow.attr('id').replace('-' + oldIndex, '-' + newIndex));
|
||||||
|
newFilterRow.find('input, select').each(function(){
|
||||||
|
var $this = $(this);
|
||||||
|
//Update the index of the name (if present)
|
||||||
|
$this.attr('name', $this.attr('name').replace('_' + oldIndex, '_' + newIndex));
|
||||||
|
$this.attr('id', $this.attr('id').replace('_' + oldIndex, '_' + newIndex));
|
||||||
|
});
|
||||||
|
//Clear the values
|
||||||
|
newFilterRow.find('input[type=text], select').val('');
|
||||||
|
|
||||||
|
previousFilterRow = newFilterRow.insertAfter(previousFilterRow);
|
||||||
|
//Initialize the add button
|
||||||
|
previousFilterRow.find('input[name^="add-filter_"]').click(function(){
|
||||||
|
addFilterRow();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
//Initialize the remove button
|
||||||
|
previousFilterRow.find('input[name^=remove-filter_]').click(function(){
|
||||||
|
removeFilterRow($(this));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})(jQuery);
|
@@ -1,133 +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/
|
|
||||||
*/
|
|
||||||
var Manager;
|
|
||||||
var query;
|
|
||||||
var defaultFacets = new Array();
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
$(function () {
|
|
||||||
var searchUrl = $("input[name='discovery-json-search-url']").val();
|
|
||||||
Manager = new AjaxSolr.Manager({
|
|
||||||
solrUrl: searchUrl
|
|
||||||
});
|
|
||||||
|
|
||||||
//Retrieve our filterSelect, which contains all the types to be sorted on
|
|
||||||
var filterSelect = $("select[id='aspect_discovery_SimpleSearch_field_filtertype']");
|
|
||||||
//Get our filters
|
|
||||||
/*
|
|
||||||
var filterOptions = filterSelect.find('option');
|
|
||||||
//Get all the
|
|
||||||
for (var index = 1; index < filterOptions.length; index++){
|
|
||||||
//We skip the first one (for the moment)
|
|
||||||
defaultFacets[index - 1] = filterOptions[index].value;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//As a default facet we use the selected value
|
|
||||||
defaultFacets[0] = filterSelect.find('option:selected').val();
|
|
||||||
|
|
||||||
var widget = Manager.addWidget(new AjaxSolr.AutocompleteWidget({
|
|
||||||
id: 'text',
|
|
||||||
target: 'li#aspect_discovery_SimpleSearch_item_search-filter-list',
|
|
||||||
field: 'allText',
|
|
||||||
fields: defaultFacets
|
|
||||||
}));
|
|
||||||
|
|
||||||
Manager.init();
|
|
||||||
|
|
||||||
query = $('input#aspect_discovery_SimpleSearch_field_query').val();
|
|
||||||
if(query == '')
|
|
||||||
query = '*:*';
|
|
||||||
|
|
||||||
Manager.store.addByValue('q', query);
|
|
||||||
//Retrieve our filter queries
|
|
||||||
var fqs = $("input[name='fq']");
|
|
||||||
for(var j = 0; j < fqs.length; j ++){
|
|
||||||
Manager.store.addByValue('fq', $(fqs[j]).val());
|
|
||||||
}
|
|
||||||
Manager.store.addByValue('facet.sort', 'count');
|
|
||||||
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
facet: true,
|
|
||||||
'facet.field': defaultFacets,
|
|
||||||
'facet.limit': 20,
|
|
||||||
'facet.mincount': 1,
|
|
||||||
'f.topics.facet.limit': 50,
|
|
||||||
'json.nl': 'map'
|
|
||||||
};
|
|
||||||
for (var name in params) {
|
|
||||||
Manager.store.addByValue(name, params[name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Attempt to add our scope !
|
|
||||||
var scope = $("input[name='discovery-json-scope']").val();
|
|
||||||
if(scope != undefined){
|
|
||||||
Manager.store.addByValue("scope", scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Manager.doRequest();
|
|
||||||
|
|
||||||
filterSelect.change(function() {
|
|
||||||
// TODO: this is dirty, but with lack of time the best I could do
|
|
||||||
var oldInput = $('input#aspect_discovery_SimpleSearch_field_filter');
|
|
||||||
var newInput = oldInput.clone(false);
|
|
||||||
|
|
||||||
// newInput.val(oldInput.val());
|
|
||||||
newInput.appendTo(oldInput.parent());
|
|
||||||
oldInput.remove();
|
|
||||||
|
|
||||||
//Remove any results lists we may still have standing
|
|
||||||
$("div#discovery_autocomplete_div").remove();
|
|
||||||
//Put the field in which our facet is going to facet into the widget
|
|
||||||
var facetFields;
|
|
||||||
|
|
||||||
if($(this).val() != '*'){
|
|
||||||
var facetVal = $(this).val();
|
|
||||||
//Only facet on autocomplete fields
|
|
||||||
// if(!facetVal.match(/.year$/)){
|
|
||||||
// facetVal += '_ac';
|
|
||||||
// }
|
|
||||||
facetFields = [facetVal];
|
|
||||||
} else {
|
|
||||||
facetFields = defaultFacets;
|
|
||||||
}
|
|
||||||
|
|
||||||
Manager.widgets.text.fields = facetFields;
|
|
||||||
Manager.initialized = false;
|
|
||||||
|
|
||||||
Manager.init();
|
|
||||||
//TODO: does this need to happen twice ?
|
|
||||||
Manager.store.addByValue('q', query);
|
|
||||||
//Retrieve our filter queries
|
|
||||||
var fqs = $("input[name='fq']");
|
|
||||||
for(var j = 0; j < fqs.length; j ++){
|
|
||||||
Manager.store.addByValue('fq', $(fqs[j]).val());
|
|
||||||
}
|
|
||||||
Manager.store.addByValue('facet.sort', 'count');
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
facet: true,
|
|
||||||
'facet.field': facetFields,
|
|
||||||
'facet.limit': 20,
|
|
||||||
'facet.mincount': 1,
|
|
||||||
'f.topics.facet.limit': 50,
|
|
||||||
'json.nl': 'map'
|
|
||||||
};
|
|
||||||
for (var name in params) {
|
|
||||||
Manager.store.addByValue(name, params[name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Attempt to add our scope !
|
|
||||||
var scope = $("input[name='discovery-json-scope']").val();
|
|
||||||
if(scope != undefined){
|
|
||||||
Manager.store.addByValue("scope", scope);
|
|
||||||
}
|
|
||||||
Manager.doRequest();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
@@ -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/
|
|
||||||
*/
|
|
||||||
(function ($) {
|
|
||||||
|
|
||||||
AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractFacetWidget.extend({
|
|
||||||
|
|
||||||
afterRequest: function () {
|
|
||||||
|
|
||||||
$(this.target).find("input[type='text']").val('');
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var callback = function (response) {
|
|
||||||
var list = [];
|
|
||||||
for (var field in response.facet_counts.facet_fields) {
|
|
||||||
for (var facet in response.facet_counts.facet_fields[field]) {
|
|
||||||
list.push({
|
|
||||||
field: field,
|
|
||||||
value: facet,
|
|
||||||
text: facet + ' (' + response.facet_counts.facet_fields[field][facet] + ')'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.requestSent = false;
|
|
||||||
$(self.target).find("input[type='text']").autocomplete(list, {
|
|
||||||
formatItem: function(facet) {
|
|
||||||
return facet.text;
|
|
||||||
}
|
|
||||||
}).result(function(e, facet) {
|
|
||||||
$(this).val(facet.value);
|
|
||||||
// self.requestSent = true;
|
|
||||||
// if (self.manager.store.addByValue('fq', facet.field + ':' + facet.value)) {
|
|
||||||
// self.manager.doRequest(0);
|
|
||||||
// }
|
|
||||||
}).bind('keydown', function(e) {
|
|
||||||
if (self.requestSent === false && e.which == 13) {
|
|
||||||
var value = $(this).val();
|
|
||||||
if (value && self.add(value)) {
|
|
||||||
self.manager.doRequest(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}; // end callback
|
|
||||||
|
|
||||||
var params = [ 'q=' + query + '&facet=true&facet.limit=-1&facet.sort=count&facet.mincount=1&json.nl=map' ];
|
|
||||||
for (var i = 0; i < this.fields.length; i++) {
|
|
||||||
params.push('facet.field=' + this.fields[i]);
|
|
||||||
}
|
|
||||||
var fqs = $("input[name='fq']");
|
|
||||||
for(var j = 0; j < fqs.length; j ++){
|
|
||||||
params.push('fq=' + encodeURIComponent($(fqs[j]).val()));
|
|
||||||
}
|
|
||||||
//Attempt to add our scope !
|
|
||||||
var scope = $("input[name='discovery-json-scope']").val();
|
|
||||||
if(scope != undefined){
|
|
||||||
params.push("scope=" + scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// jQuery.getJSON(this.manager.solrUrl + 'select?' + params.join('&') + '&wt=json&json.wrf=?', {}, callback);
|
|
||||||
jQuery.getJSON(this.manager.solrUrl + '?' + params.join('&') + '&wt=json&json.wrf=?', {}, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery);
|
|
@@ -1,20 +0,0 @@
|
|||||||
Copyright (c) 2010 John Resig, http://jquery.com/
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,799 +0,0 @@
|
|||||||
;(function($) {
|
|
||||||
|
|
||||||
$.fn.extend({
|
|
||||||
autocomplete: function(urlOrData, options) {
|
|
||||||
var isUrl = typeof urlOrData == "string";
|
|
||||||
options = $.extend({}, $.Autocompleter.defaults, {
|
|
||||||
url: isUrl ? urlOrData : null,
|
|
||||||
data: isUrl ? null : urlOrData,
|
|
||||||
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
|
|
||||||
max: options && !options.scroll ? 10 : 150
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
// if highlight is set to false, replace it with a do-nothing function
|
|
||||||
options.highlight = options.highlight || function(value) { return value; };
|
|
||||||
|
|
||||||
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
|
|
||||||
options.formatMatch = options.formatMatch || options.formatItem;
|
|
||||||
|
|
||||||
return this.each(function() {
|
|
||||||
new $.Autocompleter(this, options);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
result: function(handler) {
|
|
||||||
return this.bind("result", handler);
|
|
||||||
},
|
|
||||||
search: function(handler) {
|
|
||||||
return this.trigger("search", [handler]);
|
|
||||||
},
|
|
||||||
flushCache: function() {
|
|
||||||
return this.trigger("flushCache");
|
|
||||||
},
|
|
||||||
setOptions: function(options){
|
|
||||||
return this.trigger("setOptions", [options]);
|
|
||||||
},
|
|
||||||
unautocomplete: function() {
|
|
||||||
return this.trigger("unautocomplete");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.Autocompleter = function(input, options) {
|
|
||||||
|
|
||||||
var KEY = {
|
|
||||||
UP: 38,
|
|
||||||
DOWN: 40,
|
|
||||||
DEL: 46,
|
|
||||||
TAB: 9,
|
|
||||||
RETURN: 13,
|
|
||||||
ESC: 27,
|
|
||||||
COMMA: 188,
|
|
||||||
PAGEUP: 33,
|
|
||||||
PAGEDOWN: 34,
|
|
||||||
BACKSPACE: 8
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create $ object for input element
|
|
||||||
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
|
|
||||||
|
|
||||||
var timeout;
|
|
||||||
var previousValue = "";
|
|
||||||
var cache = $.Autocompleter.Cache(options);
|
|
||||||
var hasFocus = 0;
|
|
||||||
var lastKeyPressCode;
|
|
||||||
var config = {
|
|
||||||
mouseDownOnSelect: false
|
|
||||||
};
|
|
||||||
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
|
|
||||||
|
|
||||||
var blockSubmit;
|
|
||||||
|
|
||||||
// prevent form submit in opera when selecting with return key
|
|
||||||
$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
|
|
||||||
if (blockSubmit) {
|
|
||||||
blockSubmit = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
|
|
||||||
$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
|
|
||||||
// a keypress means the input has focus
|
|
||||||
// avoids issue where input had focus before the autocomplete was applied
|
|
||||||
hasFocus = 1;
|
|
||||||
// track last key pressed
|
|
||||||
lastKeyPressCode = event.keyCode;
|
|
||||||
switch(event.keyCode) {
|
|
||||||
|
|
||||||
case KEY.UP:
|
|
||||||
event.preventDefault();
|
|
||||||
if ( select.visible() ) {
|
|
||||||
select.prev();
|
|
||||||
} else {
|
|
||||||
onChange(0, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY.DOWN:
|
|
||||||
event.preventDefault();
|
|
||||||
if ( select.visible() ) {
|
|
||||||
select.next();
|
|
||||||
} else {
|
|
||||||
onChange(0, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY.PAGEUP:
|
|
||||||
event.preventDefault();
|
|
||||||
if ( select.visible() ) {
|
|
||||||
select.pageUp();
|
|
||||||
} else {
|
|
||||||
onChange(0, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY.PAGEDOWN:
|
|
||||||
event.preventDefault();
|
|
||||||
if ( select.visible() ) {
|
|
||||||
select.pageDown();
|
|
||||||
} else {
|
|
||||||
onChange(0, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// matches also semicolon
|
|
||||||
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
|
|
||||||
case KEY.TAB:
|
|
||||||
case KEY.RETURN:
|
|
||||||
if( selectCurrent() ) {
|
|
||||||
// stop default to prevent a form submit, Opera needs special handling
|
|
||||||
event.preventDefault();
|
|
||||||
blockSubmit = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY.ESC:
|
|
||||||
select.hide();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(onChange, options.delay);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}).focus(function(){
|
|
||||||
// track whether the field has focus, we shouldn't process any
|
|
||||||
// results if the field no longer has focus
|
|
||||||
hasFocus++;
|
|
||||||
}).blur(function() {
|
|
||||||
hasFocus = 0;
|
|
||||||
if (!config.mouseDownOnSelect) {
|
|
||||||
hideResults();
|
|
||||||
}
|
|
||||||
}).click(function() {
|
|
||||||
// show select when clicking in a focused field
|
|
||||||
if ( hasFocus++ > 1 && !select.visible() ) {
|
|
||||||
onChange(0, true);
|
|
||||||
}
|
|
||||||
}).bind("search", function() {
|
|
||||||
// TODO why not just specifying both arguments?
|
|
||||||
var fn = (arguments.length > 1) ? arguments[1] : null;
|
|
||||||
function findValueCallback(q, data) {
|
|
||||||
var result;
|
|
||||||
if( data && data.length ) {
|
|
||||||
for (var i=0; i < data.length; i++) {
|
|
||||||
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
|
|
||||||
result = data[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( typeof fn == "function" ) fn(result);
|
|
||||||
else $input.trigger("result", result && [result.data, result.value]);
|
|
||||||
}
|
|
||||||
$.each(trimWords($input.val()), function(i, value) {
|
|
||||||
request(value, findValueCallback, findValueCallback);
|
|
||||||
});
|
|
||||||
}).bind("flushCache", function() {
|
|
||||||
cache.flush();
|
|
||||||
}).bind("setOptions", function() {
|
|
||||||
$.extend(options, arguments[1]);
|
|
||||||
// if we've updated the data, repopulate
|
|
||||||
if ( "data" in arguments[1] )
|
|
||||||
cache.populate();
|
|
||||||
}).bind("unautocomplete", function() {
|
|
||||||
select.unbind();
|
|
||||||
$input.unbind();
|
|
||||||
$(input.form).unbind(".autocomplete");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function selectCurrent() {
|
|
||||||
var selected = select.selected();
|
|
||||||
if( !selected )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var v = selected.result;
|
|
||||||
previousValue = v;
|
|
||||||
|
|
||||||
if ( options.multiple ) {
|
|
||||||
var words = trimWords($input.val());
|
|
||||||
if ( words.length > 1 ) {
|
|
||||||
var separator = options.multipleSeparator.length;
|
|
||||||
var cursorAt = $(input).selection().start;
|
|
||||||
var wordAt, progress = 0;
|
|
||||||
$.each(words, function(i, word) {
|
|
||||||
progress += word.length;
|
|
||||||
if (cursorAt <= progress) {
|
|
||||||
wordAt = i;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
progress += separator;
|
|
||||||
});
|
|
||||||
words[wordAt] = v;
|
|
||||||
// TODO this should set the cursor to the right position, but it gets overriden somewhere
|
|
||||||
//$.Autocompleter.Selection(input, progress + separator, progress + separator);
|
|
||||||
v = words.join( options.multipleSeparator );
|
|
||||||
}
|
|
||||||
v += options.multipleSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
$input.val(v);
|
|
||||||
hideResultsNow();
|
|
||||||
$input.trigger("result", [selected.data, selected.value]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange(crap, skipPrevCheck) {
|
|
||||||
if( lastKeyPressCode == KEY.DEL ) {
|
|
||||||
select.hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentValue = $input.val();
|
|
||||||
|
|
||||||
if ( !skipPrevCheck && currentValue == previousValue )
|
|
||||||
return;
|
|
||||||
|
|
||||||
previousValue = currentValue;
|
|
||||||
|
|
||||||
currentValue = lastWord(currentValue);
|
|
||||||
if ( currentValue.length >= options.minChars) {
|
|
||||||
$input.addClass(options.loadingClass);
|
|
||||||
if (!options.matchCase)
|
|
||||||
currentValue = currentValue.toLowerCase();
|
|
||||||
request(currentValue, receiveData, hideResultsNow);
|
|
||||||
} else {
|
|
||||||
stopLoading();
|
|
||||||
select.hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function trimWords(value) {
|
|
||||||
if (!value)
|
|
||||||
return [""];
|
|
||||||
if (!options.multiple)
|
|
||||||
return [$.trim(value)];
|
|
||||||
return $.map(value.split(options.multipleSeparator), function(word) {
|
|
||||||
return $.trim(value).length ? $.trim(word) : null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function lastWord(value) {
|
|
||||||
if ( !options.multiple )
|
|
||||||
return value;
|
|
||||||
var words = trimWords(value);
|
|
||||||
if (words.length == 1)
|
|
||||||
return words[0];
|
|
||||||
var cursorAt = $(input).selection().start;
|
|
||||||
if (cursorAt == value.length) {
|
|
||||||
words = trimWords(value)
|
|
||||||
} else {
|
|
||||||
words = trimWords(value.replace(value.substring(cursorAt), ""));
|
|
||||||
}
|
|
||||||
return words[words.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// fills in the input box w/the first match (assumed to be the best match)
|
|
||||||
// q: the term entered
|
|
||||||
// sValue: the first matching result
|
|
||||||
function autoFill(q, sValue){
|
|
||||||
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
|
|
||||||
// if the last user key pressed was backspace, don't autofill
|
|
||||||
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
|
|
||||||
// fill in the value (keep the case the user has typed)
|
|
||||||
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
|
|
||||||
// select the portion of the value not typed by the user (so the next character will erase)
|
|
||||||
$(input).selection(previousValue.length, previousValue.length + sValue.length);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function hideResults() {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(hideResultsNow, 200);
|
|
||||||
};
|
|
||||||
|
|
||||||
function hideResultsNow() {
|
|
||||||
var wasVisible = select.visible();
|
|
||||||
select.hide();
|
|
||||||
clearTimeout(timeout);
|
|
||||||
stopLoading();
|
|
||||||
if (options.mustMatch) {
|
|
||||||
// call search and run callback
|
|
||||||
$input.search(
|
|
||||||
function (result){
|
|
||||||
// if no value found, clear the input box
|
|
||||||
if( !result ) {
|
|
||||||
if (options.multiple) {
|
|
||||||
var words = trimWords($input.val()).slice(0, -1);
|
|
||||||
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$input.val( "" );
|
|
||||||
$input.trigger("result", null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function receiveData(q, data) {
|
|
||||||
if ( data && data.length && hasFocus ) {
|
|
||||||
stopLoading();
|
|
||||||
select.display(data, q);
|
|
||||||
autoFill(q, data[0].value);
|
|
||||||
select.show();
|
|
||||||
} else {
|
|
||||||
hideResultsNow();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function request(term, success, failure) {
|
|
||||||
if (!options.matchCase)
|
|
||||||
term = term.toLowerCase();
|
|
||||||
var data = cache.load(term);
|
|
||||||
// receive the cached data
|
|
||||||
if (data && data.length) {
|
|
||||||
success(term, data);
|
|
||||||
// if an AJAX url has been supplied, try loading the data now
|
|
||||||
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
|
|
||||||
|
|
||||||
var extraParams = {
|
|
||||||
timestamp: +new Date()
|
|
||||||
};
|
|
||||||
$.each(options.extraParams, function(key, param) {
|
|
||||||
extraParams[key] = typeof param == "function" ? param() : param;
|
|
||||||
});
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
// try to leverage ajaxQueue plugin to abort previous requests
|
|
||||||
mode: "abort",
|
|
||||||
// limit abortion to this input
|
|
||||||
port: "autocomplete" + input.name,
|
|
||||||
dataType: options.dataType,
|
|
||||||
url: options.url,
|
|
||||||
data: $.extend({
|
|
||||||
q: lastWord(term),
|
|
||||||
limit: options.max
|
|
||||||
}, extraParams),
|
|
||||||
success: function(data) {
|
|
||||||
var parsed = options.parse && options.parse(data) || parse(data);
|
|
||||||
cache.add(term, parsed);
|
|
||||||
success(term, parsed);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
|
|
||||||
select.emptyList();
|
|
||||||
failure(term);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function parse(data) {
|
|
||||||
var parsed = [];
|
|
||||||
var rows = data.split("\n");
|
|
||||||
for (var i=0; i < rows.length; i++) {
|
|
||||||
var row = $.trim(rows[i]);
|
|
||||||
if (row) {
|
|
||||||
row = row.split("|");
|
|
||||||
parsed[parsed.length] = {
|
|
||||||
data: row,
|
|
||||||
value: row[0],
|
|
||||||
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parsed;
|
|
||||||
};
|
|
||||||
|
|
||||||
function stopLoading() {
|
|
||||||
$input.removeClass(options.loadingClass);
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$.Autocompleter.defaults = {
|
|
||||||
inputClass: "ac_input",
|
|
||||||
resultId: "discovery_autocomplete_div",
|
|
||||||
resultsClass: "ac_results",
|
|
||||||
loadingClass: "ac_loading",
|
|
||||||
minChars: 1,
|
|
||||||
delay: 400,
|
|
||||||
matchCase: false,
|
|
||||||
matchSubset: true,
|
|
||||||
matchContains: false,
|
|
||||||
cacheLength: 10,
|
|
||||||
max: 100,
|
|
||||||
mustMatch: false,
|
|
||||||
extraParams: {},
|
|
||||||
selectFirst: true,
|
|
||||||
formatItem: function(row) { return row[0]; },
|
|
||||||
formatMatch: null,
|
|
||||||
autoFill: false,
|
|
||||||
width: 0,
|
|
||||||
multiple: false,
|
|
||||||
multipleSeparator: ", ",
|
|
||||||
highlight: function(value, term) {
|
|
||||||
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
|
|
||||||
},
|
|
||||||
scroll: true,
|
|
||||||
scrollHeight: 180
|
|
||||||
};
|
|
||||||
|
|
||||||
$.Autocompleter.Cache = function(options) {
|
|
||||||
|
|
||||||
var data = {};
|
|
||||||
var length = 0;
|
|
||||||
|
|
||||||
function matchSubset(s, sub) {
|
|
||||||
if (!options.matchCase)
|
|
||||||
s = s.toLowerCase();
|
|
||||||
var i = s.indexOf(sub);
|
|
||||||
if (options.matchContains == "word"){
|
|
||||||
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
|
|
||||||
}
|
|
||||||
if (i == -1) return false;
|
|
||||||
return i == 0 || options.matchContains;
|
|
||||||
};
|
|
||||||
|
|
||||||
function add(q, value) {
|
|
||||||
if (length > options.cacheLength){
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
if (!data[q]){
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
data[q] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function populate(){
|
|
||||||
if( !options.data ) return false;
|
|
||||||
// track the matches
|
|
||||||
var stMatchSets = {},
|
|
||||||
nullData = 0;
|
|
||||||
|
|
||||||
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
|
|
||||||
if( !options.url ) options.cacheLength = 1;
|
|
||||||
|
|
||||||
// track all options for minChars = 0
|
|
||||||
stMatchSets[""] = [];
|
|
||||||
|
|
||||||
// loop through the array and create a lookup structure
|
|
||||||
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
|
|
||||||
var rawValue = options.data[i];
|
|
||||||
// if rawValue is a string, make an array otherwise just reference the array
|
|
||||||
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
|
|
||||||
|
|
||||||
var value = options.formatMatch(rawValue, i+1, options.data.length);
|
|
||||||
if ( value === false )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var firstChar = value.charAt(0).toLowerCase();
|
|
||||||
// if no lookup array for this character exists, look it up now
|
|
||||||
if( !stMatchSets[firstChar] )
|
|
||||||
stMatchSets[firstChar] = [];
|
|
||||||
|
|
||||||
// if the match is a string
|
|
||||||
var row = {
|
|
||||||
value: value,
|
|
||||||
data: rawValue,
|
|
||||||
result: options.formatResult && options.formatResult(rawValue) || value
|
|
||||||
};
|
|
||||||
|
|
||||||
// push the current match into the set list
|
|
||||||
stMatchSets[firstChar].push(row);
|
|
||||||
|
|
||||||
// keep track of minChars zero items
|
|
||||||
if ( nullData++ < options.max ) {
|
|
||||||
stMatchSets[""].push(row);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// add the data items to the cache
|
|
||||||
$.each(stMatchSets, function(i, value) {
|
|
||||||
// increase the cache size
|
|
||||||
options.cacheLength++;
|
|
||||||
// add to the cache
|
|
||||||
add(i, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate any existing data
|
|
||||||
setTimeout(populate, 25);
|
|
||||||
|
|
||||||
function flush(){
|
|
||||||
data = {};
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
flush: flush,
|
|
||||||
add: add,
|
|
||||||
populate: populate,
|
|
||||||
load: function(q) {
|
|
||||||
if (!options.cacheLength || !length)
|
|
||||||
return null;
|
|
||||||
/*
|
|
||||||
* if dealing w/local data and matchContains than we must make sure
|
|
||||||
* to loop through all the data collections looking for matches
|
|
||||||
*/
|
|
||||||
if( !options.url && options.matchContains ){
|
|
||||||
// track all matches
|
|
||||||
var csub = [];
|
|
||||||
// loop through all the data grids for matches
|
|
||||||
for( var k in data ){
|
|
||||||
// don't search through the stMatchSets[""] (minChars: 0) cache
|
|
||||||
// this prevents duplicates
|
|
||||||
if( k.length > 0 ){
|
|
||||||
var c = data[k];
|
|
||||||
$.each(c, function(i, x) {
|
|
||||||
// if we've got a match, add it to the array
|
|
||||||
if (matchSubset(x.value, q)) {
|
|
||||||
csub.push(x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return csub;
|
|
||||||
} else
|
|
||||||
// if the exact item exists, use it
|
|
||||||
if (data[q]){
|
|
||||||
return data[q];
|
|
||||||
} else
|
|
||||||
if (options.matchSubset) {
|
|
||||||
for (var i = q.length - 1; i >= options.minChars; i--) {
|
|
||||||
var c = data[q.substr(0, i)];
|
|
||||||
if (c) {
|
|
||||||
var csub = [];
|
|
||||||
$.each(c, function(i, x) {
|
|
||||||
if (matchSubset(x.value, q)) {
|
|
||||||
csub[csub.length] = x;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return csub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.Autocompleter.Select = function (options, input, select, config) {
|
|
||||||
var CLASSES = {
|
|
||||||
ACTIVE: "ac_over"
|
|
||||||
};
|
|
||||||
|
|
||||||
var listItems,
|
|
||||||
active = -1,
|
|
||||||
data,
|
|
||||||
term = "",
|
|
||||||
needsInit = true,
|
|
||||||
element,
|
|
||||||
list;
|
|
||||||
|
|
||||||
// Create results
|
|
||||||
function init() {
|
|
||||||
if (!needsInit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
element = $("<div/>")
|
|
||||||
.hide()
|
|
||||||
.addClass(options.resultsClass)
|
|
||||||
.attr("id", options.resultId)
|
|
||||||
.css("position", "absolute")
|
|
||||||
.appendTo(document.body);
|
|
||||||
|
|
||||||
list = $("<ul/>").appendTo(element).mouseover( function(event) {
|
|
||||||
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
|
|
||||||
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
|
|
||||||
$(target(event)).addClass(CLASSES.ACTIVE);
|
|
||||||
}
|
|
||||||
}).click(function(event) {
|
|
||||||
$(target(event)).addClass(CLASSES.ACTIVE);
|
|
||||||
select();
|
|
||||||
// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
|
|
||||||
input.focus();
|
|
||||||
return false;
|
|
||||||
}).mousedown(function() {
|
|
||||||
config.mouseDownOnSelect = true;
|
|
||||||
}).mouseup(function() {
|
|
||||||
config.mouseDownOnSelect = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
if( options.width > 0 )
|
|
||||||
element.css("width", options.width);
|
|
||||||
|
|
||||||
needsInit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function target(event) {
|
|
||||||
var element = event.target;
|
|
||||||
while(element && element.tagName != "LI")
|
|
||||||
element = element.parentNode;
|
|
||||||
// more fun with IE, sometimes event.target is empty, just ignore it then
|
|
||||||
if(!element)
|
|
||||||
return [];
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveSelect(step) {
|
|
||||||
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
|
|
||||||
movePosition(step);
|
|
||||||
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
|
|
||||||
if(options.scroll) {
|
|
||||||
var offset = 0;
|
|
||||||
listItems.slice(0, active).each(function() {
|
|
||||||
offset += this.offsetHeight;
|
|
||||||
});
|
|
||||||
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
|
|
||||||
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
|
|
||||||
} else if(offset < list.scrollTop()) {
|
|
||||||
list.scrollTop(offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function movePosition(step) {
|
|
||||||
active += step;
|
|
||||||
if (active < 0) {
|
|
||||||
active = listItems.size() - 1;
|
|
||||||
} else if (active >= listItems.size()) {
|
|
||||||
active = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function limitNumberOfItems(available) {
|
|
||||||
return options.max && options.max < available
|
|
||||||
? options.max
|
|
||||||
: available;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillList() {
|
|
||||||
list.empty();
|
|
||||||
var max = limitNumberOfItems(data.length);
|
|
||||||
for (var i=0; i < max; i++) {
|
|
||||||
if (!data[i])
|
|
||||||
continue;
|
|
||||||
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
|
|
||||||
if ( formatted === false )
|
|
||||||
continue;
|
|
||||||
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
|
|
||||||
$.data(li, "ac_data", data[i]);
|
|
||||||
}
|
|
||||||
listItems = list.find("li");
|
|
||||||
if ( options.selectFirst ) {
|
|
||||||
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
|
|
||||||
active = 0;
|
|
||||||
}
|
|
||||||
// apply bgiframe if available
|
|
||||||
if ( $.fn.bgiframe )
|
|
||||||
list.bgiframe();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
display: function(d, q) {
|
|
||||||
init();
|
|
||||||
data = d;
|
|
||||||
term = q;
|
|
||||||
fillList();
|
|
||||||
},
|
|
||||||
next: function() {
|
|
||||||
moveSelect(1);
|
|
||||||
},
|
|
||||||
prev: function() {
|
|
||||||
moveSelect(-1);
|
|
||||||
},
|
|
||||||
pageUp: function() {
|
|
||||||
if (active != 0 && active - 8 < 0) {
|
|
||||||
moveSelect( -active );
|
|
||||||
} else {
|
|
||||||
moveSelect(-8);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pageDown: function() {
|
|
||||||
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
|
|
||||||
moveSelect( listItems.size() - 1 - active );
|
|
||||||
} else {
|
|
||||||
moveSelect(8);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hide: function() {
|
|
||||||
element && element.hide();
|
|
||||||
listItems && listItems.removeClass(CLASSES.ACTIVE);
|
|
||||||
active = -1;
|
|
||||||
},
|
|
||||||
visible : function() {
|
|
||||||
return element && element.is(":visible");
|
|
||||||
},
|
|
||||||
current: function() {
|
|
||||||
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
|
|
||||||
},
|
|
||||||
show: function() {
|
|
||||||
var offset = $(input).offset();
|
|
||||||
element.css({
|
|
||||||
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
|
|
||||||
top: offset.top + input.offsetHeight,
|
|
||||||
left: offset.left
|
|
||||||
}).show();
|
|
||||||
if(options.scroll) {
|
|
||||||
list.scrollTop(0);
|
|
||||||
list.css({
|
|
||||||
maxHeight: options.scrollHeight,
|
|
||||||
overflow: 'auto'
|
|
||||||
});
|
|
||||||
|
|
||||||
if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
|
|
||||||
var listHeight = 0;
|
|
||||||
listItems.each(function() {
|
|
||||||
listHeight += this.offsetHeight;
|
|
||||||
});
|
|
||||||
var scrollbarsVisible = listHeight > options.scrollHeight;
|
|
||||||
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
|
|
||||||
if (!scrollbarsVisible) {
|
|
||||||
// IE doesn't recalculate width when scrollbar disappears
|
|
||||||
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selected: function() {
|
|
||||||
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
|
|
||||||
return selected && selected.length && $.data(selected[0], "ac_data");
|
|
||||||
},
|
|
||||||
emptyList: function (){
|
|
||||||
list && list.empty();
|
|
||||||
},
|
|
||||||
unbind: function() {
|
|
||||||
element && element.remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.selection = function(start, end) {
|
|
||||||
if (start !== undefined) {
|
|
||||||
return this.each(function() {
|
|
||||||
if( this.createTextRange ){
|
|
||||||
var selRange = this.createTextRange();
|
|
||||||
if (end === undefined || start == end) {
|
|
||||||
selRange.move("character", start);
|
|
||||||
selRange.select();
|
|
||||||
} else {
|
|
||||||
selRange.collapse(true);
|
|
||||||
selRange.moveStart("character", start);
|
|
||||||
selRange.moveEnd("character", end);
|
|
||||||
selRange.select();
|
|
||||||
}
|
|
||||||
} else if( this.setSelectionRange ){
|
|
||||||
this.setSelectionRange(start, end);
|
|
||||||
} else if( this.selectionStart ){
|
|
||||||
this.selectionStart = start;
|
|
||||||
this.selectionEnd = end;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var field = this[0];
|
|
||||||
if ( field.createTextRange ) {
|
|
||||||
var range = document.selection.createRange(),
|
|
||||||
orig = field.value,
|
|
||||||
teststring = "<->",
|
|
||||||
textLength = range.text.length;
|
|
||||||
range.text = teststring;
|
|
||||||
var caretAt = field.value.indexOf(teststring);
|
|
||||||
field.value = orig;
|
|
||||||
this.selection(caretAt, caretAt + textLength);
|
|
||||||
return {
|
|
||||||
start: caretAt,
|
|
||||||
end: caretAt + textLength
|
|
||||||
}
|
|
||||||
} else if( field.selectionStart !== undefined ){
|
|
||||||
return {
|
|
||||||
start: field.selectionStart,
|
|
||||||
end: field.selectionEnd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery);
|
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.0 KiB |
@@ -288,6 +288,8 @@ div.pagination {
|
|||||||
div.pagination-masked {
|
div.pagination-masked {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 10px 20px 10px 20px;
|
margin: 10px 20px 10px 20px;
|
||||||
|
/*Property below is required for IE7 when using discovery*/
|
||||||
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.previous-page-link {
|
a.previous-page-link {
|
||||||
@@ -886,3 +888,81 @@ margin: 2px 2px 0px 2px;
|
|||||||
/* border: 1px solid rgb(240, 240, 210); */
|
/* border: 1px solid rgb(240, 240, 210); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start discovery layout DSpace 3.x*/
|
||||||
|
div.discoverySearchBox label{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input#aspect_discovery_SimpleSearch_field_query{
|
||||||
|
width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.search-icon{
|
||||||
|
background-image: url('../images/search_icon_000000_20x20.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
text-indent: -1000px;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
line-height: 0;
|
||||||
|
background-color: #F3F3F3;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.controls-gear-wrapper{
|
||||||
|
float: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gear-icon{
|
||||||
|
background-image: url('../images/gear_000000_25x25.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option-selected{
|
||||||
|
background: url('../images/check_606060_15x15.png') no-repeat 3px center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control {
|
||||||
|
width: 30px;
|
||||||
|
margin-left: 5px;
|
||||||
|
text-indent: -1000px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 22px;
|
||||||
|
float: left;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
display:block;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-remove{
|
||||||
|
margin-left: 15px;
|
||||||
|
background-image: url('../images/remove_icon_000000_16x16.png');
|
||||||
|
background-color: #F3F3F3;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-add{
|
||||||
|
background-image: url('../images/plus_icon_000000_16x16.png');
|
||||||
|
background-color: #F3F3F3;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection{
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#aspect_discovery_SimpleSearch_div_search a.previous-page-link {
|
||||||
|
left: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End discovery layout DSpace 3.x*/
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.0 KiB |
@@ -816,52 +816,73 @@ td select.ds-select-field {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search {
|
form.search,
|
||||||
|
div.discoverySearchBox
|
||||||
|
{
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
border: 1px solid #ebebeb;
|
border: 1px solid #ebebeb;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search label {
|
form.search label,
|
||||||
|
div.discoverySearchBox label
|
||||||
|
{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search p.ds-paragraph.button-list {
|
form.search p.ds-paragraph.button-list,
|
||||||
|
div.discoverySearchBox p.ds-paragraph.button-list
|
||||||
|
{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search fieldset {
|
form.search fieldset,
|
||||||
|
div.discoverySearchBox fieldset {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search .ds-form-item {
|
form.search .ds-form-item,
|
||||||
|
div.discoverySearchBox .ds-form-item
|
||||||
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search .ds-form-item select{
|
form.search .ds-form-item select,
|
||||||
|
div.discoverySearchBox .ds-form-item select
|
||||||
|
{
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search label.ds-composite-component .ds-select-field{
|
form.search label.ds-composite-component .ds-select-field,
|
||||||
|
div.discoverySearchBox label.ds-composite-component .ds-select-field
|
||||||
|
{
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search .ds-form-item label {
|
form.search .ds-form-item label,
|
||||||
|
div.discoverySearchBox .ds-form-item label
|
||||||
|
{
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search .ds-form-content {
|
form.search .ds-form-content,
|
||||||
|
div.discoverySearchBox .ds-form-content
|
||||||
|
{
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search table input.ds-text-field {
|
form.search table input.ds-text-field,
|
||||||
|
div.discoverySearchBox table input.ds-text-field
|
||||||
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.search .field-help {
|
form.search .field-help,
|
||||||
|
div.discoverySearchBox .field-help
|
||||||
|
{
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1071,11 +1092,6 @@ form.discover-search-box{
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.search-filter-list,
|
|
||||||
li.used-filters-list
|
|
||||||
{
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.discover-sort-box select{
|
form.discover-sort-box select{
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
@@ -1183,3 +1199,111 @@ margin: 2px 2px 0px 2px;
|
|||||||
{
|
{
|
||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
span.highlight{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gear-icon{
|
||||||
|
background-image: url('../../images/gear_ffffff_25x25.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option-selected{
|
||||||
|
background: url('../../images/check_606060_15x15.png') no-repeat 3px center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input#aspect_discovery_SimpleSearch_field_query{
|
||||||
|
width: 565px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.search-icon{
|
||||||
|
background-image: url('../../images/search_icon_ffffff_20x20.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
text-indent: -1000px;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
display:block;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#aspect_discovery_SimpleSearch_div_search p.pagination-info{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#aspect_discovery_SimpleSearch_div_search .pagination-links{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters{
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters tr{
|
||||||
|
border-top: 1px solid #EBEBEB;
|
||||||
|
}
|
||||||
|
table.discovery-filters td{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters td.selection{
|
||||||
|
width: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters th.new-filter-header{
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.discovery-filters td.discovery-filter-input-cell {
|
||||||
|
padding-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.discovery-filters tr.apply-filter{
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters tr.apply-filter input{
|
||||||
|
width: 75px;
|
||||||
|
height: 33px;
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 108%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.discovery-filters td.filter-controls{
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control {
|
||||||
|
width: 30px;
|
||||||
|
margin-left: 5px;
|
||||||
|
text-indent: -1000px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 22px;
|
||||||
|
float: left;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
display:block;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-remove{
|
||||||
|
margin-left: 15px;
|
||||||
|
background-image: url('../../images/remove_icon_ffffff_16x16.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-add{
|
||||||
|
background-image: url('../../images/plus_icon_ffffff_16x16.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.searchTime{
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
@@ -180,9 +180,29 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<xsl:if test="parent::node()/dri:div[@n = 'masked-page-control']">
|
||||||
|
<xsl:apply-templates select="parent::node()/dri:div[@n='masked-page-control']/dri:div">
|
||||||
|
<xsl:with-param name="position" select="$position"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
</div>
|
</div>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n = 'masked-page-control']">
|
||||||
|
<!--Do not render this division, this is handled by the xsl-->
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n ='search-controls-gear']">
|
||||||
|
<xsl:param name="position"/>
|
||||||
|
<div>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class"><xsl:value-of select="$position"/></xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
@@ -44,87 +44,89 @@
|
|||||||
<xsl:template match="dri:options">
|
<xsl:template match="dri:options">
|
||||||
<div id="ds-options-wrapper">
|
<div id="ds-options-wrapper">
|
||||||
<div id="ds-options">
|
<div id="ds-options">
|
||||||
<h1 id="ds-search-option-head" class="ds-option-set-head">
|
<xsl:if test="not(contains(/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='request'][@qualifier='URI'], 'discover'))">
|
||||||
<i18n:text>xmlui.dri2xhtml.structural.search</i18n:text>
|
<h1 id="ds-search-option-head" class="ds-option-set-head">
|
||||||
</h1>
|
<i18n:text>xmlui.dri2xhtml.structural.search</i18n:text>
|
||||||
<div id="ds-search-option" class="ds-option-set">
|
</h1>
|
||||||
<!-- The form, complete with a text box and a button, all built from attributes referenced
|
<div id="ds-search-option" class="ds-option-set">
|
||||||
from under pageMeta. -->
|
<!-- The form, complete with a text box and a button, all built from attributes referenced
|
||||||
<form id="ds-search-form" method="post">
|
from under pageMeta. -->
|
||||||
<xsl:attribute name="action">
|
<form id="ds-search-form" method="post">
|
||||||
<xsl:value-of select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='contextPath']"/>
|
<xsl:attribute name="action">
|
||||||
<xsl:value-of
|
<xsl:value-of select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='contextPath']"/>
|
||||||
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']"/>
|
|
||||||
</xsl:attribute>
|
|
||||||
<fieldset>
|
|
||||||
<input class="ds-text-field " type="text">
|
|
||||||
<xsl:attribute name="name">
|
|
||||||
<xsl:value-of
|
|
||||||
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='queryField']"/>
|
|
||||||
</xsl:attribute>
|
|
||||||
</input>
|
|
||||||
<input class="ds-button-field " name="submit" type="submit" i18n:attr="value"
|
|
||||||
value="xmlui.general.go">
|
|
||||||
<xsl:attribute name="onclick">
|
|
||||||
<xsl:text>
|
|
||||||
var radio = document.getElementById("ds-search-form-scope-container");
|
|
||||||
if (radio != undefined && radio.checked)
|
|
||||||
{
|
|
||||||
var form = document.getElementById("ds-search-form");
|
|
||||||
form.action=
|
|
||||||
</xsl:text>
|
|
||||||
<xsl:text>"</xsl:text>
|
|
||||||
<xsl:value-of
|
|
||||||
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='contextPath']"/>
|
|
||||||
<xsl:text>/handle/" + radio.value + "</xsl:text>
|
|
||||||
<xsl:value-of select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']"/>
|
|
||||||
<xsl:text>" ; </xsl:text>
|
|
||||||
<xsl:text>
|
|
||||||
}
|
|
||||||
</xsl:text>
|
|
||||||
</xsl:attribute>
|
|
||||||
</input>
|
|
||||||
<xsl:if test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='container']">
|
|
||||||
<label>
|
|
||||||
<input id="ds-search-form-scope-all" type="radio" name="scope" value=""
|
|
||||||
checked="checked"/>
|
|
||||||
<i18n:text>xmlui.dri2xhtml.structural.search</i18n:text>
|
|
||||||
</label>
|
|
||||||
<br/>
|
|
||||||
<label>
|
|
||||||
<input id="ds-search-form-scope-container" type="radio" name="scope">
|
|
||||||
<xsl:attribute name="value">
|
|
||||||
<xsl:value-of
|
|
||||||
select="substring-after(/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='container'],':')"/>
|
|
||||||
</xsl:attribute>
|
|
||||||
</input>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when
|
|
||||||
test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='containerType']/text() = 'type:community'">
|
|
||||||
<i18n:text>xmlui.dri2xhtml.structural.search-in-community</i18n:text>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<i18n:text>xmlui.dri2xhtml.structural.search-in-collection</i18n:text>
|
|
||||||
</xsl:otherwise>
|
|
||||||
|
|
||||||
</xsl:choose>
|
|
||||||
</label>
|
|
||||||
</xsl:if>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
<!--Only add if the advanced search url is different from the simple search-->
|
|
||||||
<xsl:if test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='advancedURL'] != /dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']">
|
|
||||||
<!-- The "Advanced search" link, to be perched underneath the search box -->
|
|
||||||
<a>
|
|
||||||
<xsl:attribute name="href">
|
|
||||||
<xsl:value-of
|
<xsl:value-of
|
||||||
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='advancedURL']"/>
|
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']"/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
<i18n:text>xmlui.dri2xhtml.structural.search-advanced</i18n:text>
|
<fieldset>
|
||||||
</a>
|
<input class="ds-text-field " type="text">
|
||||||
</xsl:if>
|
<xsl:attribute name="name">
|
||||||
</div>
|
<xsl:value-of
|
||||||
|
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='queryField']"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</input>
|
||||||
|
<input class="ds-button-field " name="submit" type="submit" i18n:attr="value"
|
||||||
|
value="xmlui.general.go">
|
||||||
|
<xsl:attribute name="onclick">
|
||||||
|
<xsl:text>
|
||||||
|
var radio = document.getElementById("ds-search-form-scope-container");
|
||||||
|
if (radio != undefined && radio.checked)
|
||||||
|
{
|
||||||
|
var form = document.getElementById("ds-search-form");
|
||||||
|
form.action=
|
||||||
|
</xsl:text>
|
||||||
|
<xsl:text>"</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='contextPath']"/>
|
||||||
|
<xsl:text>/handle/" + radio.value + "</xsl:text>
|
||||||
|
<xsl:value-of select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']"/>
|
||||||
|
<xsl:text>" ; </xsl:text>
|
||||||
|
<xsl:text>
|
||||||
|
}
|
||||||
|
</xsl:text>
|
||||||
|
</xsl:attribute>
|
||||||
|
</input>
|
||||||
|
<xsl:if test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='container']">
|
||||||
|
<label>
|
||||||
|
<input id="ds-search-form-scope-all" type="radio" name="scope" value=""
|
||||||
|
checked="checked"/>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.structural.search</i18n:text>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
<label>
|
||||||
|
<input id="ds-search-form-scope-container" type="radio" name="scope">
|
||||||
|
<xsl:attribute name="value">
|
||||||
|
<xsl:value-of
|
||||||
|
select="substring-after(/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='container'],':')"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</input>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when
|
||||||
|
test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='focus'][@qualifier='containerType']/text() = 'type:community'">
|
||||||
|
<i18n:text>xmlui.dri2xhtml.structural.search-in-community</i18n:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.structural.search-in-collection</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
|
||||||
|
</xsl:choose>
|
||||||
|
</label>
|
||||||
|
</xsl:if>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<!--Only add if the advanced search url is different from the simple search-->
|
||||||
|
<xsl:if test="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='advancedURL'] != /dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='simpleURL']">
|
||||||
|
<!-- The "Advanced search" link, to be perched underneath the search box -->
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of
|
||||||
|
select="/dri:document/dri:meta/dri:pageMeta/dri:metadata[@element='search'][@qualifier='advancedURL']"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.structural.search-advanced</i18n:text>
|
||||||
|
</a>
|
||||||
|
</xsl:if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</xsl:if>
|
||||||
<!-- Once the search box is built, the other parts of the options are added -->
|
<!-- Once the search box is built, the other parts of the options are added -->
|
||||||
<xsl:apply-templates/>
|
<xsl:apply-templates/>
|
||||||
|
|
||||||
|
@@ -475,7 +475,7 @@
|
|||||||
</xsl:variable>
|
</xsl:variable>
|
||||||
|
|
||||||
<xsl:if test="$ccLicenseName and $ccLicenseUri and contains($ccLicenseUri, 'creativecommons')">
|
<xsl:if test="$ccLicenseName and $ccLicenseUri and contains($ccLicenseUri, 'creativecommons')">
|
||||||
<div about="{$handleUri}">
|
<div about="{$handleUri}" class="clearfix">
|
||||||
<xsl:attribute name="style">
|
<xsl:attribute name="style">
|
||||||
<xsl:text>margin:0em 2em 0em 2em; padding-bottom:0em;</xsl:text>
|
<xsl:text>margin:0em 2em 0em 2em; padding-bottom:0em;</xsl:text>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
@@ -1246,22 +1246,6 @@ span.Z3988 {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
form.discover-search-box div.ds-form-content,
|
|
||||||
form.discover-sort-box div.ds-form-content
|
|
||||||
{
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.discover-search-box div.ds-form-content input.update-filters{
|
|
||||||
margin-left: 145px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.discover-sort-box select{
|
|
||||||
margin: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display:none;
|
display:none;
|
||||||
visibility:hidden;
|
visibility:hidden;
|
||||||
@@ -1333,3 +1317,85 @@ select#aspect_submission_submit_SelectCollectionStep_field_handle
|
|||||||
{
|
{
|
||||||
max-width: 350px;
|
max-width: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Start discovery layout DSpace 3.x*/
|
||||||
|
div.discoverySearchBox
|
||||||
|
{
|
||||||
|
background-color: #FFFFF5;
|
||||||
|
border: 2px solid #F0F0D2;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.discover-search-box fieldset{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.discoverySearchBox label{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.discoverySearchBox div.ds-form-content{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
input#aspect_discovery_SimpleSearch_field_query{
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.search-icon{
|
||||||
|
background-image: url('../images/search_icon_DF6E00_20x20.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
text-indent: -1000px;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
line-height: 0;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.controls-gear-wrapper{
|
||||||
|
float: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gear-icon{
|
||||||
|
background-image: url('../images/gear_DF6E00_25x25.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection li.gear-option-selected{
|
||||||
|
background: url('../images/check_606060_15x15.png') no-repeat 3px center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control {
|
||||||
|
width: 30px;
|
||||||
|
margin-left: 5px;
|
||||||
|
text-indent: -1000px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
height: 22px;
|
||||||
|
float: left;
|
||||||
|
/*Css props below are required for IE*/
|
||||||
|
font-size: 0;
|
||||||
|
display:block;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-remove{
|
||||||
|
margin-left: 15px;
|
||||||
|
background-image: url('../images/remove_icon_DF6E00_16x16.png');
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.discovery-filters input.filter-control.filter-add{
|
||||||
|
background-image: url('../images/plus_icon_DF6E00_16x16.png');
|
||||||
|
border: 1px solid #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.gear-selection{
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
background-color: ivory;
|
||||||
|
border: 2px solid #F0F0D2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End discovery layout DSpace 3.x*/
|
@@ -42,6 +42,7 @@
|
|||||||
<xsl:import href="community-view.xsl"/>
|
<xsl:import href="community-view.xsl"/>
|
||||||
<xsl:import href="ORE.xsl"/>
|
<xsl:import href="ORE.xsl"/>
|
||||||
<xsl:import href="COinS.xsl"/>
|
<xsl:import href="COinS.xsl"/>
|
||||||
|
<xsl:import href="discovery.xsl"/>
|
||||||
|
|
||||||
<xsl:output indent="yes"/>
|
<xsl:output indent="yes"/>
|
||||||
|
|
||||||
|
@@ -0,0 +1,298 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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/
|
||||||
|
|
||||||
|
-->
|
||||||
|
<xsl:stylesheet
|
||||||
|
xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
|
||||||
|
xmlns:dri="http://di.tamu.edu/DRI/1.0/"
|
||||||
|
xmlns:mets="http://www.loc.gov/METS/"
|
||||||
|
xmlns:dim="http://www.dspace.org/xmlns/dspace/dim"
|
||||||
|
xmlns:xlink="http://www.w3.org/TR/xlink/"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:xalan="http://xml.apache.org/xalan"
|
||||||
|
xmlns:encoder="xalan://java.net.URLEncoder"
|
||||||
|
exclude-result-prefixes="xalan encoder i18n dri mets dim xlink xsl">
|
||||||
|
|
||||||
|
<xsl:output indent="yes"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
These templaes are devoted to rendering the search results for discovery.
|
||||||
|
Since discovery used hit highlighting seperate templates are required !
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template match="dri:list[@type='dsolist']" priority="2">
|
||||||
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
<ul class="ds-artifact-list">
|
||||||
|
<xsl:apply-templates select="*[not(name()='head')]" mode="dsoList"/>
|
||||||
|
</ul>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template match="dri:list/dri:list" mode="dsoList" priority="7">
|
||||||
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
<ul>
|
||||||
|
<xsl:apply-templates select="*[not(name()='head')]" mode="dsoList"/>
|
||||||
|
</ul>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template match="dri:list/dri:list/dri:list" mode="dsoList" priority="8">
|
||||||
|
<li>
|
||||||
|
<xsl:attribute name="class">
|
||||||
|
<xsl:text>ds-artifact-item clearfix </xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="position() mod 2 = 0">even</xsl:when>
|
||||||
|
<xsl:otherwise>odd</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:attribute>
|
||||||
|
<!--
|
||||||
|
Retrieve the type from our name, the name contains the following format:
|
||||||
|
{handle}:{metadata}
|
||||||
|
-->
|
||||||
|
<xsl:variable name="handle">
|
||||||
|
<xsl:value-of select="substring-before(@n, ':')"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable name="type">
|
||||||
|
<xsl:value-of select="substring-after(@n, ':')"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable name="externalMetadataURL">
|
||||||
|
<xsl:text>cocoon://metadata/handle/</xsl:text>
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
<xsl:text>/mets.xml</xsl:text>
|
||||||
|
<!-- Since this is a summary only grab the descriptive metadata, and the thumbnails -->
|
||||||
|
<xsl:text>?sections=dmdSec,fileSec&fileGrpTypes=THUMBNAIL</xsl:text>
|
||||||
|
<!-- An example of requesting a specific metadata standard (MODS and QDC crosswalks only work for items)->
|
||||||
|
<xsl:if test="@type='DSpace Item'">
|
||||||
|
<xsl:text>&dmdTypes=DC</xsl:text>
|
||||||
|
</xsl:if>-->
|
||||||
|
</xsl:variable>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$type='community'">
|
||||||
|
<xsl:call-template name="communitySummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$type='collection'">
|
||||||
|
<xsl:call-template name="collectionSummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$type='item'">
|
||||||
|
<xsl:call-template name="itemSummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
</li>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="communitySummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
<div class="artifact-title">
|
||||||
|
<a href="{$metsDoc/mets:METS/@OBJID}">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</a>
|
||||||
|
<!--Display community strengths (item counts) if they exist-->
|
||||||
|
<xsl:if test="string-length($metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]) > 0">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="collectionSummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
<div class="artifact-title">
|
||||||
|
<a href="{$metsDoc/mets:METS/@OBJID}">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!--Display collection strengths (item counts) if they exist-->
|
||||||
|
<xsl:if test="string-length($metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]) > 0">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="itemSummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Generates thumbnails (if present)-->
|
||||||
|
<xsl:apply-templates select="$metsDoc/mets:METS/mets:fileSec" mode="artifact-preview"/>
|
||||||
|
|
||||||
|
<div class="artifact-description">
|
||||||
|
<div class="artifact-title">
|
||||||
|
<xsl:element name="a">
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/@withdrawn">
|
||||||
|
<xsl:value-of select="$metsDoc/mets:METS/@OBJEDIT"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="concat($context-path, '/handle/', $handle)"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:element>
|
||||||
|
<!-- Generate COinS with empty content per spec but force Cocoon to not create a minified tag -->
|
||||||
|
<span class="Z3988">
|
||||||
|
<xsl:attribute name="title">
|
||||||
|
<xsl:for-each select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim">
|
||||||
|
<xsl:call-template name="renderCOinS"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:attribute>
|
||||||
|
 <!-- non-breaking space to force separating the end tag -->
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="artifact-info">
|
||||||
|
<span class="author">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.contributor.author'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.contributor.author'))]/dri:item">
|
||||||
|
<xsl:variable name="author">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:variable>
|
||||||
|
<span>
|
||||||
|
<!--Check authority in the mets document-->
|
||||||
|
<xsl:if test="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='contributor' and @qualifier='author' and . = $author]/@authority">
|
||||||
|
<xsl:attribute name="class">
|
||||||
|
<xsl:text>ds-dc_contributor_author-authority</xsl:text>
|
||||||
|
</xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.creator'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.creator'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.contributor'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.contributor'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-author</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</span>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="dri:list[@n=(concat($handle, ':dc.date.issued'))] or dri:list[@n=(concat($handle, ':dc.publisher'))]">
|
||||||
|
<span class="publisher-date">
|
||||||
|
<xsl:text>(</xsl:text>
|
||||||
|
<xsl:if test="dri:list[@n=(concat($handle, ':dc.publisher'))]">
|
||||||
|
<span class="publisher">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.publisher'))]/dri:item"/>
|
||||||
|
</span>
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<span class="date">
|
||||||
|
<xsl:value-of
|
||||||
|
select="substring(dri:list[@n=(concat($handle, ':dc.date.issued'))]/dri:item,1,10)"/>
|
||||||
|
</span>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
</span>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.description.abstract'))]/dri:item/dri:hi">
|
||||||
|
<div class="abstract">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.description.abstract'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:text>...</xsl:text>
|
||||||
|
<br/>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':fulltext'))]">
|
||||||
|
<div class="abstract">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':fulltext'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:text>...</xsl:text>
|
||||||
|
<br/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</div>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
@@ -169,6 +169,11 @@
|
|||||||
<i18n:text>xmlui.dri2xhtml.structural.pagination-next</i18n:text>
|
<i18n:text>xmlui.dri2xhtml.structural.pagination-next</i18n:text>
|
||||||
</a>
|
</a>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
<xsl:if test="parent::node()/dri:div[@n = 'masked-page-control']">
|
||||||
|
<xsl:apply-templates select="parent::node()/dri:div[@n='masked-page-control']/dri:div">
|
||||||
|
<xsl:with-param name="position" select="$position"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
</div>
|
</div>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
@@ -245,4 +250,19 @@
|
|||||||
<!-- The general "catch-all" template for attributes matched, but not handled above -->
|
<!-- The general "catch-all" template for attributes matched, but not handled above -->
|
||||||
<xsl:template match="@*"></xsl:template>
|
<xsl:template match="@*"></xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n = 'masked-page-control']">
|
||||||
|
<!--Do not render this division, this is handled by the xsl-->
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n ='search-controls-gear']">
|
||||||
|
<xsl:param name="position"/>
|
||||||
|
<div>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class"><xsl:value-of select="$position"/></xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
@@ -482,10 +482,13 @@
|
|||||||
|
|
||||||
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="nested">
|
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
<xsl:apply-templates />
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class">ds-simple-list-item</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Wrap orphaned sub-lists into the preceding item -->
|
<!-- Wrap orphaned sub-lists into the preceding item -->
|
||||||
<xsl:variable name="node-set1" select="./following-sibling::dri:list"/>
|
<xsl:variable name="node-set1" select="./following-sibling::dri:list"/>
|
||||||
<xsl:variable name="node-set2" select="./following-sibling::dri:item[1]/following-sibling::dri:list"/>
|
<xsl:variable name="node-set2" select="./following-sibling::dri:item[1]/following-sibling::dri:list"/>
|
||||||
|
<xsl:apply-templates />
|
||||||
<xsl:apply-templates select="$node-set1[count(.|$node-set2) != count($node-set2)]"/>
|
<xsl:apply-templates select="$node-set1[count(.|$node-set2) != count($node-set2)]"/>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
@@ -512,6 +515,9 @@
|
|||||||
<!-- Generic item handling for cases where nothing special needs to be done -->
|
<!-- Generic item handling for cases where nothing special needs to be done -->
|
||||||
<xsl:template match="dri:item" mode="nested">
|
<xsl:template match="dri:item" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class">ds-simple-list-item</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
@@ -224,20 +224,22 @@
|
|||||||
<xsl:when test="dri:field">
|
<xsl:when test="dri:field">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="preceding-sibling::*[1][local-name()='label']">
|
<xsl:when test="preceding-sibling::*[1][local-name()='label']">
|
||||||
<label class="ds-form-label">
|
<xsl:if test="string-length(string(preceding-sibling::*[1][local-name()='label'])) > 0">
|
||||||
|
<label class="ds-form-label">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="./dri:field/@id">
|
<xsl:when test="./dri:field/@id">
|
||||||
<xsl:attribute name="for">
|
<xsl:attribute name="for">
|
||||||
<xsl:value-of select="translate(./dri:field/@id,'.','_')"/>
|
<xsl:value-of select="translate(./dri:field/@id,'.','_')"/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:otherwise></xsl:otherwise>
|
<xsl:otherwise></xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<xsl:apply-templates select="preceding-sibling::*[1][local-name()='label']"/> 
|
<xsl:apply-templates select="preceding-sibling::*[1][local-name()='label']"/>
|
||||||
</label>
|
</label>
|
||||||
|
</xsl:if>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:otherwise>
|
<xsl:otherwise>
|
||||||
<xsl:apply-templates select="preceding-sibling::*[1][local-name()='label']"/> 
|
<xsl:apply-templates select="preceding-sibling::*[1][local-name()='label']"/>
|
||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
|
@@ -994,7 +994,7 @@
|
|||||||
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
||||||
</ul>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- The item template creates an HTML list item element and places the contents of the DRI item inside it.
|
<!-- The item template creates an HTML list item element and places the contents of the DRI item inside it.
|
||||||
Additionally, it checks to see if the currently viewed item has a label element directly preceeding it,
|
Additionally, it checks to see if the currently viewed item has a label element directly preceeding it,
|
||||||
and if it does, applies the label's template before performing its own actions. This mechanism applies
|
and if it does, applies the label's template before performing its own actions. This mechanism applies
|
||||||
@@ -1007,7 +1007,7 @@
|
|||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- The case of nested lists is handled in a similar way across all lists. You match the sub-list based on
|
<!-- The case of nested lists is handled in a similar way across all lists. You match the sub-list based on
|
||||||
its parent, create a list item approtiate to the list type, fill its content from the sub-list's head
|
its parent, create a list item approtiate to the list type, fill its content from the sub-list's head
|
||||||
element and apply the other templates normally. -->
|
element and apply the other templates normally. -->
|
||||||
@@ -1016,8 +1016,8 @@
|
|||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- Second type is the ordered list, which is a list with either labels or names to designate an ordering
|
<!-- Second type is the ordered list, which is a list with either labels or names to designate an ordering
|
||||||
of some kind. -->
|
of some kind. -->
|
||||||
<xsl:template match="dri:list[@type='ordered']" priority="2">
|
<xsl:template match="dri:list[@type='ordered']" priority="2">
|
||||||
@@ -1031,7 +1031,7 @@
|
|||||||
</xsl:apply-templates>
|
</xsl:apply-templates>
|
||||||
</ol>
|
</ol>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='ordered']/dri:item" priority="2" mode="nested">
|
<xsl:template match="dri:list[@type='ordered']/dri:item" priority="2" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
<xsl:if test="name(preceding-sibling::*[position()=1]) = 'label'">
|
<xsl:if test="name(preceding-sibling::*[position()=1]) = 'label'">
|
||||||
@@ -1040,14 +1040,14 @@
|
|||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='ordered']/dri:list" priority="3" mode="nested">
|
<xsl:template match="dri:list[@type='ordered']/dri:list" priority="3" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- Progress list used primarily in forms that span several pages. There isn't a template for the nested
|
<!-- Progress list used primarily in forms that span several pages. There isn't a template for the nested
|
||||||
version of this list, mostly because there isn't a use case for it. -->
|
version of this list, mostly because there isn't a use case for it. -->
|
||||||
<xsl:template match="dri:list[@type='progress']" priority="2">
|
<xsl:template match="dri:list[@type='progress']" priority="2">
|
||||||
@@ -1059,7 +1059,7 @@
|
|||||||
<xsl:apply-templates select="dri:item"/>
|
<xsl:apply-templates select="dri:item"/>
|
||||||
</ul>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='progress']/dri:item" priority="2">
|
<xsl:template match="dri:list[@type='progress']/dri:item" priority="2">
|
||||||
<li>
|
<li>
|
||||||
<xsl:attribute name="class">
|
<xsl:attribute name="class">
|
||||||
@@ -1082,8 +1082,8 @@
|
|||||||
</li>
|
</li>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- The third type of list is the glossary (gloss) list. It is essentially a list of pairs, consisting of
|
<!-- The third type of list is the glossary (gloss) list. It is essentially a list of pairs, consisting of
|
||||||
a set of labels, each followed by an item. Unlike the ordered and bulleted lists, gloss is implemented
|
a set of labels, each followed by an item. Unlike the ordered and bulleted lists, gloss is implemented
|
||||||
via HTML definition list (dd) element. It can also be changed to work as a two-column table. -->
|
via HTML definition list (dd) element. It can also be changed to work as a two-column table. -->
|
||||||
@@ -1096,13 +1096,13 @@
|
|||||||
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
||||||
</dl>
|
</dl>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='gloss']/dri:item" priority="2" mode="nested">
|
<xsl:template match="dri:list[@type='gloss']/dri:item" priority="2" mode="nested">
|
||||||
<dd>
|
<dd>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</dd>
|
</dd>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='gloss']/dri:label" priority="2" mode="nested">
|
<xsl:template match="dri:list[@type='gloss']/dri:label" priority="2" mode="nested">
|
||||||
<dt>
|
<dt>
|
||||||
<span>
|
<span>
|
||||||
@@ -1115,14 +1115,14 @@
|
|||||||
</span>
|
</span>
|
||||||
</dt>
|
</dt>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='gloss']/dri:list" priority="3" mode="nested">
|
<xsl:template match="dri:list[@type='gloss']/dri:list" priority="3" mode="nested">
|
||||||
<dd>
|
<dd>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
</dd>
|
</dd>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- The next list type is one without a type attribute. In this case XSL makes a decision: if the items
|
<!-- The next list type is one without a type attribute. In this case XSL makes a decision: if the items
|
||||||
of the list have labels the the list will be made into a table-like structure, otherwise it is considered
|
of the list have labels the the list will be made into a table-like structure, otherwise it is considered
|
||||||
to be a plain unordered list and handled generically. -->
|
to be a plain unordered list and handled generically. -->
|
||||||
@@ -1147,7 +1147,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="labeled">
|
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="labeled">
|
||||||
<tr>
|
<tr>
|
||||||
<xsl:attribute name="class">
|
<xsl:attribute name="class">
|
||||||
@@ -1164,7 +1164,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[not(@type)]/dri:label" priority="2" mode="labeled">
|
<xsl:template match="dri:list[not(@type)]/dri:label" priority="2" mode="labeled">
|
||||||
<td>
|
<td>
|
||||||
<xsl:if test="count(./node())>0">
|
<xsl:if test="count(./node())>0">
|
||||||
@@ -1179,9 +1179,12 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
</td>
|
</td>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="nested">
|
<xsl:template match="dri:list[not(@type)]/dri:item" priority="2" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class">ds-simple-list-item</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
<!-- Wrap orphaned sub-lists into the preceding item -->
|
<!-- Wrap orphaned sub-lists into the preceding item -->
|
||||||
<xsl:variable name="node-set1" select="./following-sibling::dri:list"/>
|
<xsl:variable name="node-set1" select="./following-sibling::dri:list"/>
|
||||||
@@ -1189,18 +1192,18 @@
|
|||||||
<xsl:apply-templates select="$node-set1[count(.|$node-set2) != count($node-set2)]"/>
|
<xsl:apply-templates select="$node-set1[count(.|$node-set2) != count($node-set2)]"/>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Special treatment of a list type "form", which is used to encode simple forms and give them structure.
|
<!-- Special treatment of a list type "form", which is used to encode simple forms and give them structure.
|
||||||
This is done partly to ensure that the resulting HTML form follows accessibility guidelines. -->
|
This is done partly to ensure that the resulting HTML form follows accessibility guidelines. -->
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='form']" priority="3">
|
<xsl:template match="dri:list[@type='form']" priority="3">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="ancestor::dri:list[@type='form']">
|
<xsl:when test="ancestor::dri:list[@type='form']">
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<xsl:call-template name="standardAttributes">
|
<xsl:call-template name="standardAttributes">
|
||||||
@@ -1217,7 +1220,7 @@
|
|||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:apply-templates select="dri:head"/>
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<xsl:apply-templates select="*[not(name()='label' or name()='head')]" />
|
<xsl:apply-templates select="*[not(name()='label' or name()='head')]" />
|
||||||
</ol>
|
</ol>
|
||||||
@@ -1240,7 +1243,7 @@
|
|||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:apply-templates select="dri:head"/>
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<xsl:apply-templates select="*[not(name()='label' or name()='head')]" />
|
<xsl:apply-templates select="*[not(name()='label' or name()='head')]" />
|
||||||
</ol>
|
</ol>
|
||||||
@@ -1248,7 +1251,7 @@
|
|||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- TODO: Account for the dri:hi/dri:field kind of nesting here and everywhere else... -->
|
<!-- TODO: Account for the dri:hi/dri:field kind of nesting here and everywhere else... -->
|
||||||
<xsl:template match="dri:list[@type='form']/dri:item" priority="3">
|
<xsl:template match="dri:list[@type='form']/dri:item" priority="3">
|
||||||
<li>
|
<li>
|
||||||
@@ -1276,7 +1279,7 @@
|
|||||||
<xsl:if test="dri:list[@type='form']">sublist </xsl:if>
|
<xsl:if test="dri:list[@type='form']">sublist </xsl:if>
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
|
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="dri:field[@type='composite']">
|
<xsl:when test="dri:field[@type='composite']">
|
||||||
<xsl:call-template name="pick-label"/>
|
<xsl:call-template name="pick-label"/>
|
||||||
@@ -1300,7 +1303,7 @@
|
|||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- An item in a nested "form" list -->
|
<!-- An item in a nested "form" list -->
|
||||||
<xsl:template match="dri:list[@type='form']//dri:list[@type='form']/dri:item" priority="3">
|
<xsl:template match="dri:list[@type='form']//dri:list[@type='form']/dri:item" priority="3">
|
||||||
<li>
|
<li>
|
||||||
@@ -1315,13 +1318,13 @@
|
|||||||
<!--<xsl:if test="count(../dri:item) > 3">-->
|
<!--<xsl:if test="count(../dri:item) > 3">-->
|
||||||
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 0)">even </xsl:if>
|
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 0)">even </xsl:if>
|
||||||
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 1)">odd </xsl:if>
|
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 1)">odd </xsl:if>
|
||||||
|
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="(count(../../..//dri:item) - count(../../..//dri:list[@type='form'])) mod 2 = 1">
|
<xsl:when test="(count(../../..//dri:item) - count(../../..//dri:list[@type='form'])) mod 2 = 1">
|
||||||
<!--<xsl:if test="count(../dri:item) > 3">-->
|
<!--<xsl:if test="count(../dri:item) > 3">-->
|
||||||
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 1)">even </xsl:if>
|
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 1)">even </xsl:if>
|
||||||
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 0)">odd </xsl:if>
|
<xsl:if test="(count(preceding-sibling::dri:item | ../../preceding-sibling::dri:item/dri:list[@type='form']/dri:item) mod 2 = 0)">odd </xsl:if>
|
||||||
|
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<!--
|
<!--
|
||||||
@@ -1329,7 +1332,7 @@
|
|||||||
-->
|
-->
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
|
|
||||||
<xsl:call-template name="pick-label"/>
|
<xsl:call-template name="pick-label"/>
|
||||||
|
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
@@ -1350,7 +1353,7 @@
|
|||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template name="pick-label">
|
<xsl:template name="pick-label">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="dri:field/dri:label">
|
<xsl:when test="dri:field/dri:label">
|
||||||
@@ -1382,7 +1385,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
|
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="dri:field">
|
<xsl:when test="dri:field">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
@@ -1411,7 +1414,7 @@
|
|||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='form']/dri:label" priority="3">
|
<xsl:template match="dri:list[@type='form']/dri:label" priority="3">
|
||||||
<xsl:attribute name="class">
|
<xsl:attribute name="class">
|
||||||
<xsl:text>ds-form-label</xsl:text>
|
<xsl:text>ds-form-label</xsl:text>
|
||||||
@@ -1431,12 +1434,12 @@
|
|||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="dri:field/dri:label" mode="formComposite">
|
<xsl:template match="dri:field/dri:label" mode="formComposite">
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list[@type='form']/dri:head" priority="5">
|
<xsl:template match="dri:list[@type='form']/dri:head" priority="5">
|
||||||
<legend>
|
<legend>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
@@ -1561,27 +1564,30 @@
|
|||||||
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
<xsl:apply-templates select="*[not(name()='head')]" mode="nested"/>
|
||||||
</ul>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- Generic label handling: simply place the text of the element followed by a period and space. -->
|
<!-- Generic label handling: simply place the text of the element followed by a period and space. -->
|
||||||
<xsl:template match="dri:label" priority="1" mode="nested">
|
<xsl:template match="dri:label" priority="1" mode="nested">
|
||||||
<xsl:copy-of select="./node()"/>
|
<xsl:copy-of select="./node()"/>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- Generic item handling for cases where nothing special needs to be done -->
|
<!-- Generic item handling for cases where nothing special needs to be done -->
|
||||||
<xsl:template match="dri:item" mode="nested">
|
<xsl:template match="dri:item" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class">ds-simple-list-item</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="dri:list/dri:list" priority="1" mode="nested">
|
<xsl:template match="dri:list/dri:list" priority="1" mode="nested">
|
||||||
<li>
|
<li>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
</li>
|
</li>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- From here on out come the templates for supporting elements that are contained within structural
|
<!-- From here on out come the templates for supporting elements that are contained within structural
|
||||||
ones. These include head (in all its myriad forms), rich text container elements (like hi and figure),
|
ones. These include head (in all its myriad forms), rich text container elements (like hi and figure),
|
||||||
@@ -2692,11 +2698,33 @@
|
|||||||
<i18n:text>xmlui.dri2xhtml.structural.pagination-next</i18n:text>
|
<i18n:text>xmlui.dri2xhtml.structural.pagination-next</i18n:text>
|
||||||
</a>
|
</a>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
<xsl:if test="parent::node()/dri:div[@n = 'masked-page-control']">
|
||||||
|
<xsl:apply-templates select="parent::node()/dri:div[@n='masked-page-control']/dri:div">
|
||||||
|
<xsl:with-param name="position" select="$position"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
</div>
|
</div>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n = 'masked-page-control']" priority="5">
|
||||||
|
<!--Do not render this division, this is handled by the xsl-->
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:div[@n ='search-controls-gear']">
|
||||||
|
<xsl:param name="position"/>
|
||||||
|
<div>
|
||||||
|
<xsl:call-template name="standardAttributes">
|
||||||
|
<xsl:with-param name="class"><xsl:value-of select="$position"/></xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- A quick helper function used by the @pagination template for repetitive tasks -->
|
<!-- A quick helper function used by the @pagination template for repetitive tasks -->
|
||||||
<xsl:template name="offset-link">
|
<xsl:template name="offset-link">
|
||||||
<xsl:param name="pageOffset"/>
|
<xsl:param name="pageOffset"/>
|
||||||
@@ -2820,7 +2848,7 @@
|
|||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- First, the detail list case -->
|
<!-- First, the detail list case -->
|
||||||
<xsl:template match="dri:referenceSet[@type = 'detailList']" priority="2">
|
<xsl:template match="dri:referenceSet[@type = 'detailList']" priority="2">
|
||||||
<xsl:apply-templates select="dri:head"/>
|
<xsl:apply-templates select="dri:head"/>
|
||||||
@@ -2828,15 +2856,15 @@
|
|||||||
<xsl:apply-templates select="*[not(name()='head')]" mode="detailList"/>
|
<xsl:apply-templates select="*[not(name()='head')]" mode="detailList"/>
|
||||||
</ul>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
<!-- Next up is the summary view case that at this point applies only to items, since communities and
|
<!-- Next up is the summary view case that at this point applies only to items, since communities and
|
||||||
collections do not have two separate views. -->
|
collections do not have two separate views. -->
|
||||||
<xsl:template match="dri:referenceSet[@type = 'summaryView']" priority="2">
|
<xsl:template match="dri:referenceSet[@type = 'summaryView']" priority="2">
|
||||||
<xsl:apply-templates select="dri:head"/>
|
<xsl:apply-templates select="dri:head"/>
|
||||||
<xsl:apply-templates select="*[not(name()='head')]" mode="summaryView"/>
|
<xsl:apply-templates select="*[not(name()='head')]" mode="summaryView"/>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- Finally, we have the detailed view case that is applicable to items, communities and collections.
|
<!-- Finally, we have the detailed view case that is applicable to items, communities and collections.
|
||||||
In DRI it constitutes a standard view of collections/communities and a complete metadata listing
|
In DRI it constitutes a standard view of collections/communities and a complete metadata listing
|
||||||
view of items. -->
|
view of items. -->
|
||||||
@@ -3489,4 +3517,272 @@
|
|||||||
</td>
|
</td>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template match="dri:list[@type='dsolist']" priority="2">
|
||||||
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
<ul class="ds-artifact-list">
|
||||||
|
<xsl:apply-templates select="*[not(name()='head')]" mode="dsoList"/>
|
||||||
|
</ul>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:list/dri:list" mode="dsoList" priority="7">
|
||||||
|
<xsl:apply-templates select="dri:head"/>
|
||||||
|
<ul>
|
||||||
|
<xsl:apply-templates select="*[not(name()='head')]" mode="dsoList"/>
|
||||||
|
</ul>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="dri:list/dri:list/dri:list" mode="dsoList" priority="8">
|
||||||
|
<li>
|
||||||
|
<xsl:attribute name="class">
|
||||||
|
<xsl:text>ds-artifact-item clearfix </xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="position() mod 2 = 0">even</xsl:when>
|
||||||
|
<xsl:otherwise>odd</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:attribute>
|
||||||
|
<!--
|
||||||
|
Retrieve the type from our name, the name contains the following format:
|
||||||
|
{handle}:{metadata}
|
||||||
|
-->
|
||||||
|
<xsl:variable name="handle">
|
||||||
|
<xsl:value-of select="substring-before(@n, ':')"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable name="type">
|
||||||
|
<xsl:value-of select="substring-after(@n, ':')"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable name="externalMetadataURL">
|
||||||
|
<xsl:text>cocoon://metadata/handle/</xsl:text>
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
<xsl:text>/mets.xml</xsl:text>
|
||||||
|
<!-- Since this is a summary only grab the descriptive metadata, and the thumbnails -->
|
||||||
|
<xsl:text>?sections=dmdSec,fileSec&fileGrpTypes=THUMBNAIL</xsl:text>
|
||||||
|
<!-- An example of requesting a specific metadata standard (MODS and QDC crosswalks only work for items)->
|
||||||
|
<xsl:if test="@type='DSpace Item'">
|
||||||
|
<xsl:text>&dmdTypes=DC</xsl:text>
|
||||||
|
</xsl:if>-->
|
||||||
|
</xsl:variable>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$type='community'">
|
||||||
|
<xsl:call-template name="communitySummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$type='collection'">
|
||||||
|
<xsl:call-template name="collectionSummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$type='item'">
|
||||||
|
<xsl:call-template name="itemSummaryList">
|
||||||
|
<xsl:with-param name="handle">
|
||||||
|
<xsl:value-of select="$handle"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="externalMetadataUrl">
|
||||||
|
<xsl:value-of select="$externalMetadataURL"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
</li>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="communitySummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
<div class="artifact-title">
|
||||||
|
<a href="{$metsDoc/mets:METS/@OBJID}">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</a>
|
||||||
|
<!--Display community strengths (item counts) if they exist-->
|
||||||
|
<xsl:if test="string-length($metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]) > 0">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</div>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="collectionSummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
<div class="artifact-title">
|
||||||
|
<a href="{$metsDoc/mets:METS/@OBJID}">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!--Display collection strengths (item counts) if they exist-->
|
||||||
|
<xsl:if test="string-length($metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]) > 0">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='format'][@qualifier='extent'][1]"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="itemSummaryList">
|
||||||
|
<xsl:param name="handle"/>
|
||||||
|
<xsl:param name="externalMetadataUrl"/>
|
||||||
|
|
||||||
|
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
|
||||||
|
|
||||||
|
<div class="artifact-description">
|
||||||
|
<div class="artifact-title">
|
||||||
|
<xsl:element name="a">
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/@withdrawn">
|
||||||
|
<xsl:value-of select="$metsDoc/mets:METS/@OBJEDIT"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="concat($context-path, '/handle/', $handle)"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.title'))]">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.title'))]/dri:item"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:element>
|
||||||
|
<!-- Generate COinS with empty content per spec but force Cocoon to not create a minified tag -->
|
||||||
|
<span class="Z3988">
|
||||||
|
<xsl:attribute name="title">
|
||||||
|
<xsl:for-each select="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim">
|
||||||
|
<xsl:call-template name="renderCOinS"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:attribute>
|
||||||
|
 <!-- non-breaking space to force separating the end tag -->
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="artifact-info">
|
||||||
|
<span class="author">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.contributor.author'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.contributor.author'))]/dri:item">
|
||||||
|
<xsl:variable name="author">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:variable>
|
||||||
|
<span>
|
||||||
|
<!--Check authority in the mets document-->
|
||||||
|
<xsl:if test="$metsDoc/mets:METS/mets:dmdSec/mets:mdWrap/mets:xmlData/dim:dim/dim:field[@element='contributor' and @qualifier='author' and . = $author]/@authority">
|
||||||
|
<xsl:attribute name="class">
|
||||||
|
<xsl:text>ds-dc_contributor_author-authority</xsl:text>
|
||||||
|
</xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.creator'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.creator'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.contributor'))]">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.contributor'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:if test="count(following-sibling::dri:item) != 0">
|
||||||
|
<xsl:text>; </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-author</i18n:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</span>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="dri:list[@n=(concat($handle, ':dc.date.issued'))] or dri:list[@n=(concat($handle, ':dc.publisher'))]">
|
||||||
|
<span class="publisher-date">
|
||||||
|
<xsl:text>(</xsl:text>
|
||||||
|
<xsl:if test="dri:list[@n=(concat($handle, ':dc.publisher'))]">
|
||||||
|
<span class="publisher">
|
||||||
|
<xsl:apply-templates select="dri:list[@n=(concat($handle, ':dc.publisher'))]/dri:item"/>
|
||||||
|
</span>
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<span class="date">
|
||||||
|
<xsl:value-of
|
||||||
|
select="substring(dri:list[@n=(concat($handle, ':dc.date.issued'))]/dri:item,1,10)"/>
|
||||||
|
</span>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
</span>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':dc.description.abstract'))]/dri:item/dri:hi">
|
||||||
|
<div class="abstract">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':dc.description.abstract'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:text>...</xsl:text>
|
||||||
|
<br/>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="dri:list[@n=(concat($handle, ':fulltext'))]">
|
||||||
|
<div class="abstract">
|
||||||
|
<xsl:for-each select="dri:list[@n=(concat($handle, ':fulltext'))]/dri:item">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:text>...</xsl:text>
|
||||||
|
<br/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</div>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Generates thumbnails (if present)-->
|
||||||
|
<xsl:apply-templates select="$metsDoc/mets:METS/mets:fileSec" mode="artifact-preview"/>
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
@@ -84,9 +84,11 @@ public class List extends AbstractWingElement implements WingMergeableElement,
|
|||||||
|
|
||||||
public static final String TYPE_FORM = "form";
|
public static final String TYPE_FORM = "form";
|
||||||
|
|
||||||
|
public static final String TYPE_DSO_LIST = "dsolist";
|
||||||
|
|
||||||
/** All the possible list types collected into one array */
|
/** All the possible list types collected into one array */
|
||||||
public static final String[] TYPES = { TYPE_SIMPLE, TYPE_ORDERED,
|
public static final String[] TYPES = { TYPE_SIMPLE, TYPE_ORDERED,
|
||||||
TYPE_BULLETED, TYPE_GLOSS, TYPE_PROGRESS, TYPE_FORM };
|
TYPE_BULLETED, TYPE_GLOSS, TYPE_PROGRESS, TYPE_FORM, TYPE_DSO_LIST };
|
||||||
|
|
||||||
/** The list's name */
|
/** The list's name */
|
||||||
private String name;
|
private String name;
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
search.server = http://localhost:8080/solr/search
|
search.server = http://localhost:8080/solr/search
|
||||||
|
|
||||||
#Char used to ensure that the sidebar facets are case insensitive
|
#Char used to ensure that the sidebar facets are case insensitive
|
||||||
#solr.facets.split.char=|||
|
#solr.facets.split.char=\n|||\n
|
||||||
|
|
||||||
#All metadata fields that will not end up in the index, this is a comma separated list
|
#All metadata fields that will not end up in the index, this is a comma separated list
|
||||||
index.ignore=dc.description.provenance
|
index.ignore=dc.description.provenance
|
||||||
|
@@ -42,9 +42,9 @@
|
|||||||
<!--Which sidebar facets are to be displayed-->
|
<!--Which sidebar facets are to be displayed-->
|
||||||
<property name="sidebarFacets">
|
<property name="sidebarFacets">
|
||||||
<list>
|
<list>
|
||||||
<ref bean="sidebarFacetAuthor" />
|
<ref bean="searchFilterAuthor" />
|
||||||
<ref bean="sidebarFacetSubject" />
|
<ref bean="searchFilterSubject" />
|
||||||
<ref bean="sidebarFacetDateIssued" />
|
<ref bean="searchFilterIssued" />
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
<!--The search filters which can be used on the discovery search page-->
|
<!--The search filters which can be used on the discovery search page-->
|
||||||
@@ -85,6 +85,52 @@
|
|||||||
<property name="max" value="5"/>
|
<property name="max" value="5"/>
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="hitHighlightingConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration">
|
||||||
|
<property name="metadataFields">
|
||||||
|
<list>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.title"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.contributor.author"/>
|
||||||
|
<property name="snippets" value="5"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="dc.description.abstract"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
|
||||||
|
<property name="field" value="fulltext"/>
|
||||||
|
<property name="maxSize" value="250"/>
|
||||||
|
<property name="snippets" value="2"/>
|
||||||
|
</bean>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<property name="moreLikeThisConfiguration">
|
||||||
|
<bean class="org.dspace.discovery.configuration.DiscoveryMoreLikeThisConfiguration">
|
||||||
|
<!--When altering this list also alter the "xmlui.Discovery.RelatedItems.help" key as it describes
|
||||||
|
the metadata fields below-->
|
||||||
|
<property name="similarityMetadataFields">
|
||||||
|
<list>
|
||||||
|
<value>dc.title</value>
|
||||||
|
<value>dc.contributor.author</value>
|
||||||
|
<value>dc.creator</value>
|
||||||
|
<value>dc.subject</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<!--The minimum number of matching terms across the metadata fields above before an item is found as related -->
|
||||||
|
<property name="minTermFrequency" value="5"/>
|
||||||
|
<!--The maximum number of related items displayed-->
|
||||||
|
<property name="max" value="3"/>
|
||||||
|
<!--The minimum word length below which words will be ignored-->
|
||||||
|
<property name="minWordLength" value="5"/>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
@@ -97,45 +143,9 @@
|
|||||||
<value>dc.title</value>
|
<value>dc.title</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
<property name="fullAutoComplete" value="false"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="searchFilterAuthor" class="org.dspace.discovery.configuration.DiscoverySearchFilter">
|
<bean id="searchFilterAuthor" class="org.dspace.discovery.configuration.DiscoverySearchFilterFacet">
|
||||||
<property name="indexFieldName" value="author"/>
|
|
||||||
<property name="metadataFields">
|
|
||||||
<list>
|
|
||||||
<value>dc.contributor.author</value>
|
|
||||||
<value>dc.creator</value>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
<property name="fullAutoComplete" value="true"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="searchFilterSubject" class="org.dspace.discovery.configuration.DiscoverySearchFilter">
|
|
||||||
<property name="indexFieldName" value="subject"/>
|
|
||||||
<property name="metadataFields">
|
|
||||||
<list>
|
|
||||||
<value>dc.subject.*</value>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
<property name="fullAutoComplete" value="true"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="searchFilterIssued" class="org.dspace.discovery.configuration.DiscoverySearchFilter">
|
|
||||||
<property name="indexFieldName" value="dateIssued"/>
|
|
||||||
<property name="metadataFields">
|
|
||||||
<list>
|
|
||||||
<value>dc.date.issued</value>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
<property name="type" value="date"/>
|
|
||||||
<property name="fullAutoComplete" value="false"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--Sidebar facet configuration beans-->
|
|
||||||
<bean id="sidebarFacetAuthor" class="org.dspace.discovery.configuration.SidebarFacetConfiguration">
|
|
||||||
<property name="indexFieldName" value="author"/>
|
<property name="indexFieldName" value="author"/>
|
||||||
<property name="metadataFields">
|
<property name="metadataFields">
|
||||||
<list>
|
<list>
|
||||||
@@ -147,7 +157,7 @@
|
|||||||
<property name="sortOrder" value="COUNT"/>
|
<property name="sortOrder" value="COUNT"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="sidebarFacetSubject" class="org.dspace.discovery.configuration.SidebarFacetConfiguration">
|
<bean id="searchFilterSubject" class="org.dspace.discovery.configuration.DiscoverySearchFilterFacet">
|
||||||
<property name="indexFieldName" value="subject"/>
|
<property name="indexFieldName" value="subject"/>
|
||||||
<property name="metadataFields">
|
<property name="metadataFields">
|
||||||
<list>
|
<list>
|
||||||
@@ -158,7 +168,7 @@
|
|||||||
<property name="sortOrder" value="COUNT"/>
|
<property name="sortOrder" value="COUNT"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="sidebarFacetDateIssued" class="org.dspace.discovery.configuration.SidebarFacetConfiguration">
|
<bean id="searchFilterIssued" class="org.dspace.discovery.configuration.DiscoverySearchFilterFacet">
|
||||||
<property name="indexFieldName" value="dateIssued"/>
|
<property name="indexFieldName" value="dateIssued"/>
|
||||||
<property name="metadataFields">
|
<property name="metadataFields">
|
||||||
<list>
|
<list>
|
||||||
@@ -169,7 +179,6 @@
|
|||||||
<property name="sortOrder" value="VALUE"/>
|
<property name="sortOrder" value="VALUE"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!--Sort properties-->
|
<!--Sort properties-->
|
||||||
<bean id="sortTitle" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
<bean id="sortTitle" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
|
||||||
<property name="metadataField" value="dc.title"/>
|
<property name="metadataField" value="dc.title"/>
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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/
|
||||||
|
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||||
|
|
||||||
|
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
|
||||||
|
|
||||||
|
<bean class="org.dspace.discovery.SolrServiceResourceRestrictionPlugin" id="solrServiceResourceIndexPlugin" scope="prototype"/>
|
||||||
|
|
||||||
|
<alias name="solrServiceResourceIndexPlugin" alias="org.dspace.discovery.SolrServiceResourceRestrictionPlugin"/>
|
||||||
|
|
||||||
|
</beans>
|