First part of search update - reduce search size, add in fields for sorting content, lessen dependency on handles

git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2508 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Graham Triggs
2008-01-10 14:03:36 +00:00
parent 4b4828ef0e
commit d86af20a5a
34 changed files with 732 additions and 444 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* AbstractTextFilterBOD.java * AbstractTextFilterOFD.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -42,6 +42,7 @@ package org.dspace.browse;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.text.filter.TextFilter; import org.dspace.text.filter.TextFilter;
import org.dspace.sort.OrderFormatDelegate;
/** /**
* Helper class for creating order delegates. * Helper class for creating order delegates.
@@ -49,7 +50,7 @@ import org.dspace.text.filter.TextFilter;
* To configure the filters create a subclass and, in an object initializer, * To configure the filters create a subclass and, in an object initializer,
* create an array of classes that implement TextFilter: * create an array of classes that implement TextFilter:
* *
* class MyLocaleDelegate extends AbstractTextFilterBOD { * class MyLocaleDelegate extends AbstractTextFilterOFD {
* { * {
* filters = new TextFilter[] { new LocaleOrderingFilter(); } * filters = new TextFilter[] { new LocaleOrderingFilter(); }
* } * }
@@ -72,9 +73,9 @@ import org.dspace.text.filter.TextFilter;
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public abstract class AbstractTextFilterBOD implements BrowseOrderDelegate public abstract class AbstractTextFilterOFD implements OrderFormatDelegate
{ {
private final static Logger log = Logger.getLogger(AbstractTextFilterBOD.class); private final static Logger log = Logger.getLogger(AbstractTextFilterOFD.class);
// Initialised in subclass in an object initializer // Initialised in subclass in an object initializer
protected TextFilter[] filters; protected TextFilter[] filters;

View File

@@ -49,6 +49,8 @@ import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.sort.SortOption;
import org.dspace.sort.OrderFormat;
/** /**
* This class does most of the actual grunt work of preparing a browse * This class does most of the actual grunt work of preparing a browse
@@ -285,7 +287,7 @@ public class BrowseEngine
rawValue = value; rawValue = value;
// make sure the incoming value is normalised // make sure the incoming value is normalised
value = BrowseOrder.makeSortString(value, scope.getFilterValueLang(), value = OrderFormat.makeSortString(value, scope.getFilterValueLang(),
scope.getBrowseIndex().getDataType()); scope.getBrowseIndex().getDataType());
// set the values in the Browse Query // set the values in the Browse Query
@@ -737,12 +739,12 @@ public class BrowseEngine
if (scope.hasJumpToValue()) if (scope.hasJumpToValue())
{ {
// Normalize it based on the specified language as appropriate for this index // Normalize it based on the specified language as appropriate for this index
return BrowseOrder.makeSortString(scope.getJumpToValue(), scope.setJumpToValueLang(), scope.getBrowseIndex().getDataType()); return OrderFormat.makeSortString(scope.getJumpToValue(), scope.setJumpToValueLang(), scope.getBrowseIndex().getDataType());
} }
else if (scope.hasStartsWith()) else if (scope.hasStartsWith())
{ {
// Scope has a starts with, so normalize that instead // Scope has a starts with, so normalize that instead
return BrowseOrder.makeSortString(scope.getStartsWith(), null, scope.getBrowseIndex().getDataType()); return OrderFormat.makeSortString(scope.getStartsWith(), null, scope.getBrowseIndex().getDataType());
} }
// No focus value on the scope (ie. focus by id), so just return the passed focus value // No focus value on the scope (ie. focus by id), so just return the passed focus value

View File

@@ -41,12 +41,13 @@ package org.dspace.browse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
/** /**
* This class holds all the information about a specifically configured * This class holds all the information about a specifically configured
@@ -113,7 +114,7 @@ public class BrowseIndex
displayType = "item"; displayType = "item";
sortOption = SortOption.getDefaultSortOption(); sortOption = SortOption.getDefaultSortOption();
} }
catch (BrowseException be) catch (SortException se)
{ {
// FIXME Exception handling // FIXME Exception handling
} }
@@ -140,82 +141,89 @@ public class BrowseIndex
private BrowseIndex(String definition, int number) private BrowseIndex(String definition, int number)
throws BrowseException throws BrowseException
{ {
boolean valid = true; try
this.defaultOrder = SortOption.ASCENDING;
this.number = number;
String rx = "(\\w+):(\\w+):([\\w\\.\\*,]+):?(\\w*):?(\\w*)";
Pattern pattern = Pattern.compile(rx);
Matcher matcher = pattern.matcher(definition);
if (matcher.matches())
{ {
name = matcher.group(1); boolean valid = true;
displayType = matcher.group(2); this.defaultOrder = SortOption.ASCENDING;
this.number = number;
if (isMetadataIndex())
String rx = "(\\w+):(\\w+):([\\w\\.\\*,]+):?(\\w*):?(\\w*)";
Pattern pattern = Pattern.compile(rx);
Matcher matcher = pattern.matcher(definition);
if (matcher.matches())
{ {
metadataAll = matcher.group(3); name = matcher.group(1);
datatype = matcher.group(4); displayType = matcher.group(2);
if (metadataAll != null) if (isMetadataIndex())
metadata = metadataAll.split(",");
if (metadata == null || metadata.length == 0)
valid = false;
if (datatype == null || datatype.equals(""))
valid = false;
// If an optional ordering configuration is supplied,
// set the defaultOrder appropriately (asc or desc)
if (matcher.groupCount() > 4)
{ {
String order = matcher.group(5); metadataAll = matcher.group(3);
if (SortOption.DESCENDING.equalsIgnoreCase(order)) datatype = matcher.group(4);
this.defaultOrder = SortOption.DESCENDING;
if (metadataAll != null)
metadata = metadataAll.split(",");
if (metadata == null || metadata.length == 0)
valid = false;
if (datatype == null || datatype.equals(""))
valid = false;
// If an optional ordering configuration is supplied,
// set the defaultOrder appropriately (asc or desc)
if (matcher.groupCount() > 4)
{
String order = matcher.group(5);
if (SortOption.DESCENDING.equalsIgnoreCase(order))
this.defaultOrder = SortOption.DESCENDING;
}
tableBaseName = makeTableBaseName(number);
} }
else if (isItemIndex())
tableBaseName = makeTableBaseName(number);
}
else if (isItemIndex())
{
String sortName = matcher.group(3);
for (SortOption so : SortOption.getSortOptions())
{ {
if (so.getName().equals(sortName)) String sortName = matcher.group(3);
sortOption = so;
}
if (sortOption == null) for (SortOption so : SortOption.getSortOptions())
{
if (so.getName().equals(sortName))
sortOption = so;
}
if (sortOption == null)
valid = false;
// If an optional ordering configuration is supplied,
// set the defaultOrder appropriately (asc or desc)
if (matcher.groupCount() > 3)
{
String order = matcher.group(4);
if (SortOption.DESCENDING.equalsIgnoreCase(order))
this.defaultOrder = SortOption.DESCENDING;
}
tableBaseName = getItemBrowseIndex().tableBaseName;
}
else
{
valid = false; valid = false;
// If an optional ordering configuration is supplied,
// set the defaultOrder appropriately (asc or desc)
if (matcher.groupCount() > 3)
{
String order = matcher.group(4);
if (SortOption.DESCENDING.equalsIgnoreCase(order))
this.defaultOrder = SortOption.DESCENDING;
} }
tableBaseName = getItemBrowseIndex().tableBaseName;
} }
else else
{ {
valid = false; valid = false;
} }
if (!valid)
{
throw new BrowseException("Browse Index configuration is not valid: webui.browse.index." +
number + " = " + definition);
}
} }
else catch (SortException se)
{ {
valid = false; throw new BrowseException("Error in SortOptions", se);
}
if (!valid)
{
throw new BrowseException("Browse Index configuration is not valid: webui.browse.index." +
number + " = " + definition);
} }
} }

View File

@@ -40,7 +40,6 @@
package org.dspace.browse; package org.dspace.browse;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -51,6 +50,7 @@ import org.dspace.content.DCValue;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.sort.SortOption;
/** /**
* The results of a Browse, including all the contextual information about * The results of a Browse, including all the contextual information about

View File

@@ -39,6 +39,8 @@ 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.Context; import org.dspace.core.Context;
import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
@@ -404,53 +406,60 @@ public class BrowserScope
public SortOption getSortOption() public SortOption getSortOption()
throws BrowseException throws BrowseException
{ {
// If a sortOption hasn't been set, work out the default try
if (sortOption == null) {
{ // If a sortOption hasn't been set, work out the default
// We need a browse index first though if (sortOption == null)
if (browseIndex != null) {
{ // We need a browse index first though
// If a sorting hasn't been specified, and it's a metadata browse if (browseIndex != null)
if (sortBy <= 0 && browseIndex.isMetadataIndex()) {
{ // If a sorting hasn't been specified, and it's a metadata browse
// Create a dummy sortOption for the metadata sort if (sortBy <= 0 && browseIndex.isMetadataIndex())
String dataType = browseIndex.getDataType(); {
String type = ("date".equals(dataType) ? "date" : "text"); // Create a dummy sortOption for the metadata sort
sortOption = new SortOption(0, browseIndex.getName(), browseIndex.getMetadata(0), type); String dataType = browseIndex.getDataType();
} String type = ("date".equals(dataType) ? "date" : "text");
else sortOption = new SortOption(0, browseIndex.getName(), browseIndex.getMetadata(0), type);
{ }
// If a sorting hasn't been specified else
if (sortBy <= 0) {
{ // If a sorting hasn't been specified
// Get the sort option from the index if (sortBy <= 0)
sortOption = browseIndex.getSortOption();
if (sortOption == null)
{
// No sort option, so default to the first one defined in the config
for (SortOption so : SortOption.getSortOptions())
{
sortOption = so;
break;
}
}
}
else
{
// A sorting has been specified, so get it from the configured sort columns
for (SortOption so : SortOption.getSortOptions())
{ {
if (so.getNumber() == sortBy) // Get the sort option from the index
sortOption = so; sortOption = browseIndex.getSortOption();
if (sortOption == null)
{
// No sort option, so default to the first one defined in the config
for (SortOption so : SortOption.getSortOptions())
{
sortOption = so;
break;
}
}
} }
} else
} {
} // A sorting has been specified, so get it from the configured sort columns
} for (SortOption so : SortOption.getSortOptions())
{
return sortOption; if (so.getNumber() == sortBy)
} sortOption = so;
}
}
}
}
}
return sortOption;
}
catch (SortException se)
{
throw new BrowseException("Error in SortOptions", se);
}
}
/** /**
* @return Returns the startsWith. * @return Returns the startsWith.

View File

@@ -54,6 +54,9 @@ import org.apache.log4j.Logger;
import org.dspace.content.DCValue; import org.dspace.content.DCValue;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.sort.OrderFormat;
/** /**
* Tool to create Browse indexes. This class is used from the command line to * Tool to create Browse indexes. This class is used from the command line to
@@ -433,7 +436,7 @@ public class IndexBrowse
for (int x = 0; x < values.length; x++) for (int x = 0; x < values.length; x++)
{ {
// get the normalised version of the value // get the normalised version of the value
String nVal = BrowseOrder.makeSortString(values[x].value, values[x].language, bis[i].getDataType()); String nVal = OrderFormat.makeSortString(values[x].value, values[x].language, bis[i].getDataType());
Map sortMap = getSortValues(item, itemMDMap); Map sortMap = getSortValues(item, itemMDMap);
@@ -469,51 +472,59 @@ public class IndexBrowse
private Map<Integer, String> getSortValues(ItemMetadataProxy item, Map itemMDMap) private Map<Integer, String> getSortValues(ItemMetadataProxy item, Map itemMDMap)
throws BrowseException, SQLException throws BrowseException, SQLException
{ {
// now obtain the sort order values that we will use try
Map<Integer, String> sortMap = new HashMap<Integer, String>();
for (SortOption so : SortOption.getSortOptions())
{ {
Integer key = new Integer(so.getNumber()); // now obtain the sort order values that we will use
String metadata = so.getMetadata(); Map<Integer, String> sortMap = new HashMap<Integer, String>();
for (SortOption so : SortOption.getSortOptions())
// If we've already used the metadata for this Item
// it will be cached in the map
DCValue value = null;
if (itemMDMap != null)
value = (DCValue) itemMDMap.get(metadata);
// We haven't used this metadata before, so grab it from the item
if (value == null)
{ {
String[] somd = so.getMdBits(); Integer key = new Integer(so.getNumber());
DCValue[] dcv = item.getMetadata(somd[0], somd[1], somd[2], Item.ANY); String metadata = so.getMetadata();
if (dcv == null) // If we've already used the metadata for this Item
// it will be cached in the map
DCValue value = null;
if (itemMDMap != null)
value = (DCValue) itemMDMap.get(metadata);
// We haven't used this metadata before, so grab it from the item
if (value == null)
{ {
continue; String[] somd = so.getMdBits();
DCValue[] dcv = item.getMetadata(somd[0], somd[1], somd[2], Item.ANY);
if (dcv == null)
{
continue;
}
// we only use the first dc value
if (dcv.length > 0)
{
// Set it as the current metadata value to use
// and add it to the map
value = dcv[0];
if (itemMDMap != null)
itemMDMap.put(metadata, dcv[0]);
}
} }
// we only use the first dc value // normalise the values as we insert into the sort map
if (dcv.length > 0) if (value != null && value.value != null)
{ {
// Set it as the current metadata value to use String nValue = OrderFormat.makeSortString(value.value, value.language, so.getType());
// and add it to the map sortMap.put(key, nValue);
value = dcv[0];
if (itemMDMap != null)
itemMDMap.put(metadata, dcv[0]);
} }
} }
// normalise the values as we insert into the sort map return sortMap;
if (value != null && value.value != null) }
{ catch (SortException se)
String nValue = BrowseOrder.makeSortString(value.value, value.language, so.getType()); {
sortMap.put(key, nValue); throw new BrowseException("Error in SortOptions", se);
}
} }
return sortMap;
} }
/** /**
@@ -696,26 +707,33 @@ public class IndexBrowse
private void prepTables() private void prepTables()
throws BrowseException throws BrowseException
{ {
// first, erase the existing indexes try
clearDatabase();
createItemTables();
// for each current browse index, make all the relevant tables
for (int i = 0; i < bis.length; i++)
{ {
createTables(bis[i]); // first, erase the existing indexes
clearDatabase();
// prepare some CLI output
StringBuffer logMe = new StringBuffer(); createItemTables();
for (SortOption so : SortOption.getSortOptions())
{ // for each current browse index, make all the relevant tables
logMe.append(" " + so.getMetadata() + " "); for (int i = 0; i < bis.length; i++)
} {
createTables(bis[i]);
output.message("Creating browse index " + bis[i].getName() +
": index by " + bis[i].getMetadata() + // prepare some CLI output
" sortable by: " + logMe.toString()); StringBuffer logMe = new StringBuffer();
for (SortOption so : SortOption.getSortOptions())
{
logMe.append(" " + so.getMetadata() + " ");
}
output.message("Creating browse index " + bis[i].getName() +
": index by " + bis[i].getMetadata() +
" sortable by: " + logMe.toString());
}
}
catch (SortException se)
{
throw new BrowseException("Error in SortOptions", se);
} }
} }
@@ -884,6 +902,10 @@ public class IndexBrowse
context.commit(); context.commit();
} }
} }
catch (SortException se)
{
throw new BrowseException("Error in SortOptions", se);
}
catch (SQLException e) catch (SQLException e)
{ {
log.error("caught exception: ", e); log.error("caught exception: ", e);
@@ -994,6 +1016,10 @@ public class IndexBrowse
context.commit(); context.commit();
} }
} }
catch (SortException se)
{
throw new BrowseException("Error in SortOptions", se);
}
catch (SQLException e) catch (SQLException e)
{ {
log.error("caught exception: ", e); log.error("caught exception: ", e);

View File

@@ -45,7 +45,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.dspace.browse.BrowseOrder; import org.dspace.sort.OrderFormat;
/** /**
* Compare two Items by their DCValues. * Compare two Items by their DCValues.
@@ -256,6 +256,6 @@ public class ItemComparator implements Comparator
return value.value; return value.value;
} }
return BrowseOrder.makeSortString(value.value, value.language, BrowseOrder.TITLE); return OrderFormat.makeSortString(value.value, value.language, OrderFormat.TITLE);
} }
} }

View File

@@ -48,6 +48,7 @@ import org.apache.lucene.analysis.PorterStemFilter;
import org.apache.lucene.analysis.StopFilter; import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardFilter; import org.apache.lucene.analysis.standard.StandardFilter;
import org.dspace.core.ConfigurationManager;
/** /**
* Custom Lucene Analyzer that combines the standard filter, lowercase filter, * Custom Lucene Analyzer that combines the standard filter, lowercase filter,
@@ -94,4 +95,14 @@ public class DSAnalyzer extends Analyzer
return result; return result;
} }
public int getPositionIncrementGap(String fieldName)
{
// If it is the default field, or bounded fields is turned off in the config, return the default value
if ("default".equalsIgnoreCase(fieldName) || !ConfigurationManager.getBooleanProperty("search.boundedfields", false))
return super.getPositionIncrementGap(fieldName);
// Not the default field, and we want bounded fields, so return an large gap increment
return 10;
}
} }

View File

@@ -47,16 +47,22 @@ import java.io.StringWriter;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.PosixParser;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
@@ -75,6 +81,8 @@ import org.dspace.core.Context;
import org.dspace.core.Email; import org.dspace.core.Email;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.handle.HandleManager; import org.dspace.handle.HandleManager;
import org.dspace.sort.SortOption;
import org.dspace.sort.OrderFormat;
/** /**
* DSIndexer contains the methods that index Items and their metadata, * DSIndexer contains the methods that index Items and their metadata,
@@ -111,6 +119,20 @@ public class DSIndexer
String schema; String schema;
String element; String element;
String qualifier = null; String qualifier = null;
String type = "text";
IndexConfig()
{
}
IndexConfig(String indexName, String schema, String element, String qualifier, String type)
{
this.indexName = indexName;
this.schema = schema;
this.element = element;
this.qualifier = qualifier;
this.type = type;
}
} }
private static String index_directory = ConfigurationManager.getProperty("search.dir"); private static String index_directory = ConfigurationManager.getProperty("search.dir");
@@ -121,9 +143,23 @@ public class DSIndexer
/** The analyzer for this DSpace instance */ /** The analyzer for this DSpace instance */
private static Analyzer analyzer = null; private static Analyzer analyzer = null;
// Static initialisation of index configuration / /** Static initialisation of index configuration */
private static IndexConfig[] indexConfigArr = new IndexConfig[0]; /** Includes backwards compatible default configuration */
private static IndexConfig[] indexConfigArr = new IndexConfig[]
{
new IndexConfig("author", "dc", "contributor", Item.ANY, "text") ,
new IndexConfig("author", "dc", "creator", Item.ANY, "text"),
new IndexConfig("author", "dc", "description", "statementofresponsibility", "text"),
new IndexConfig("title", "dc", "title", Item.ANY, "text"),
new IndexConfig("keyword", "dc", "subject", Item.ANY, "text"),
new IndexConfig("abstract", "dc", "description", "abstract", "text"),
new IndexConfig("abstract", "dc", "description", "tableofcontents", "text"),
new IndexConfig("series", "dc", "relation", "ispartofseries", "text"),
new IndexConfig("mimetype", "dc", "format", "mimetype", "text"),
new IndexConfig("sponsor", "dc", "description", "sponsorship", "text"),
new IndexConfig("identifier", "dc", "identifier", Item.ANY, "text")
};
static { static {
// calculate maxfieldlength // calculate maxfieldlength
@@ -133,7 +169,7 @@ public class DSIndexer
} }
// read in indexes from the config // read in indexes from the config
ArrayList indexConfigList = new ArrayList(); ArrayList<String> indexConfigList = new ArrayList<String>();
// read in search.index.1, search.index.2.... // read in search.index.1, search.index.2....
for (int i = 1; ConfigurationManager.getProperty("search.index." + i) != null; i++) for (int i = 1; ConfigurationManager.getProperty("search.index." + i) != null; i++)
@@ -148,7 +184,7 @@ public class DSIndexer
for (int i = 0; i < indexConfigList.size(); i++) for (int i = 0; i < indexConfigList.size(); i++)
{ {
indexConfigArr[i] = new IndexConfig(); indexConfigArr[i] = new IndexConfig();
String index = (String) indexConfigList.get(i); String index = indexConfigList.get(i);
String[] configLine = index.split(":"); String[] configLine = index.split(":");
@@ -172,6 +208,11 @@ public class DSIndexer
throw new RuntimeException( throw new RuntimeException(
"Malformed configuration line: search.index." + i); "Malformed configuration line: search.index." + i);
} }
if (configLine.length > 2)
{
indexConfigArr[i].type = configLine[2];
}
} }
} }
@@ -246,7 +287,7 @@ public class DSIndexer
Item item = (Item)dso; Item item = (Item)dso;
if (item.isArchived() && !item.isWithdrawn()) if (item.isArchived() && !item.isWithdrawn())
{ {
if(requiresIndexing(handle, ((Item)dso).getLastModified()) || force) if (requiresIndexing(handle, ((Item)dso).getLastModified()) || force)
{ {
Document doc = buildDocument(context, (Item) dso); Document doc = buildDocument(context, (Item) dso);
@@ -696,7 +737,7 @@ public class DSIndexer
* to determine if the index is stale. * to determine if the index is stale.
* *
* @param handle * @param handle
* @param dso * @param lastModified
* @return * @return
* @throws SQLException * @throws SQLException
* @throws IOException * @throws IOException
@@ -810,17 +851,17 @@ public class DSIndexer
throws SQLException, IOException throws SQLException, IOException
{ {
// Create Lucene Document // Create Lucene Document
Document doc = buildDocument(Constants.COMMUNITY, community.getHandle(), null); Document doc = buildDocument(Constants.COMMUNITY, community.getID(), community.getHandle(), null);
// and populate it // and populate it
String name = community.getMetadata("name"); String name = community.getMetadata("name");
if(name != null) if (name != null)
{ {
doc.add(new Field("name", name, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("name", name, Field.Store.NO, Field.Index.TOKENIZED));
doc.add(new Field("default", name, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("default", name, Field.Store.NO, Field.Index.TOKENIZED));
} }
return doc; return doc;
} }
@@ -839,15 +880,15 @@ public class DSIndexer
String location_text = buildCollectionLocationString(context, collection); String location_text = buildCollectionLocationString(context, collection);
// Create Lucene Document // Create Lucene Document
Document doc = buildDocument(Constants.COLLECTION, collection.getHandle(), location_text); Document doc = buildDocument(Constants.COLLECTION, collection.getID(), collection.getHandle(), location_text);
// and populate it // and populate it
String name = collection.getMetadata("name"); String name = collection.getMetadata("name");
if(name != null) if (name != null)
{ {
doc.add(new Field("name", name, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("name", name, Field.Store.NO, Field.Index.TOKENIZED));
doc.add(new Field("default", name, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("default", name, Field.Store.NO, Field.Index.TOKENIZED));
} }
return doc; return doc;
@@ -866,7 +907,6 @@ public class DSIndexer
private static Document buildDocument(Context context, Item item) private static Document buildDocument(Context context, Item item)
throws SQLException, IOException throws SQLException, IOException
{ {
String handle = item.getHandle(); String handle = item.getHandle();
if(handle == null) if(handle == null)
@@ -877,7 +917,7 @@ public class DSIndexer
// get the location string (for searching by collection & community) // get the location string (for searching by collection & community)
String location = buildItemLocationString(context, item); String location = buildItemLocationString(context, item);
Document doc = buildDocument(Constants.ITEM, handle, location); Document doc = buildDocument(Constants.ITEM, item.getID(), handle, location);
log.debug("Building Item: " + handle); log.debug("Building Item: " + handle);
@@ -902,132 +942,71 @@ public class DSIndexer
mydc = item.getMetadata(indexConfigArr[i].schema, indexConfigArr[i].element, indexConfigArr[i].qualifier, Item.ANY); mydc = item.getMetadata(indexConfigArr[i].schema, indexConfigArr[i].element, indexConfigArr[i].qualifier, Item.ANY);
} }
// put them all from an array of strings to one string for
// writing out pack all of the arrays of DCValues into plain
// text strings for the indexer
String content_text = "";
for (j = 0; j < mydc.length; j++) for (j = 0; j < mydc.length; j++)
{ {
content_text = new String(content_text + mydc[j].value + " "); if (!StringUtils.isEmpty(mydc[j].value))
{
if ("timestamp".equalsIgnoreCase(indexConfigArr[i].type))
{
Date d = toDate(mydc[j].value);
if (d != null)
{
doc.add( new Field(indexConfigArr[i].indexName,
DateTools.dateToString(d, DateTools.Resolution.SECOND),
Field.Store.NO,
Field.Index.TOKENIZED));
}
}
else if ("date".equalsIgnoreCase(indexConfigArr[i].type))
{
Date d = toDate(mydc[j].value);
if (d != null)
{
doc.add( new Field(indexConfigArr[i].indexName,
DateTools.dateToString(d, DateTools.Resolution.DAY),
Field.Store.NO,
Field.Index.TOKENIZED));
}
}
else
{
// TODO: use a delegate to allow custom 'types' to be used to reformat the field
doc.add( new Field(indexConfigArr[i].indexName,
mydc[j].value,
Field.Store.NO,
Field.Index.TOKENIZED));
}
doc.add( new Field("default", mydc[j].value, Field.Store.NO, Field.Index.TOKENIZED));
}
} }
// arranges content with fields in ArrayLists with same index to
// put
// into hash later
k = fields.indexOf(indexConfigArr[i].indexName);
if (k < 0)
{
fields.add(indexConfigArr[i].indexName);
content.add(content_text);
}
else
{
content_text = new String(content_text
+ (String) content.get(k) + " ");
content.set(k, content_text);
}
}
// build the hash
for (int i = 0; i < fields.size(); i++)
{
doc.add(
new Field(
(String) fields.get(i),
(String) content.get(i),
Field.Store.YES, Field.Index.TOKENIZED
));
doc.add(new Field("default", (String) content.get(i), Field.Store.YES, Field.Index.TOKENIZED));
}
}
else
// if no search indexes found in cfg file, for backward compatibility
{
// extract metadata (ANY is wildcard from Item class)
DCValue[] authors = item.getDC("contributor", Item.ANY, Item.ANY);
for (j = 0; j < authors.length; j++)
{
doc.add(new Field("author", authors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", authors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] creators = item.getDC("creator", Item.ANY, Item.ANY);
for (j = 0; j < creators.length; j++) //also authors
{
doc.add(new Field("author", creators[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", creators[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] sors = item.getDC("description", "statementofresponsibility", Item.ANY);
for (j = 0; j < sors.length; j++) //also authors
{
doc.add(new Field("author", sors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", sors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] titles = item.getDC("title", Item.ANY, Item.ANY);
for (j = 0; j < titles.length; j++)
{
doc.add(new Field("title", titles[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", titles[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] keywords = item.getDC("subject", Item.ANY, Item.ANY);
for (j = 0; j < keywords.length; j++)
{
doc.add(new Field("keyword", keywords[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", keywords[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] abstracts = item.getDC("description", "abstract", Item.ANY);
for (j = 0; j < abstracts.length; j++)
{
doc.add(new Field("abstract", abstracts[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", abstracts[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] tocs = item.getDC("description", "tableofcontents", Item.ANY);
for (j = 0; j < tocs.length; j++)
{
doc.add(new Field("abstract", tocs[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", tocs[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] series = item.getDC("relation", "ispartofseries", Item.ANY);
for (j = 0; j < series.length; j++)
{
doc.add(new Field("series", series[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", series[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] mimetypes = item.getDC("format", "mimetype", Item.ANY);
for (j = 0; j < mimetypes.length; j++)
{
doc.add(new Field("mimetype", mimetypes[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", mimetypes[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] sponsors = item.getDC("description", "sponsorship", Item.ANY);
for (j = 0; j < sponsors.length; j++)
{
doc.add(new Field("sponsor", sponsors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", sponsors[j].value, Field.Store.YES, Field.Index.TOKENIZED));
}
DCValue[] identifiers = item.getDC("identifier", Item.ANY, Item.ANY);
for (j = 0; j < identifiers.length; j++)
{
doc.add(new Field("identifier", identifiers[j].value, Field.Store.YES, Field.Index.TOKENIZED));
doc.add(new Field("default", identifiers[j].value, Field.Store.YES, Field.Index.TOKENIZED));
} }
} }
log.debug(" Added Metadata"); log.debug(" Added Metadata");
try
{
// Now get the configured sort options, and add those as untokenized fields
// Note that we will use the sort order delegates to normalise the values written
for (SortOption so : SortOption.getSortOptions())
{
String[] somd = so.getMdBits();
DCValue[] dcv = item.getMetadata(somd[0], somd[1], somd[2], Item.ANY);
if (dcv.length > 0)
{
String value = OrderFormat.makeSortString(dcv[0].value, dcv[0].language, so.getType());
doc.add( new Field("sort_" + so.getName(), value, Field.Store.NO, Field.Index.UN_TOKENIZED) );
}
}
}
catch (Exception e)
{
log.error(e.getMessage(),e);
}
log.debug(" Added Sorting");
try try
{ {
// now get full text of any bitstreams in the TEXT bundle // now get full text of any bitstreams in the TEXT bundle
@@ -1077,11 +1056,11 @@ public class DSIndexer
* Create Lucene document with all the shared fields initialized. * Create Lucene document with all the shared fields initialized.
* *
* @param type Type of DSpace Object * @param type Type of DSpace Object
* @param handle * @param id
* @param location *@param handle
* @return * @param location @return
*/ */
private static Document buildDocument(int type, String handle, String location) private static Document buildDocument(int type, int id, String handle, String location)
{ {
Document doc = new Document(); Document doc = new Document();
@@ -1089,10 +1068,14 @@ public class DSIndexer
// (not tokenized, but it is indexed) // (not tokenized, but it is indexed)
doc.add(new Field(LAST_INDEXED_FIELD, Long.toString(System.currentTimeMillis()), Field.Store.YES, Field.Index.UN_TOKENIZED)); doc.add(new Field(LAST_INDEXED_FIELD, Long.toString(System.currentTimeMillis()), Field.Store.YES, Field.Index.UN_TOKENIZED));
// KEPT FOR BACKWARDS COMPATIBILITY
// do location, type, handle first // do location, type, handle first
doc.add(new Field("type", Integer.toString(type), Field.Store.YES, Field.Index.NO)); doc.add(new Field("type", Integer.toString(type), Field.Store.YES, Field.Index.NO));
// New fields to weaken the dependence on handles, and allow for faster list display
doc.add(new Field("search.resourcetype", Integer.toString(type), Field.Store.YES, Field.Index.NO));
doc.add(new Field("search.resourceid", Integer.toString(id), Field.Store.YES, Field.Index.NO));
// want to be able to search for handle, so use keyword // want to be able to search for handle, so use keyword
// (not tokenized, but it is indexed) // (not tokenized, but it is indexed)
if (handle != null) if (handle != null)
@@ -1105,17 +1088,72 @@ public class DSIndexer
doc.add(new Field("handle", handle, Field.Store.YES, Field.Index.UN_TOKENIZED)); doc.add(new Field("handle", handle, Field.Store.YES, Field.Index.UN_TOKENIZED));
// add to full text index // add to full text index
doc.add(new Field("default", handle, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("default", handle, Field.Store.NO, Field.Index.TOKENIZED));
} }
if(location != null) if(location != null)
{ {
doc.add(new Field("location", location, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("location", location, Field.Store.NO, Field.Index.TOKENIZED));
doc.add(new Field("default", location, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("default", location, Field.Store.NO, Field.Index.TOKENIZED));
} }
return doc; return doc;
} }
/**
* Helper function to retrieve a date using a best guess of the potential date encodings on a field
*
* @param t
* @return
*/
private static Date toDate(String t)
{
SimpleDateFormat[] dfArr;
// Choose the likely date formats based on string length
switch (t.length())
{
case 4:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy") };
break;
case 6:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyyMM") };
break;
case 7:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM") };
break;
case 8:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyyMMdd"), new SimpleDateFormat("yyyy MMM") };
break;
case 10:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM-dd") };
break;
case 11:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy MMM dd") };
break;
case 20:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") };
break;
default:
dfArr = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") };
break;
}
for (SimpleDateFormat df : dfArr)
{
try
{
// Parse the date
df.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC")));
return df.parse(t);
}
catch (ParseException pe)
{
log.error("Unable to parse date format", pe);
}
}
return null;
}
} }

View File

@@ -40,7 +40,6 @@
package org.dspace.search; package org.dspace.search;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -56,6 +55,8 @@ import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher; import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.oro.text.perl.Perl5Util; import org.apache.oro.text.perl.Perl5Util;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
@@ -63,6 +64,7 @@ import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.sort.SortOption;
// issues // issues
// need to filter query string for security // need to filter query string for security
@@ -123,10 +125,12 @@ public class DSQuery
String querystring = args.getQuery(); String querystring = args.getQuery();
QueryResults qr = new QueryResults(); QueryResults qr = new QueryResults();
List hitHandles = new ArrayList(); List hitHandles = new ArrayList();
List hitTypes = new ArrayList(); List hitIds = new ArrayList();
List hitTypes = new ArrayList();
// set up the QueryResults object // set up the QueryResults object
qr.setHitHandles(hitHandles); qr.setHitHandles(hitHandles);
qr.setHitIds(hitIds);
qr.setHitTypes(hitTypes); qr.setHitTypes(hitTypes);
qr.setStart(args.getStart()); qr.setStart(args.getStart());
qr.setPageSize(args.getPageSize()); qr.setPageSize(args.getPageSize());
@@ -159,8 +163,18 @@ public class DSQuery
} }
Query myquery = qp.parse(querystring); Query myquery = qp.parse(querystring);
Hits hits = searcher.search(myquery); Hits hits = null;
if (args.getSortOption() == null)
{
hits = searcher.search(myquery, new Sort(new SortField[] { new SortField("type"), SortField.FIELD_SCORE }));
}
else
{
SortField[] sortFields = new SortField[] { new SortField("type"), new SortField("sort_" + args.getSortOption().getName(), SortOption.DESCENDING.equals(args.getSortOrder())), SortField.FIELD_SCORE };
hits = searcher.search(myquery, new Sort(sortFields));
}
// set total number of hits // set total number of hits
qr.setHitCount(hits.length()); qr.setHitCount(hits.length());
@@ -181,52 +195,47 @@ public class DSQuery
{ {
Document d = hits.doc(i); Document d = hits.doc(i);
String resourceId = d.get("search.resourceid");
String resourceType = d.get("search.resourcetype");
String handleText = d.get("handle"); String handleText = d.get("handle");
String handletype = d.get("type"); String handleType = d.get("type");
hitHandles.add(handleText); switch (Integer.parseInt( resourceType != null ? resourceType : handleType))
{
case Constants.ITEM:
hitTypes.add(new Integer(Constants.ITEM));
break;
if (handletype.equals("" + Constants.ITEM)) case Constants.COLLECTION:
{ hitTypes.add(new Integer(Constants.COLLECTION));
hitTypes.add(new Integer(Constants.ITEM)); break;
}
else if (handletype.equals("" + Constants.COLLECTION)) case Constants.COMMUNITY:
{ hitTypes.add(new Integer(Constants.COMMUNITY));
hitTypes.add(new Integer(Constants.COLLECTION)); break;
}
else if (handletype.equals("" + Constants.COMMUNITY))
{
hitTypes.add(new Integer(Constants.COMMUNITY));
}
else
{
// error! unknown type!
} }
hitHandles.add( handleText );
hitIds.add( resourceId == null ? null: Integer.parseInt(resourceId) );
} }
} }
} }
catch (NumberFormatException e) catch (NumberFormatException e)
{ {
log log.warn(LogManager.getHeader(c, "Number format exception", "" + e));
.warn(LogManager.getHeader(c, "Number format exception", ""
+ e));
qr.setErrorMsg("Number format exception"); qr.setErrorMsg("Number format exception");
} }
catch (ParseException e) catch (ParseException e)
{ {
// a parse exception - log and return null results // a parse exception - log and return null results
log.warn(LogManager.getHeader(c, "Invalid search string", "" + e)); log.warn(LogManager.getHeader(c, "Invalid search string", "" + e));
qr.setErrorMsg("Invalid search string"); qr.setErrorMsg("Invalid search string");
} }
catch (TokenMgrError tme) catch (TokenMgrError tme)
{ {
// Similar to parse exception // Similar to parse exception
log log.warn(LogManager.getHeader(c, "Invalid search string", "" + tme));
.warn(LogManager.getHeader(c, "Invalid search string", ""
+ tme));
qr.setErrorMsg("Invalid search string"); qr.setErrorMsg("Invalid search string");
} }
catch(BooleanQuery.TooManyClauses e) catch(BooleanQuery.TooManyClauses e)
@@ -387,6 +396,25 @@ public class DSQuery
} }
} }
/**
* Close any IndexSearcher that is currently open.
*/
public static void close()
{
if (searcher != null)
{
try
{
searcher.close();
searcher = null;
}
catch (IOException ioe)
{
log.error("DSQuery: Unable to close open IndexSearcher", ioe);
}
}
}
public static void main(String[] args) public static void main(String[] args)
{ {
if (args.length > 0) if (args.length > 0)

View File

@@ -47,6 +47,7 @@ import java.util.Iterator;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.sort.SortOption;
import org.apache.oro.text.perl.Perl5Util; import org.apache.oro.text.perl.Perl5Util;
@@ -64,6 +65,10 @@ public class QueryArgs
private int pageSize = 10; private int pageSize = 10;
private SortOption sortOption = null;
private String sortOrder = SortOption.ASCENDING;
/** /**
* set the query string * set the query string
* *
@@ -128,6 +133,26 @@ public class QueryArgs
return pageSize; return pageSize;
} }
public SortOption getSortOption()
{
return sortOption;
}
public void setSortOption(SortOption sortOption)
{
this.sortOption = sortOption;
}
public String getSortOrder()
{
return sortOrder;
}
public void setSortOrder(String sortOrder)
{
this.sortOrder = sortOrder;
}
/** /**
* Builds an advanced-query description string. * Builds an advanced-query description string.
* *

View File

@@ -56,8 +56,8 @@ public class QueryResults
private List hitHandles; // handles of content (items, collections, private List hitHandles; // handles of content (items, collections,
// communities) // communities)
private List hitTypes; // Integers from Constants defng types of private List hitTypes; // Resource type - from Constants
// corresponding handles private List hitIds; // Resource ids
private String errorMsg; //error string, if there is one private String errorMsg; //error string, if there is one
@@ -112,6 +112,18 @@ public class QueryResults
return hitHandles; return hitHandles;
} }
/** set the List of ids corresponding to hits */
public void setHitIds(List myHits)
{
hitIds = myHits;
}
/** get the List of handles corresponding to hits */
public List getHitIds()
{
return hitIds;
}
/** set the List of types corresponding to handles */ /** set the List of types corresponding to handles */
public void setHitTypes(List newTypes) public void setHitTypes(List newTypes)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrder.java * OrderFormat.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,11 +38,15 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import org.apache.log4j.LogManager; import org.apache.log4j.LogManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.core.PluginManager; import org.dspace.core.PluginManager;
import org.dspace.sort.OrderFormatDelegate;
import org.dspace.sort.OrderFormatAuthor;
import org.dspace.sort.OrderFormatTitle;
import org.dspace.sort.OrderFormatText;
/** /**
* Class implementing static helpers for anywhere that interacts with the sort columns * Class implementing static helpers for anywhere that interacts with the sort columns
@@ -52,16 +56,16 @@ import org.dspace.core.PluginManager;
* *
* Types can be defined or configured using the plugin manager: * Types can be defined or configured using the plugin manager:
* *
* plugin.named.org.dspace.browse.BrowseOrderDelegate= * plugin.named.org.dspace.sort.OrderFormatDelegate=
* org.dspace.browse.BrowseOrderTitleMarc21=title * org.dspace.sort.OrderFormatTitleMarc21=title
* org.dspace.browse.BrowseOrderAuthor=author * org.dspace.sort.OrderFormatAuthor=author
* *
* The following standard types have been defined by default, but can be reconfigured * The following standard types have been defined by default, but can be reconfigured
* via the plugin manager: * via the plugin manager:
* *
* author = org.dspace.browse.BrowseOrderAuthor * author = org.dspace.sort.OrderFormatAuthor
* title = org.dspace.browse.BrowseOrderTitle * title = org.dspace.sort.OrderFormatTitle
* text = org.dspace.browse.BrowseOrderText * text = org.dspace.sort.OrderFormatText
* *
* IMPORTANT - If you change any of the orderings, you need to rebuild the browse sort columns * IMPORTANT - If you change any of the orderings, you need to rebuild the browse sort columns
* (ie. run 'index-all', or 'dsrun org.dspace.browse.InitializeBrowse') * (ie. run 'index-all', or 'dsrun org.dspace.browse.InitializeBrowse')
@@ -69,50 +73,50 @@ import org.dspace.core.PluginManager;
* @author Graham Triggs * @author Graham Triggs
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class BrowseOrder public class OrderFormat
{ {
private final static Logger log = LogManager.getLogger(BrowseOrder.class); private final static Logger log = LogManager.getLogger(OrderFormat.class);
public final static String AUTHOR = "author"; public final static String AUTHOR = "author";
public final static String TITLE = "title"; public final static String TITLE = "title";
public final static String TEXT = "text"; public final static String TEXT = "text";
// Array of all available order delegates - avoids excessive calls to plugin manager // Array of all available order delegates - avoids excessive calls to plugin manager
private final static String[] delegates = PluginManager.getAllPluginNames(BrowseOrderDelegate.class); private final static String[] delegates = PluginManager.getAllPluginNames(OrderFormatDelegate.class);
private final static BrowseOrderDelegate authorDelegate = new BrowseOrderAuthor(); private final static OrderFormatDelegate authorDelegate = new OrderFormatAuthor();
private final static BrowseOrderDelegate titleDelegate = new BrowseOrderTitle(); private final static OrderFormatDelegate titleDelegate = new OrderFormatTitle();
private final static BrowseOrderDelegate textDelegate = new BrowseOrderText(); private final static OrderFormatDelegate textDelegate = new OrderFormatText();
/** /**
* Generate a sort string for the given DC metadata * Generate a sort string for the given DC metadata
*/ */
public static String makeSortString(String value, String language, String type) public static String makeSortString(String value, String language, String type)
{ {
BrowseOrderDelegate delegate = null; OrderFormatDelegate delegate = null;
// If a named index has been supplied // If a named index has been supplied
if (type != null && type.length() > 0) if (type != null && type.length() > 0)
{ {
// Use a delegate if one is configured // Use a delegate if one is configured
if ((delegate = BrowseOrder.getDelegate(type)) != null) if ((delegate = OrderFormat.getDelegate(type)) != null)
{ {
return delegate.makeSortString(value, language); return delegate.makeSortString(value, language);
} }
} }
// No delegates found, so apply defaults // No delegates found, so apply defaults
if (type.equalsIgnoreCase(BrowseOrder.AUTHOR) && authorDelegate != null) if (type.equalsIgnoreCase(OrderFormat.AUTHOR) && authorDelegate != null)
{ {
return authorDelegate.makeSortString(value, language); return authorDelegate.makeSortString(value, language);
} }
if (type.equalsIgnoreCase(BrowseOrder.TITLE) && titleDelegate != null) if (type.equalsIgnoreCase(OrderFormat.TITLE) && titleDelegate != null)
{ {
return titleDelegate.makeSortString(value, language); return titleDelegate.makeSortString(value, language);
} }
if (type.equalsIgnoreCase(BrowseOrder.TEXT) && textDelegate != null) if (type.equalsIgnoreCase(OrderFormat.TEXT) && textDelegate != null)
{ {
return textDelegate.makeSortString(value, language); return textDelegate.makeSortString(value, language);
} }
@@ -123,7 +127,7 @@ public class BrowseOrder
/** /**
* Retrieve the named delegate * Retrieve the named delegate
*/ */
private static BrowseOrderDelegate getDelegate(String name) private static OrderFormatDelegate getDelegate(String name)
{ {
if (name != null && name.length() > 0) if (name != null && name.length() > 0)
{ {
@@ -132,7 +136,7 @@ public class BrowseOrder
{ {
if (delegates[idx].equals(name)) if (delegates[idx].equals(name))
{ {
return (BrowseOrderDelegate)PluginManager.getNamedPlugin(BrowseOrderDelegate.class, name); return (OrderFormatDelegate)PluginManager.getNamedPlugin(OrderFormatDelegate.class, name);
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrderAuthor.java * OrderFormatAuthor.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,18 +38,19 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import org.dspace.text.filter.DecomposeDiactritics; import org.dspace.text.filter.DecomposeDiactritics;
import org.dspace.text.filter.LowerCaseAndTrim; import org.dspace.text.filter.LowerCaseAndTrim;
import org.dspace.text.filter.TextFilter; import org.dspace.text.filter.TextFilter;
import org.dspace.browse.AbstractTextFilterOFD;
/** /**
* Standard author ordering delegate implementation * Standard author ordering delegate implementation
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public class BrowseOrderAuthor extends AbstractTextFilterBOD public class OrderFormatAuthor extends AbstractTextFilterOFD
{ {
{ {
filters = new TextFilter[] { new DecomposeDiactritics(), filters = new TextFilter[] { new DecomposeDiactritics(),

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrderDelegate.java * OrderFormatDelegate.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,14 +38,14 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
/** /**
* Interface for browse order delegates * Interface for browse order delegates
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public interface BrowseOrderDelegate public interface OrderFormatDelegate
{ {
/** /**
* Prepare the appropriate sort string for the given value in the * Prepare the appropriate sort string for the given value in the

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrderText.java * OrderFormatText.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,18 +38,19 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import org.dspace.text.filter.DecomposeDiactritics; import org.dspace.text.filter.DecomposeDiactritics;
import org.dspace.text.filter.LowerCaseAndTrim; import org.dspace.text.filter.LowerCaseAndTrim;
import org.dspace.text.filter.TextFilter; import org.dspace.text.filter.TextFilter;
import org.dspace.browse.AbstractTextFilterOFD;
/** /**
* Standard text ordering delegate implementation * Standard text ordering delegate implementation
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public class BrowseOrderText extends AbstractTextFilterBOD public class OrderFormatText extends AbstractTextFilterOFD
{ {
{ {
filters = new TextFilter[] { new DecomposeDiactritics(), filters = new TextFilter[] { new DecomposeDiactritics(),

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrderTitle.java * OrderFormatTitle.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,19 +38,20 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import org.dspace.text.filter.DecomposeDiactritics; import org.dspace.text.filter.DecomposeDiactritics;
import org.dspace.text.filter.LowerCaseAndTrim; import org.dspace.text.filter.LowerCaseAndTrim;
import org.dspace.text.filter.StandardInitialArticleWord; import org.dspace.text.filter.StandardInitialArticleWord;
import org.dspace.text.filter.TextFilter; import org.dspace.text.filter.TextFilter;
import org.dspace.browse.AbstractTextFilterOFD;
/** /**
* Standard title ordering delegate implementation * Standard title ordering delegate implementation
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public class BrowseOrderTitle extends AbstractTextFilterBOD public class OrderFormatTitle extends AbstractTextFilterOFD
{ {
{ {
filters = new TextFilter[] { new StandardInitialArticleWord(), filters = new TextFilter[] { new StandardInitialArticleWord(),

View File

@@ -1,5 +1,5 @@
/* /*
* BrowseOrderTitleMarc21.java * OrderFormatTitleMarc21.java
* *
* Version: $Revision: 1.0 $ * Version: $Revision: 1.0 $
* *
@@ -38,16 +38,17 @@
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import org.dspace.text.filter.*; import org.dspace.text.filter.*;
import org.dspace.browse.AbstractTextFilterOFD;
/** /**
* MARC 21 title ordering delegate implementation * MARC 21 title ordering delegate implementation
* *
* @author Graham Triggs * @author Graham Triggs
*/ */
public class BrowseOrderTitleMarc21 extends AbstractTextFilterBOD public class OrderFormatTitleMarc21 extends AbstractTextFilterOFD
{ {
{ {
filters = new TextFilter[] { new MARC21InitialArticleWord(), filters = new TextFilter[] { new MARC21InitialArticleWord(),

View File

@@ -0,0 +1,68 @@
/*
* SortException.java
*
* Version: $Revision: $
*
* Date: $Date: $
*
* Copyright (c) 2002-2007, Hewlett-Packard Company and Massachusetts
* Institute of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Hewlett-Packard Company nor the name of the
* Massachusetts Institute of Technology nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package org.dspace.sort;
/**
* Just a quick SortException class to give us the relevant data type
*/
public class SortException extends Exception
{
public SortException()
{
super();
}
public SortException(String message)
{
super(message);
}
public SortException(String message, Throwable cause)
{
super(message, cause);
}
public SortException(Throwable cause)
{
super(cause);
}
}

View File

@@ -33,7 +33,7 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE. * DAMAGE.
*/ */
package org.dspace.browse; package org.dspace.sort;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -86,10 +86,10 @@ public class SortOption
* @param name * @param name
* @param md * @param md
* @param type * @param type
* @throws BrowseException * @throws SortException
*/ */
public SortOption(int number, String name, String md, String type) public SortOption(int number, String name, String md, String type)
throws BrowseException throws SortException
{ {
this.name = name; this.name = name;
this.type = type; this.type = type;
@@ -104,10 +104,10 @@ public class SortOption
* *
* @param number * @param number
* @param definition * @param definition
* @throws BrowseException * @throws SortException
*/ */
public SortOption(int number, String definition) public SortOption(int number, String definition)
throws BrowseException throws SortException
{ {
this.number = number; this.number = number;
@@ -117,7 +117,7 @@ public class SortOption
if (!matcher.matches()) if (!matcher.matches())
{ {
throw new BrowseException("Sort Order configuration is not valid: webui.browse.sort-order." + throw new SortException("Sort Order configuration is not valid: webui.itemlist.sort-option." +
number + " = " + definition); number + " = " + definition);
} }
@@ -219,10 +219,10 @@ public class SortOption
/** /**
* Tell the class to generate the metadata bits * Tell the class to generate the metadata bits
* *
* @throws BrowseException * @throws SortException
*/ */
public void generateMdBits() public void generateMdBits()
throws BrowseException throws SortException
{ {
try try
{ {
@@ -230,7 +230,7 @@ public class SortOption
} }
catch(IOException e) catch(IOException e)
{ {
throw new BrowseException(e); throw new SortException(e);
} }
} }
@@ -300,7 +300,7 @@ public class SortOption
/** /**
* @return a map of the configured sort options * @return a map of the configured sort options
*/ */
public static Map<Integer, SortOption> getSortOptionsMap() throws BrowseException public static Map<Integer, SortOption> getSortOptionsMap() throws SortException
{ {
if (SortOption.sortOptionsMap != null) if (SortOption.sortOptionsMap != null)
return SortOption.sortOptionsMap; return SortOption.sortOptionsMap;
@@ -320,9 +320,9 @@ public class SortOption
/** /**
* Return all the configured sort options * Return all the configured sort options
* @return * @return
* @throws BrowseException * @throws SortException
*/ */
public static Set<SortOption> getSortOptions() throws BrowseException public static Set<SortOption> getSortOptions() throws SortException
{ {
if (SortOption.sortOptionsSet != null) if (SortOption.sortOptionsSet != null)
return SortOption.sortOptionsSet; return SortOption.sortOptionsSet;
@@ -333,7 +333,7 @@ public class SortOption
int idx = 1; int idx = 1;
String option; String option;
while ( ((option = ConfigurationManager.getProperty("webui.browse.sort-option." + idx))) != null) while ( ((option = ConfigurationManager.getProperty("webui.itemlist.sort-option." + idx))) != null)
{ {
SortOption so = new SortOption(idx, option); SortOption so = new SortOption(idx, option);
SortOption.sortOptionsSet.add(so); SortOption.sortOptionsSet.add(so);
@@ -348,9 +348,9 @@ public class SortOption
* Get the defined sort option by number (.1, .2, etc) * Get the defined sort option by number (.1, .2, etc)
* @param number * @param number
* @return * @return
* @throws BrowseException * @throws SortException
*/ */
public static SortOption getSortOption(int number) throws BrowseException public static SortOption getSortOption(int number) throws SortException
{ {
for (SortOption so : SortOption.getSortOptions()) for (SortOption so : SortOption.getSortOptions())
{ {
@@ -364,9 +364,9 @@ public class SortOption
/** /**
* Get the default sort option - initially, just the first one defined * Get the default sort option - initially, just the first one defined
* @return * @return
* @throws BrowseException * @throws SortException
*/ */
public static SortOption getDefaultSortOption() throws BrowseException public static SortOption getDefaultSortOption() throws SortException
{ {
for (SortOption so : getSortOptions()) for (SortOption so : getSortOptions())
return so; return so;

View File

@@ -46,7 +46,8 @@ import org.dspace.browse.BrowserScope;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowseInfo;
import org.dspace.browse.BrowseException; import org.dspace.browse.BrowseException;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.content.Item; import org.dspace.content.Item;
@@ -120,6 +121,11 @@ public class RecentSubmissionsManager
return rs; return rs;
} }
catch (SortException se)
{
log.error("caught exception: ", se);
throw new RecentSubmissionsException(se);
}
catch (BrowseException e) catch (BrowseException e)
{ {
log.error("caught exception: ", e); log.error("caught exception: ", e);

View File

@@ -53,6 +53,7 @@ import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Utils; import org.dspace.core.Utils;
import org.dspace.storage.bitstore.BitstreamStorageManager; import org.dspace.storage.bitstore.BitstreamStorageManager;
import org.dspace.sort.SortOption;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;

View File

@@ -15,7 +15,8 @@ import org.dspace.browse.BrowseException;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowseInfo;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
@@ -251,6 +252,11 @@ public abstract class AbstractBrowserServlet extends DSpaceServlet
return scope; return scope;
} }
catch (SortException se)
{
log.error("caught exception: ", se);
throw new ServletException(se);
}
catch (BrowseException e) catch (BrowseException e)
{ {
log.error("caught exception: ", e); log.error("caught exception: ", e);

View File

@@ -66,7 +66,8 @@ import org.dspace.browse.BrowseException;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowseInfo;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
@@ -436,6 +437,11 @@ public class FeedServlet extends DSpaceServlet
return channel; return channel;
} }
catch (SortException se)
{
log.error("caught exception: ", se);
throw new IOException(se);
}
catch (BrowseException e) catch (BrowseException e)
{ {
log.error("caught exception: ", e); log.error("caught exception: ", e);

View File

@@ -65,6 +65,7 @@ import org.dspace.handle.HandleManager;
import org.dspace.search.DSQuery; import org.dspace.search.DSQuery;
import org.dspace.search.QueryArgs; import org.dspace.search.QueryArgs;
import org.dspace.search.QueryResults; import org.dspace.search.QueryResults;
import org.dspace.sort.SortOption;
/** /**
* Servlet for handling a simple search. * Servlet for handling a simple search.
@@ -97,6 +98,8 @@ public class SimpleSearchServlet extends DSpaceServlet
int start = UIUtil.getIntParameter(request, "start"); int start = UIUtil.getIntParameter(request, "start");
String advanced = request.getParameter("advanced"); String advanced = request.getParameter("advanced");
String fromAdvanced = request.getParameter("from_advanced"); String fromAdvanced = request.getParameter("from_advanced");
int sortBy = UIUtil.getIntParameter(request, "sort_by");
String order = request.getParameter("order");
String advancedQuery = ""; String advancedQuery = "";
HashMap queryHash = new HashMap(); HashMap queryHash = new HashMap();
@@ -117,6 +120,22 @@ public class SimpleSearchServlet extends DSpaceServlet
QueryResults qResults = null; QueryResults qResults = null;
QueryArgs qArgs = new QueryArgs(); QueryArgs qArgs = new QueryArgs();
try
{
qArgs.setSortOption(SortOption.getSortOption(sortBy));
if (SortOption.DESCENDING.equalsIgnoreCase(order))
{
qArgs.setSortOrder(SortOption.DESCENDING);
}
else
{
qArgs.setSortOrder(SortOption.ASCENDING);
}
}
catch (Exception e)
{
}
// if the "advanced" flag is set, build the query string from the // if the "advanced" flag is set, build the query string from the
// multiple query fields // multiple query fields
if (advanced != null) if (advanced != null)

View File

@@ -52,6 +52,7 @@ import org.dspace.content.ItemIterator;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.sort.SortOption;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;

View File

@@ -49,11 +49,10 @@
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ page import="org.dspace.browse.BrowseInfo" %> <%@ page import="org.dspace.browse.BrowseInfo" %>
<%@ page import="org.dspace.browse.SortOption" %> <%@ page import="org.dspace.sort.SortOption" %>
<%@ page import="org.dspace.content.Collection" %> <%@ page import="org.dspace.content.Collection" %>
<%@ page import="org.dspace.content.Community" %> <%@ page import="org.dspace.content.Community" %>
<%@ page import="org.dspace.browse.BrowseIndex" %> <%@ page import="org.dspace.browse.BrowseIndex" %>
<%@ page import="org.dspace.browse.SortOption" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ page import="org.dspace.core.ConfigurationManager" %>
<%@ page import="java.net.URLEncoder" %> <%@ page import="java.net.URLEncoder" %>
<%@ page import="java.util.Map" %> <%@ page import="java.util.Map" %>

View File

@@ -50,7 +50,7 @@
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %> <%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
<%@ page import="org.dspace.browse.BrowseInfo" %> <%@ page import="org.dspace.browse.BrowseInfo" %>
<%@ page import="org.dspace.browse.SortOption" %> <%@ page import="org.dspace.sort.SortOption" %>
<%@ page import="org.dspace.app.webui.util.UIUtil" %> <%@ page import="org.dspace.app.webui.util.UIUtil" %>

View File

@@ -78,7 +78,8 @@ import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowseInfo;
import org.dspace.browse.BrowseItem; import org.dspace.browse.BrowseItem;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.DCDate; import org.dspace.content.DCDate;
@@ -475,9 +476,9 @@ public class WithdrawnItems extends AbstractDSpaceTransformer implements
} }
} }
} }
catch (BrowseException be) catch (SortException se)
{ {
throw new WingException("Unable to get sort options", be); throw new WingException("Unable to get sort options", se);
} }
} }

View File

@@ -66,10 +66,10 @@ import org.dspace.browse.BrowseException;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseItem; import org.dspace.browse.BrowseItem;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@@ -324,6 +324,10 @@ public class CollectionViewer extends AbstractDSpaceTransformer implements Cache
BrowseEngine be = new BrowseEngine(context); BrowseEngine be = new BrowseEngine(context);
this.recentSubmissionItems = be.browse(scope).getResults(); this.recentSubmissionItems = be.browse(scope).getResults();
} }
catch (SortException se)
{
log.error("Caught SortException", se);
}
catch (BrowseException bex) catch (BrowseException bex)
{ {
log.error("Caught BrowseException", bex); log.error("Caught BrowseException", bex);

View File

@@ -67,11 +67,11 @@ import org.dspace.browse.BrowseException;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseItem; import org.dspace.browse.BrowseItem;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Collection; 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.content.Item;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@@ -375,6 +375,10 @@ public class CommunityViewer extends AbstractDSpaceTransformer implements Cachea
BrowseEngine be = new BrowseEngine(context); BrowseEngine be = new BrowseEngine(context);
this.recentSubmittedItems = be.browse(scope).getResults(); this.recentSubmittedItems = be.browse(scope).getResults();
} }
catch (SortException se)
{
log.error("Caught SortException", se);
}
catch (BrowseException bex) catch (BrowseException bex)
{ {
log.error("Caught BrowseException", bex); log.error("Caught BrowseException", bex);

View File

@@ -42,8 +42,6 @@ package org.dspace.app.xmlui.aspect.artifactbrowser;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@@ -80,13 +78,13 @@ import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowseInfo;
import org.dspace.browse.BrowseItem; import org.dspace.browse.BrowseItem;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.sort.SortException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.DCDate; import org.dspace.content.DCDate;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@@ -473,9 +471,9 @@ public class ConfigurableBrowse extends AbstractDSpaceTransformer implements
} }
} }
} }
catch (BrowseException be) catch (SortException se)
{ {
throw new WingException("Unable to get sort options", be); throw new WingException("Unable to get sort options", se);
} }
} }
@@ -623,21 +621,28 @@ public class ConfigurableBrowse extends AbstractDSpaceTransformer implements
} }
else if (bi.isItemIndex() && !bi.isInternalIndex()) else if (bi.isItemIndex() && !bi.isInternalIndex())
{ {
// If a default sort option is specified by the index, but it isn't try
// the same as sort option requested, attempt to find an index that
// is configured to use that sort by default
// This is so that we can then highlight the correct option in the navigation
SortOption bso = bi.getSortOption();
SortOption so = SortOption.getSortOption(sortBy);
if ( bso != null && bso != so)
{ {
BrowseIndex newBi = BrowseIndex.getBrowseIndex(so); // If a default sort option is specified by the index, but it isn't
if (newBi != null) // the same as sort option requested, attempt to find an index that
// is configured to use that sort by default
// This is so that we can then highlight the correct option in the navigation
SortOption bso = bi.getSortOption();
SortOption so = SortOption.getSortOption(sortBy);
if ( bso != null && bso != so)
{ {
bi = newBi; BrowseIndex newBi = BrowseIndex.getBrowseIndex(so);
type = bi.getName(); if (newBi != null)
{
bi = newBi;
type = bi.getName();
}
} }
} }
catch (SortException se)
{
throw new UIException("Unable to get sort options", se);
}
} }
params.scope.setBrowseIndex(bi); params.scope.setBrowseIndex(bi);

View File

@@ -70,7 +70,7 @@ import org.dspace.browse.BrowseEngine;
import org.dspace.browse.BrowseException; import org.dspace.browse.BrowseException;
import org.dspace.browse.BrowseIndex; import org.dspace.browse.BrowseIndex;
import org.dspace.browse.BrowserScope; import org.dspace.browse.BrowserScope;
import org.dspace.browse.SortOption; import org.dspace.sort.SortOption;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;

View File

@@ -474,7 +474,7 @@ plugin.single.org.dspace.app.webui.util.StyleSelection = \
# webui.browse.index.<n> = <index name> : item : <sort option name> : (asc | desc) # webui.browse.index.<n> = <index name> : item : <sort option name> : (asc | desc)
# #
# sort option name: this is the sorting to be applied to the display. It must match the # sort option name: this is the sorting to be applied to the display. It must match the
# name given to one of the webui.browse.sort-option entries given below. # name given to one of the webui.itemlist.sort-option entries given below.
# #
# The final part of the configuration is optional, and specifies the default ordering # The final part of the configuration is optional, and specifies the default ordering
# for the index - whether it is ASCending (the default, and best for text indexes), or # for the index - whether it is ASCending (the default, and best for text indexes), or
@@ -499,13 +499,13 @@ webui.browse.index.4 = subject:metadata:dc.subject.*:text
# Set the options for what can be sorted by # Set the options for what can be sorted by
# #
# Sort options will be available when browsing a list of items (i.e. only in # Sort options will be available when browsing a list of items (i.e. an 'item' browse,
# "full" mode, not "single" mode). You can define an arbitrary number of fields # or search results). You can define an arbitrary number of fields
# to sort on, irrespective of which fields you display using webui.itemlist.columns # to sort on, irrespective of which fields you display using webui.itemlist.columns
# #
# the format is: # the format is:
# #
# webui.browse.sort-option.<n> = <option name> : \ # webui.itemlist.sort-option.<n> = <option name> : \
# <schema prefix>.<element>[.<qualifier>|.*] : \ # <schema prefix>.<element>[.<qualifier>|.*] : \
# (date | text | ...) : (show | hide) # (date | text | ...) : (show | hide)
# #
@@ -518,9 +518,9 @@ webui.browse.index.4 = subject:metadata:dc.subject.*:text
# you need to define a specific date sort for use by the recent items lists, # you need to define a specific date sort for use by the recent items lists,
# but otherwise don't want users to choose that option. # but otherwise don't want users to choose that option.
# #
webui.browse.sort-option.1 = title:dc.title:title webui.itemlist.sort-option.1 = title:dc.title:title
webui.browse.sort-option.2 = dateissued:dc.date.issued:date webui.itemlist.sort-option.2 = dateissued:dc.date.issued:date
webui.browse.sort-option.3 = dateaccessioned:dc.date.accessioned:date webui.itemlist.sort-option.3 = dateaccessioned:dc.date.accessioned:date
# Set the options for the size (number of characters) of the fields stored in the database. # Set the options for the size (number of characters) of the fields stored in the database.
# #
@@ -550,9 +550,9 @@ webui.browse.sort-option.3 = dateaccessioned:dc.date.accessioned:date
# #
# The default datatypes (and delegates) are: # The default datatypes (and delegates) are:
# #
# author = org.dspace.browse.BrowseOrderAuthor # author = org.dspace.sort.OrderFormatAuthor
# title = org.dspace.browse.BrowseOrderTitle # title = org.dspace.sort.OrderFormatTitle
# text = org.dspace.browse.BrowseOrderText # text = org.dspace.sort.OrderFormatText
# #
# If you redefine a default datatype here, the configuration will be used in preference # If you redefine a default datatype here, the configuration will be used in preference
# to the default, however, if you do not explicitly redefine a datatype, then the # to the default, however, if you do not explicitly redefine a datatype, then the
@@ -560,8 +560,8 @@ webui.browse.sort-option.3 = dateaccessioned:dc.date.accessioned:date
# #
# Uncomment the configuration below to use the multi-lingual MARC 21 title ordering. # Uncomment the configuration below to use the multi-lingual MARC 21 title ordering.
# #
#plugin.named.org.dspace.browse.BrowseOrderDelegate= \ #plugin.named.org.dspace.sort.OrderFormatDelegate= \
# org.dspace.browse.BrowseOrderTitleMarc21=title # org.dspace.sort.OrderFormatTitleMarc21=title
## Set the options for how authors are displayed in the browse listing ## Set the options for how authors are displayed in the browse listing