diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOOracle.java b/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOOracle.java index 0abc535424..134d1e3150 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOOracle.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOOracle.java @@ -619,8 +619,15 @@ public class BrowseCreateDAOOracle implements BrowseCreateDAO try { - String query = "SELECT item_id FROM " + table + " WHERE item_id NOT IN ( SELECT item_id FROM item WHERE in_archive = 1 AND withdrawn = " + - (withdrawn ? "0" : "1") + ")"; + String query = "SELECT item_id FROM " + table + " WHERE item_id NOT IN ( SELECT item_id FROM item WHERE "; + + if (withdrawn) + query += "withdrawn = 1"; + else + query += "in_archive = 1 AND withdrawn = 0"; + + query += ")"; + tri = DatabaseManager.query(context, query); while (tri.hasNext()) { diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOPostgres.java b/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOPostgres.java index 6a938eeeae..1d8acd268c 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOPostgres.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseCreateDAOPostgres.java @@ -619,8 +619,15 @@ public class BrowseCreateDAOPostgres implements BrowseCreateDAO try { - String query = "SELECT item_id FROM " + table + " WHERE item_id NOT IN ( SELECT item_id FROM item WHERE in_archive = true AND withdrawn = " + - (withdrawn ? "true" : "false") + ")"; + String query = "SELECT item_id FROM " + table + " WHERE item_id NOT IN ( SELECT item_id FROM item WHERE "; + + if (withdrawn) + query += "withdrawn = true"; + else + query += "in_archive = true AND withdrawn = false"; + + query += ")"; + tri = DatabaseManager.query(context, query); while (tri.hasNext()) { diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOFactory.java b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOFactory.java index 14d0fad530..4e1b093925 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOFactory.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOFactory.java @@ -101,8 +101,34 @@ public class BrowseDAOFactory throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database"); } } - - /** + + /** + * Get an instance of the relevant Read Only DAO class, which will + * conform to the BrowseItemDAO interface + * + * @param context the DSpace context + * @return the relevant DAO + * @throws BrowseException + */ + public static BrowseItemDAO getItemInstance(Context context) + throws BrowseException + { + String db = ConfigurationManager.getProperty("db.name"); + if ("postgres".equals(db)) + { + return new BrowseItemDAOPostgres(context); + } + else if ("oracle".equals(db)) + { + return new BrowseItemDAOOracle(context); + } + else + { + throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database"); + } + } + + /** * Get an instance of the relevant DAO Utilities class, which will * conform to the BrowseDAOUtils interface * diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOOracle.java b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOOracle.java index 64429c4137..f7d165948c 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOOracle.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOOracle.java @@ -138,6 +138,11 @@ public class BrowseDAOOracle implements BrowseDAO /** whether the query (above) needs to be regenerated */ private boolean rebuildQuery = true; + // FIXME Would be better to join to item table and get the correct values + /** flags for what the items represent */ + private boolean itemsInArchive = true; + private boolean itemsWithdrawn = false; + public BrowseDAOOracle(Context context) throws BrowseException { @@ -254,7 +259,9 @@ public class BrowseDAOOracle implements BrowseDAO while (tri.hasNext()) { TableRow row = tri.next(); - BrowseItem browseItem = new BrowseItem(context, row.getIntColumn("item_id")); + BrowseItem browseItem = new BrowseItem(context, row.getIntColumn("item_id"), + itemsInArchive, + itemsWithdrawn); results.add(browseItem); } @@ -579,6 +586,21 @@ public class BrowseDAOOracle implements BrowseDAO public void setTable(String table) { this.table = table; + + // FIXME Rather than assume from the browse table, join the query to item to get the correct values + // Check to see if this is the withdrawn browse index - if it is, + // we need to set the flags appropriately for when we create the BrowseItems + if (table.equals(BrowseIndex.getWithdrawnBrowseIndex().getTableName())) + { + itemsInArchive = false; + itemsWithdrawn = true; + } + else + { + itemsInArchive = true; + itemsWithdrawn = false; + } + this.rebuildQuery = true; } diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgres.java b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgres.java index 2b88fa692e..dcd6169a0e 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgres.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgres.java @@ -138,6 +138,11 @@ public class BrowseDAOPostgres implements BrowseDAO private String whereClauseOperator = ""; + // FIXME Would be better to join to item table and get the correct values + /** flags for what the items represent */ + private boolean itemsInArchive = true; + private boolean itemsWithdrawn = false; + /** * Required constructor for use by BrowseDAOFactory * @@ -261,7 +266,9 @@ public class BrowseDAOPostgres implements BrowseDAO while (tri.hasNext()) { TableRow row = tri.next(); - BrowseItem browseItem = new BrowseItem(context, row.getIntColumn("item_id")); + BrowseItem browseItem = new BrowseItem(context, row.getIntColumn("item_id"), + itemsInArchive, + itemsWithdrawn); results.add(browseItem); } @@ -583,6 +590,21 @@ public class BrowseDAOPostgres implements BrowseDAO public void setTable(String table) { this.table = table; + + // FIXME Rather than assume from the browse table, join the query to item to get the correct values + // Check to see if this is the withdrawn browse index - if it is, + // we need to set the flags appropriately for when we create the BrowseItems + if (table.equals(BrowseIndex.getWithdrawnBrowseIndex().getTableName())) + { + itemsInArchive = false; + itemsWithdrawn = true; + } + else + { + itemsInArchive = true; + itemsWithdrawn = false; + } + this.rebuildQuery = true; } @@ -862,7 +884,7 @@ public class BrowseDAOPostgres implements BrowseDAO * SELECT [arguments] FROM [table] * * - * @param args the string value obtained from distinctClause, countClause or selectValues + * @param queryBuf the string value obtained from distinctClause, countClause or selectValues * @return the SELECT part of the query */ private void buildSelectStatement(StringBuffer queryBuf) throws BrowseException diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgresRJ.java b/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgresRJ.java deleted file mode 100644 index 650b4112cc..0000000000 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseDAOPostgresRJ.java +++ /dev/null @@ -1,1199 +0,0 @@ -/* - * BrowseDAOPostgresRJ.java - * - * Version: $Revision: $ - * - * Date: $Date: $ - * - * Copyright (c) 2002-2005, 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.browse; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.log4j.Logger; -import org.dspace.core.Context; -import org.dspace.core.LogManager; -import org.dspace.storage.rdbms.DatabaseManager; -import org.dspace.storage.rdbms.TableRow; -import org.dspace.storage.rdbms.TableRowIterator; - -/** - * This class is the PostgreSQL driver class for reading information from the - * Browse tables. It implements the BrowseDAO interface, and also has a - * constructor of the form: - * - * BrowseDAOPostgres(Context context) - * - * As required by BrowseDAOFactory. This class should only ever be loaded by - * that Factory object. - * - * @author Richard Jones - * - */ -public class BrowseDAOPostgresRJ implements BrowseDAO -{ - // administrative attributes for this class - - /** a cache of the actual query to be executed */ - private String query = ""; - - /** whether the query (above) needs to be regenerated */ - private boolean rebuildQuery = true; - - /** Log4j log */ - private static Logger log = Logger.getLogger(BrowseDAOPostgres.class); - - /** The DSpace context */ - private Context context; - - private BrowseDAOUtils utils; - - // SQL query related attributes for this class - - /** the values to place in the SELECT --- FROM bit */ - private String[] selectValues = { "*" }; - - /** the values to place in the SELECT DISTINCT(---) bit */ - private String[] distinctValues; - - /** the values to place in the SELECT COUNT(---) bit */ - private String[] countValues; - - /** table to select from */ - private String table = null; - - /** field to look for focus value in */ - private String focusField = null; - - /** value to start browse from in focus field */ - private String focusValue = null; - - /** field to look for value in */ - private String valueField = null; - - /** value to restrict browse to (e.g. author name) */ - private String value = null; - - /** the table that defines the mapping for the relevant container */ - private String containerTable = null; - - /** the name of the field which contains the container id (e.g. collection_id) */ - private String containerIDField = null; - - /** the database id of the container we are constraining to */ - private int containerID = -1; - - /** the column that we are sorting results by */ - private String orderField = null; - - /** whether to sort results ascending or descending */ - private boolean ascending = true; - - /** the limit of number of results to return */ - private int limit = -1; - - /** the offset of the start point (avoid using) */ - private int offset = -1; - - /** whether to use the equals comparator in value comparisons */ - private boolean equalsComparator = true; - - /** whether this is a distinct browse or not */ - private boolean distinct = false; - - /** - * Required constructor for use by BrowseDAOFactory - * - * @param context DSpace context - */ - public BrowseDAOPostgresRJ(Context context) - throws BrowseException - { - this.context = context; - - // obtain the relevant Utils for this class - utils = BrowseDAOFactory.getUtils(context); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#doCountQuery() - */ - public int doCountQuery() - throws BrowseException - { - String query = getQuery(); - log.debug(LogManager.getHeader(context, "executing_count_query", "query=" + query)); - - TableRowIterator tri = null; - - try - { - // now run the query - tri = DatabaseManager.query(context, query); - - if (tri.hasNext()) - { - TableRow row = tri.next(); - return (int) row.getLongColumn("number"); - } - else - { - return 0; - } - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new BrowseException(e); - } - finally - { - if (tri != null) - tri.close(); - } - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#doValueQuery() - */ - public List doValueQuery() - throws BrowseException - { - String query = getQuery(); - log.debug(LogManager.getHeader(context, "executing_value_query", "query=" + query)); - - TableRowIterator tri = null; - - try - { - // now run the query - tri = DatabaseManager.query(context, query); - - // go over the query results and process - List results = new ArrayList(); - while (tri.hasNext()) - { - TableRow row = tri.next(); - String stringResult = row.getStringColumn("value"); - results.add(stringResult); - } - - return results; - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new BrowseException(e); - } - finally - { - if (tri != null) - tri.close(); - } - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#doQuery() - */ - public List doQuery() - throws BrowseException - { - String query = getQuery(); - log.debug(LogManager.getHeader(context, "executing_full_query", "query=" + query)); - - TableRowIterator tri = null; - try - { - // now run the query - tri = DatabaseManager.query(context, query); - - // go over the query results and process - List results = new ArrayList(); - while (tri.hasNext()) - { - TableRow row = tri.next(); - BrowseItem browseItem = new BrowseItem(context, row.getIntColumn("item_id")); - results.add(browseItem); - } - - return results; - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new BrowseException("problem with query: " + query, e); - } - finally - { - if (tri != null) - tri.close(); - } - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getQuery() - */ - public String getQuery() - throws BrowseException - { - if ("".equals(query) || rebuild()) - { - if (this.isDistinct()) - { - query = buildDistinctQuery(); - } - else - { - query = buildQuery(); - } - setRebuildQuery(false); - } - return query; - } - - /** - * Build a clause for selecting distinct values. Will return something of the form - * - * - * DISTINCT( [value 1], [value 2] ) - * - * - * @return the distinct clause - */ - private String distinctClause() - { - String selectArgs = ""; - if (distinctValues != null) - { - for (int i = 0; i < distinctValues.length; i++) - { - if (i == 0) - { - selectArgs = selectArgs + " DISTINCT("; - } - if (i > 0) - { - selectArgs = selectArgs + " , "; - } - selectArgs = selectArgs + escape(distinctValues[i]); - if (i == distinctValues.length - 1) - { - selectArgs = selectArgs + ") "; - } - } - } - return selectArgs; - } - - /** - * Build a clause for counting results. Will return something of the form: - * - * - * COUNT( [value 1], [value 2] ) AS number - * - * - * @return the count clause - */ - private String countClause() - { - String selectArgs = ""; - if (countValues != null) - { - for (int i = 0; i < countValues.length; i++) - { - if (i == 0) - { - selectArgs = selectArgs + " COUNT("; - } - if (i > 0) - { - selectArgs = selectArgs + " , "; - } - selectArgs = selectArgs + escape(countValues[i]); - if (i == countValues.length - 1) - { - selectArgs = selectArgs + ") AS number"; - } - } - } - return selectArgs; - } - - /** - * Prepare the list of values to be selected on. Will return something of the form: - * - * - * [value 1], [value 2] - * - * - * @return the select value list - */ - private String selectValues() - { - String selectArgs = ""; - if (selectValues != null) - { - for (int i = 0; i < selectValues.length; i++) - { - if ((!"".equals(selectArgs) && i == 0) || i > 0) - { - selectArgs = selectArgs + " , "; - } - selectArgs = selectArgs + escape(selectValues[i]); - } - } - return selectArgs; - } - - /** - * Get the comparator which should be used to compare focus values - * with values in the database. This will return one of the 4 following - * possible values: <, >, <=, >= - * - * @return the focus comparator - */ - private String getFocusComparator() - { - // now decide whether we will use an equals comparator; - String equals = "="; - if (!useEqualsComparator()) - { - equals = ""; - } - - // get the comparator for the match of the browsable index value - // the rule is: if the scope has a value, then the comparator is always "=" - // if, the order is set to ascending then we want to use - // WHERE sort_value > - // and when the order is descending then we want to use - // WHERE sort_value < - String focusComparator = ""; - if (isAscending()) - { - focusComparator = ">" + equals; - } - else - { - focusComparator = "<" + equals; - } - - return focusComparator; - } - - /** - * Get the clause to get the browse to start from a given focus value. - * Will return something of the form: - * - * - * [field] (<[=] | >[=]) '[value]' - * - * - * such as: - * - * - * sort_value <= 'my text' - * - * - * @return the focus clause - */ - private String getFocusClause() - { - // get the operator (<[=] | >[=]) which the focus of the browse will - // be matched using - String focusComparator = getFocusComparator(); - - // assemble the focus clase if we are to have one - // it will look like one of the following - // - sort_value <= myvalue - // - sort_1 >= myvalue - String focusClause = ""; - if (focusField != null && focusValue != null) - { - focusClause = " " + escape(focusField) + " " + focusComparator + " '" + escape(focusValue) + "' "; - } - - return focusClause; - } - - /** - * Return the clause to constrain the browse to a specific value. - * Will return something of the form: - * - * - * [field] = '[value]' - * - * - * such as: - * - * - * sort_value = 'some author' - * - * - * @return the value clause - */ - private String getValueClause() - { - // assemble the value clause if we are to have one - String valueClause = ""; - if (value != null && valueField != null) - { - String valueComparator = "="; - valueClause = " " + escape(valueField) + " " + valueComparator + " '" + escape(value) + "' "; - } - return valueClause; - } - - /** - * assemble a WHERE clause with the given constraints. This will return something - * of the form: - * - * - * WHERE [focus clause] [AND] [value clause] [AND] [container constraint] - * - * - * The container constraint is described in one of either getFullConstraint or - * getDistinctConstraint, and the form of that section of the query can be - * found in their documentation. - * - * If either of focusClause or valueClause is null, they will be duly omitted from - * the WHERE clause. - * - * @param focusClause the focus clause, as returned by getFocusClause - * @param valueClause the value clause, as returned by getValue Clause - * @param useContainer whether to constrain to a container - * @param isDistinct whether this is a distinct browse - * @return the WHERE clause - */ - private String getWhereClause(String focusClause, String valueClause, boolean useContainer, boolean isDistinct) - { - // assemble the where clause out of the two possible value clauses - String whereClause = ""; - - if (!"".equals(focusClause) && focusClause != null) - { - whereClause = whereClause + focusClause; - } - - if (!"".equals(valueClause) && valueClause != null) - { - if (!"".equals(whereClause)) - { - whereClause = whereClause + " AND "; - } - whereClause = whereClause + valueClause; - } - - // add the constraint to community or collection if necessary - // and desired - if (useContainer) - { - String constraint = ""; - if (isDistinct) - { - constraint = getDistinctConstraint(); - } - else - { - constraint = getFullConstraint(); - } - - if (!"".equals(constraint)) - { - if (!"".equals(whereClause)) - { - whereClause = whereClause + " AND "; - } - whereClause = whereClause + constraint; - } - - } - - // now finalise the construction of the where clause - if (!"".equals(whereClause)) - { - whereClause = " WHERE " + whereClause; - } - - return whereClause; - } - - /** - * Get a sub-query to obtain the ids for a distinct browse within a given - * constraint. This will produce something of the form: - * - * - * id IN (SELECT distinct_id FROM [container table] WHERE [container field] = [container id]) - * - * - * This is for use inside the overall WHERE clause only - * - * @return the sub-query - */ - private String getDistinctConstraint() - { - String constraint = ""; - if (containerIDField != null && containerID != -1 && containerTable != null) - { - constraint = " id IN (SELECT distinct_id FROM " + escape(containerTable) + - " WHERE " + escape(containerIDField) + " = " + containerID + ") "; - } - return constraint; - } - - /** - * Get a clause to obtain the ids for a full browse within a given - * constraint. This will produce something of the form: - * - * - * [container field] = [container id] - * - * - * This is for use inside the overall WHERE clause only - * - * @return the constraint clause - */ - private String getFullConstraint() - { - String constraint = ""; - if (containerIDField != null && containerID != -1) - { - constraint = escape(containerIDField) + " = " + containerID + " "; - } - return constraint; - } - - /** - * Get the clause to perform search result ordering. This will - * return something of the form: - * - * - * ORDER BY [order field] (ASC | DESC) - * - * - * @return the ORDER BY clause - */ - private String getOrderBy() - { - // assemble the order by field - String orderBy = ""; - if (orderField != null) - { - orderBy = " " + escape(orderField); - if (isAscending()) - { - orderBy = orderBy + " ASC "; - } - else - { - orderBy = orderBy + " DESC "; - } - orderBy = " ORDER BY " + orderBy; - } - - return orderBy; - } - - /** - * Get the limit clause to perform search result truncation. Will return - * something of the form: - * - * - * LIMIT [limit] - * - * - * @return the limit clause - */ - private String getLimitClause() - { - // prepare the LIMIT clause - String limitClause = ""; - if (limit != -1) - { - limitClause = " LIMIT " + Integer.toString(limit); - } - - return limitClause; - } - - /** - * Get the offset clause to offset the start point of search results - * - * @return - * @deprecated - */ - private String getOffsetClause() - { - // prepare the OFFSET clause - String offsetClause = ""; - if (offset != -1) - { - offsetClause = " OFFSET " + Integer.toString(offset); - } - - return offsetClause; - } - - /** - * Prepare the select clause using the pre-prepared arguments. This will produce something - * of the form: - * - * - * SELECT [arguments] FROM [table] - * - * - * @param args the string value obtained from distinctClause, countClause or selectValues - * @return the SELECT part of the query - */ - private String selectClause(String args) - { - String selectFrom = "SELECT " + args + " FROM " + escape(table) + " "; - return selectFrom; - } - - /** - * Assemble a query from the various component parts passed in here. If any of those - * parts are null, they will be duly omitted from the final query. This will - * produce something of the form: - * - * - * [select] [where] [order by] [limit] [offset] - * - * - * @param selectFrom SELECT part of the query - * @param whereClause WHERE clause - * @param orderBy ORDER BY clause - * @param limitClause LIMIT clause - * @param offsetClause OFFSET clause - * @return the final query to be executed - * @throws BrowseException - */ - private String assembleQuery(String selectFrom, String whereClause, String orderBy, String limitClause, String offsetClause) - throws BrowseException - { - if (selectFrom == null) - { - throw new BrowseException("Cannot generate query: the SELECT clause does not exist"); - } - - if (whereClause == null) { whereClause = ""; } - if (orderBy == null) { orderBy = ""; } - if (limitClause == null) { limitClause = ""; } - if (offsetClause == null) { offsetClause = ""; } - - String query = selectFrom + whereClause + orderBy + limitClause + offsetClause; - return query; - } - - /** - * Build the query that will be used for a distinct select. This incorporates - * only the parts of the parameters that are actually useful for this type - * of browse - * - * @return the query to be executed - * @throws BrowseException - */ - private String buildDistinctQuery() - throws BrowseException - { - String selectArgs = countClause(); - if ("".equals(selectArgs) || selectArgs == null) - { - selectArgs = selectValues(); - } - if ("".equals(selectArgs) || selectArgs == null) - { - throw new BrowseException("No arguments for SELECT statement"); - } - String selectFrom = selectClause(selectArgs); - - // assemble the focus clase if we are to have one - // it will look like one of the following, for example - // sort_value <= myvalue - // sort_1 >= myvalue - String focusClause = getFocusClause(); - - // assemble the where clause out of the two possible value clauses - // and include container support - String whereClause = getWhereClause(focusClause, null, true, true); - - // assemble the order by field - String orderBy = getOrderBy(); - - // prepare the LIMIT clause - String limitClause = getLimitClause(); - - // finally, put the query together and return it - String query = assembleQuery(selectFrom, whereClause, orderBy, limitClause, null); - return query; - } - - /** - * Build the query that will be used for a full browse. - * - * @return the query to be executed - * @throws BrowseException - */ - private String buildQuery() - throws BrowseException - { - // build the SELECT part of the query - String selectArgs = countClause(); - if ("".equals(selectArgs) || selectArgs == null) - { - selectArgs = distinctClause(); - selectArgs = selectArgs + selectValues(); - } - if ("".equals(selectArgs) || selectArgs == null) - { - throw new BrowseException("No arguments for SELECT statement"); - } - String selectFrom = selectClause(selectArgs); - - // assemble the focus clase if we are to have one - // it will look like one of the following, for example - // sort_value <= myvalue - // sort_1 >= myvalue - String focusClause = getFocusClause(); - - // assemble the value clause if we are to have one - String valueClause = getValueClause(); - - // assemble the where clause out of the two possible value clauses - // and include container support - String whereClause = getWhereClause(focusClause, valueClause, true, false); - - // assemble the order by field - String orderBy = getOrderBy(); - - // prepare the LIMIT clause - String limitClause = getLimitClause(); - - // prepare the OFFSET clause - String offsetClause = getOffsetClause(); - - // finally, put the query together and return it - String query = assembleQuery(selectFrom, whereClause, orderBy, limitClause, offsetClause); - return query; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#doMaxQuery(java.lang.String, java.lang.String, int) - */ - public String doMaxQuery(String column, String table, int itemID) - throws BrowseException - { - TableRowIterator tri = null; - - try - { - String query = "SELECT max(" + column + ") FROM " + table + " WHERE item_id = ?"; - - Object[] params = { new Integer(itemID) }; - tri = DatabaseManager.query(context, query, params); - - TableRow row; - if (tri.hasNext()) - { - row = tri.next(); - return row.getStringColumn("max"); - } - else - { - return null; - } - } - catch (SQLException e) - { - throw new BrowseException(e); - } - finally - { - if (tri != null) - tri.close(); - } - } - - /** - * Tell the class that the query needs to be rebuilt again. This should be - * called after any modification of the parameters. - * - * @param bool whether to rebuild the query again or not - */ - private void setRebuildQuery(boolean bool) - { - this.rebuildQuery = bool; - } - - /** - * Should the query be rebuilt? - * @return - */ - private boolean rebuild() - { - return this.rebuildQuery; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#useEqualsComparator() - */ - public boolean useEqualsComparator() - { - return equalsComparator; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setEqualsComparator(boolean) - */ - public void setEqualsComparator(boolean equalsComparator) - { - this.equalsComparator = equalsComparator; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#isAscending() - */ - public boolean isAscending() - { - return ascending; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setAscending(boolean) - */ - public void setAscending(boolean ascending) - { - this.ascending = ascending; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getContainerID() - */ - public int getContainerID() - { - return containerID; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setContainerID(int) - */ - public void setContainerID(int containerID) - { - this.containerID = containerID; - setRebuildQuery(true); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getContainerIDField() - */ - public String getContainerIDField() - { - return containerIDField; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setContainerIDField(java.lang.String) - */ - public void setContainerIDField(String containerIDField) - { - this.containerIDField = containerIDField; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getFocusField() - */ - public String getJumpToField() - { - return focusField; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setFocusField(java.lang.String) - */ - public void setJumpToField(String focusField) - { - this.focusField = focusField; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getFocusValue() - */ - public String getJumpToValue() - { - return focusValue; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setFocusValue(java.lang.String) - */ - public void setJumpToValue(String focusValue) - { - this.focusValue = focusValue; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getLimit() - */ - public int getLimit() - { - return limit; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setLimit(int) - */ - public void setLimit(int limit) - { - this.limit = limit; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getOffset() - */ - public int getOffset() - { - return offset; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setOffset(int) - */ - public void setOffset(int offset) - { - this.offset = offset; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getOrderField() - */ - public String getOrderField() - { - return orderField; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setOrderField(java.lang.String) - */ - public void setOrderField(String orderField) - { - this.orderField = orderField; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getSelectValues() - */ - public String[] getSelectValues() - { - return selectValues; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setSelectValues(java.lang.String[]) - */ - public void setSelectValues(String[] selectValues) - { - this.selectValues = selectValues; - setRebuildQuery(true); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#selectDistinctOn(java.lang.String[]) - */ - public void selectDistinctOn(String[] fields) - { - this.distinctValues = fields; - setRebuildQuery(true); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getCountValues() - */ - public String[] getCountValues() - { - return this.countValues; - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getDistinctValues() - */ - public String[] getDistinctValues() - { - return this.distinctValues; - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setCountValues(java.lang.String[]) - */ - public void setCountValues(String[] fields) - { - this.countValues = fields; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getTable() - */ - public String getTable() - { - return table; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setTable(java.lang.String) - */ - public void setTable(String table) - { - this.table = table; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getValue() - */ - public String getFilterValue() - { - return value; - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setValue(java.lang.String) - */ - public void setFilterValue(String value) - { - this.value = value; - setRebuildQuery(true); - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getValueField() - */ - public String getFilterValueField() - { - return valueField; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setValueField(java.lang.String) - */ - public void setFilterValueField(String valueField) - { - this.valueField = valueField; - setRebuildQuery(true); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setDistinct(boolean) - */ - public void setDistinct(boolean bool) - { - this.distinct = bool; - setRebuildQuery(true); - } - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#isDistinct() - */ - public boolean isDistinct() - { - return this.distinct; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#getContainerTable() - */ - public String getContainerTable() - { - return containerTable; - } - - - /* (non-Javadoc) - * @see org.dspace.browse.BrowseDAO#setContainerTable(java.lang.String) - */ - public void setContainerTable(String containerTable) - { - this.containerTable = containerTable; - } - - /** - * Escape the passed string so that it is safe to run against the database. We - * don't use the usual PreparedStatement because the query is too complicated - * to assemble in a way that makes that feasible. - * - * @param source the string to be escaped - * @return the escaped string - */ - private String escape(String source) - { - // escape is simply the process of converting ' to \' (I think!) (which is double escaped in Java) - String result = source.replace("'", "''"); - return result; - } - -} diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseEngine.java b/dspace-api/src/main/java/org/dspace/browse/BrowseEngine.java index 1fb7f29d17..df51e83964 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseEngine.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseEngine.java @@ -43,7 +43,6 @@ package org.dspace.browse; import java.sql.SQLException; import java.util.Iterator; import java.util.List; -import java.util.Map; import org.apache.log4j.Logger; import org.dspace.content.Collection; @@ -213,6 +212,8 @@ public class BrowseEngine browseInfo.setResultsPerPage(scope.getResultsPerPage()); + browseInfo.setEtAl(scope.getEtAl()); + return browseInfo; } @@ -367,8 +368,13 @@ public class BrowseEngine } if (prevID != -1) { - prev = new BrowseItem(context, prevID); - } + // If we are browsing the withdrawn index, create a 'withdrawn' browse item + // Otherwise, assume that the item is in the archive and not withdrawn + if (bs.getBrowseIndex() == BrowseIndex.getWithdrawnBrowseIndex()) + prev = new BrowseItem(context, prevID, false, true); + else + prev = new BrowseItem(context, prevID, true, false); + } } // now we need to process the position, total and offset for the results @@ -447,6 +453,8 @@ public class BrowseEngine } browseInfo.setResultsPerPage(scope.getResultsPerPage()); + + browseInfo.setEtAl(scope.getEtAl()); return browseInfo; } @@ -708,7 +716,7 @@ public class BrowseEngine * Return a normalized focus value. If there is no normalization that can be performed, * return the focus value that is passed in. * - * @param String a focus value to normalize + * @param value a focus value to normalize * @return the normalized focus value * @throws BrowseException */ diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseIndex.java b/dspace-api/src/main/java/org/dspace/browse/BrowseIndex.java index a90db7af67..316b303191 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseIndex.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseIndex.java @@ -42,7 +42,6 @@ package org.dspace.browse; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; -import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -84,9 +83,6 @@ public class BrowseIndex /** a three part array of the metadata bits (e.g. dc.contributor.author) */ private String[] mdBits; - /** array of the configured indexes */ - private static BrowseIndex[] browseIndexes = null; - /** additional 'internal' tables that are always defined */ private static BrowseIndex itemIndex = new BrowseIndex("bi_item"); private static BrowseIndex withdrawnIndex = new BrowseIndex("bi_withdrawn"); @@ -100,7 +96,7 @@ public class BrowseIndex /** * Constructor for creating generic / internal index objects - * @param baseName + * @param baseName The base of the table name */ private BrowseIndex(String baseName) { @@ -133,7 +129,7 @@ public class BrowseIndex * * @param definition the configuration definition of this index * @param number the configuration number of this index - * @throws BrowseException + * @throws BrowseException */ private BrowseIndex(String definition, int number) throws BrowseException @@ -770,7 +766,6 @@ public class BrowseIndex /** * Does this browse index represent one of the internal item indexes * - * @param bi * @return */ public boolean isInternalIndex() diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java index 3f750744fc..a42986ac77 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java @@ -35,24 +35,18 @@ */ package org.dspace.browse; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeManager; -import org.dspace.content.Bitstream; -import org.dspace.content.Bundle; -import org.dspace.content.DCValue; -import org.dspace.content.DSpaceObject; -import org.dspace.content.Item; +import org.dspace.content.*; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.handle.HandleManager; -import org.dspace.storage.rdbms.DatabaseManager; -import org.dspace.storage.rdbms.TableRow; -import org.dspace.storage.rdbms.TableRowIterator; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; /** * Entity class to represent an item that is being used to generate Browse @@ -81,79 +75,35 @@ public class BrowseItem extends DSpaceObject /** database id of the item */ private int id = -1; - - /** item handle */ + + /** is the item in the archive */ + private boolean in_archive = true; + + /** is the item withdrawn */ + private boolean withdrawn = false; + + /** item handle */ private String handle = null; - - /** query to obtain all the items from the database */ - private String findAll = "SELECT * FROM item WHERE in_archive = true AND withdrawn = false"; - - /** query to check the existance of an item id */ - private String getByID = "SELECT id FROM item WHERE item_id = ?"; - - /** query to get the text value of a metadata element only (qualifier is NULL) */ - private String getByMetadataElement = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + - " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + - " AND metadatafieldregistry.element = ? " + - " AND metadatafieldregistry.qualifier IS NULL " + - " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + - " AND metadataschemaregistry.short_id = ?"; - - /** query to get the text value of a metadata element and qualifier */ - private String getByMetadata = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + - " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + - " AND metadatafieldregistry.element = ? " + - " AND metadatafieldregistry.qualifier = ? " + - " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + - " AND metadataschemaregistry.short_id = ?"; - - /** query to get the text value of a metadata element with the wildcard qualifier (*) */ - private String getByMetadataAnyQualifier = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + - " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + - " AND metadatafieldregistry.element = ? " + - " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + - " AND metadataschemaregistry.short_id = ?"; /** inner item, if we really absolutely have to instantiate it */ private Item item; - - /** + + /** * Construct a new browse item with the given context and the database id * * @param context the DSpace context - * @param id the database id of the item - */ - public BrowseItem(Context context, int id) + * @param id the database id of the item + * @param in_archive + * @param withdrawn + */ + public BrowseItem(Context context, int id, boolean in_archive, boolean withdrawn) { this.context = context; this.id = id; - } + this.in_archive = in_archive; + this.withdrawn = withdrawn; + } - /** - * Get an integer array of all the item ids in the database - * - * @return integer array of item ids - * @throws SQLException - */ - public Integer[] findAll() - throws SQLException - { - TableRowIterator tri = DatabaseManager.query(context, findAll); - ArrayList ids = new ArrayList(); - - while (tri.hasNext()) - { - TableRow row = tri.next(); - ids.add(new Integer(row.getIntColumn("item_id"))); - } - - Integer[] ints = new Integer[ids.size()]; - return (Integer[]) ids.toArray((Integer[]) ints); - } - /** * Get String array of metadata values matching the given parameters * @@ -167,44 +117,58 @@ public class BrowseItem extends DSpaceObject public DCValue[] getMetadata(String schema, String element, String qualifier, String lang) throws SQLException { - // if the qualifier is a wildcard, we have to get it out of the - // database - if (Item.ANY.equals(qualifier)) - { - return queryMetadata(schema, element, qualifier, lang); - } - - if (!metadata.isEmpty()) - { - List values = new ArrayList(); - Iterator i = metadata.iterator(); - - while (i.hasNext()) - { - DCValue dcv = (DCValue) i.next(); - - if (match(schema, element, qualifier, lang, dcv)) - { - values.add(dcv); - } - } - - if (values.isEmpty()) - { - return queryMetadata(schema, element, qualifier, lang); - } - - // else, Create an array of matching values - DCValue[] valueArray = new DCValue[values.size()]; - valueArray = (DCValue[]) values.toArray(valueArray); - - return valueArray; - } - else - { - return queryMetadata(schema, element, qualifier, lang); - } - } + try + { + BrowseItemDAO dao = BrowseDAOFactory.getItemInstance(context); + + // if the qualifier is a wildcard, we have to get it out of the + // database + if (Item.ANY.equals(qualifier)) + { + return dao.queryMetadata(id, schema, element, qualifier, lang); + } + + if (!metadata.isEmpty()) + { + List values = new ArrayList(); + Iterator i = metadata.iterator(); + + while (i.hasNext()) + { + DCValue dcv = (DCValue) i.next(); + + if (match(schema, element, qualifier, lang, dcv)) + { + values.add(dcv); + } + } + + if (values.isEmpty()) + { + DCValue[] dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + Collections.addAll(metadata, dcvs); + return dcvs; + } + + // else, Create an array of matching values + DCValue[] valueArray = new DCValue[values.size()]; + valueArray = (DCValue[]) values.toArray(valueArray); + + return valueArray; + } + else + { + DCValue[] dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + Collections.addAll(metadata, dcvs); + return dcvs; + } + } + catch (BrowseException be) + { + log.error("caught exception: ", be); + return null; + } + } /** * Get the type of object. This object masquerates as an Item, so this @@ -332,67 +296,6 @@ public class BrowseItem extends DSpaceObject // If we get this far, we have a match return true; } - - /** - * perform a database query to obtain the string array of values corresponding to - * the passed parameters. In general you should use: - * - * - * getMetadata(schema, element, qualifier, lang); - * - * - * As this will obtain the value from cache if available first. - * - * @param schema - * @param element - * @param qualifier - * @param lang - * @return - * @throws SQLException - */ - public DCValue[] queryMetadata(String schema, String element, String qualifier, String lang) - throws SQLException - { - ArrayList values = new ArrayList(); - TableRowIterator tri; - - if (qualifier == null) - { - Object[] params = { new Integer(id), element, schema }; - tri = DatabaseManager.query(context, getByMetadataElement, params); - } - else if (Item.ANY.equals(qualifier)) - { - Object[] params = { new Integer(id), element, schema }; - tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); - } - else - { - Object[] params = { new Integer(id), element, qualifier, schema }; - tri = DatabaseManager.query(context, getByMetadata, params); - } - - if (!tri.hasNext()) - { - return null; - } - - while (tri.hasNext()) - { - TableRow tr = tri.next(); - DCValue dcv = new DCValue(); - dcv.schema = schema; - dcv.element = tr.getStringColumn("element"); - dcv.qualifier = tr.getStringColumn("qualifier"); - dcv.language = tr.getStringColumn("text_lang"); - dcv.value = tr.getStringColumn("text_value"); - metadata.add(dcv); - values.add(dcv); - } - - DCValue[] dcvs = new DCValue[values.size()]; - return (DCValue[]) values.toArray(dcvs); - } /* (non-Javadoc) * @see org.dspace.content.DSpaceObject#getHandle() @@ -506,4 +409,14 @@ public class BrowseItem extends DSpaceObject return null; } } + + public boolean isArchived() + { + return in_archive; + } + + public boolean isWithdrawn() + { + return withdrawn; + } } diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAO.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAO.java new file mode 100644 index 0000000000..8ed9fce207 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAO.java @@ -0,0 +1,73 @@ +/* + * BrowseItemDAO.java + * + * 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.browse; + +import org.dspace.content.DCValue; + +import java.sql.SQLException; + +public interface BrowseItemDAO +{ + /** + * Get an array of all the items in the database + * + * @return array of items + * @throws java.sql.SQLException + */ + public BrowseItem[] findAll() + throws SQLException; + + /** + * perform a database query to obtain the string array of values corresponding to + * the passed parameters. In general you should use: + * + * + * getMetadata(schema, element, qualifier, lang); + * + * + * As this will obtain the value from cache if available first. + * + * @param itemId + * @param schema + * @param element + * @param qualifier + * @param lang + * @return + * @throws SQLException + */ + public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang) + throws SQLException; +} diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java new file mode 100644 index 0000000000..04271e6496 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java @@ -0,0 +1,147 @@ +/* + * BrowseItemDAOOracle.java + * + * 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.browse; + +import org.dspace.storage.rdbms.TableRowIterator; +import org.dspace.storage.rdbms.DatabaseManager; +import org.dspace.storage.rdbms.TableRow; +import org.dspace.core.Context; +import org.dspace.content.DCValue; +import org.dspace.content.Item; + +import java.sql.SQLException; +import java.util.ArrayList; + +public class BrowseItemDAOOracle implements BrowseItemDAO +{ + /** query to obtain all the items from the database */ + private String findAll = "SELECT item_id, in_archive, withdrawn FROM item WHERE in_archive = 1 OR withdrawn = 1"; + + /** query to get the text value of a metadata element only (qualifier is NULL) */ + private String getByMetadataElement = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.qualifier IS NULL " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** query to get the text value of a metadata element and qualifier */ + private String getByMetadata = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.qualifier = ? " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** query to get the text value of a metadata element with the wildcard qualifier (*) */ + private String getByMetadataAnyQualifier = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** DSpace context */ + private Context context; + + public BrowseItemDAOOracle(Context context) + throws BrowseException + { + this.context = context; + } + + public BrowseItem[] findAll() throws SQLException + { + TableRowIterator tri = DatabaseManager.query(context, findAll); + ArrayList items = new ArrayList(); + + while (tri.hasNext()) + { + TableRow row = tri.next(); + items.add(new BrowseItem(context, row.getIntColumn("item_id"), + row.getBooleanColumn("in_archive"), + row.getBooleanColumn("withdrawn"))); + } + + BrowseItem[] bis = new BrowseItem[items.size()]; + return (BrowseItem[]) items.toArray((BrowseItem[]) bis); + } + + public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang) + throws SQLException + { + ArrayList values = new ArrayList(); + TableRowIterator tri; + + if (qualifier == null) + { + Object[] params = { new Integer(itemId), element, schema }; + tri = DatabaseManager.query(context, getByMetadataElement, params); + } + else if (Item.ANY.equals(qualifier)) + { + Object[] params = { new Integer(itemId), element, schema }; + tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); + } + else + { + Object[] params = { new Integer(itemId), element, qualifier, schema }; + tri = DatabaseManager.query(context, getByMetadata, params); + } + + if (!tri.hasNext()) + { + return null; + } + + while (tri.hasNext()) + { + TableRow tr = tri.next(); + DCValue dcv = new DCValue(); + dcv.schema = schema; + dcv.element = tr.getStringColumn("element"); + dcv.qualifier = tr.getStringColumn("qualifier"); + dcv.language = tr.getStringColumn("text_lang"); + dcv.value = tr.getStringColumn("text_value"); + values.add(dcv); + } + + DCValue[] dcvs = new DCValue[values.size()]; + return (DCValue[]) values.toArray(dcvs); + } +} diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java new file mode 100644 index 0000000000..1bf306d8bc --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java @@ -0,0 +1,147 @@ +/* + * BrowseItemDAOPostgres.java + * + * 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.browse; + +import org.dspace.storage.rdbms.TableRowIterator; +import org.dspace.storage.rdbms.DatabaseManager; +import org.dspace.storage.rdbms.TableRow; +import org.dspace.core.Context; +import org.dspace.content.DCValue; +import org.dspace.content.Item; + +import java.sql.SQLException; +import java.util.ArrayList; + +public class BrowseItemDAOPostgres implements BrowseItemDAO +{ + /** query to obtain all the items from the database */ + private String findAll = "SELECT item_id, in_archive, withdrawn FROM item WHERE in_archive = true OR withdrawn = true"; + + /** query to get the text value of a metadata element only (qualifier is NULL) */ + private String getByMetadataElement = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.qualifier IS NULL " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** query to get the text value of a metadata element and qualifier */ + private String getByMetadata = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.qualifier = ? " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** query to get the text value of a metadata element with the wildcard qualifier (*) */ + private String getByMetadataAnyQualifier = "SELECT text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + + "WHERE metadatavalue.item_id = ? " + + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + + " AND metadatafieldregistry.element = ? " + + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + + " AND metadataschemaregistry.short_id = ?"; + + /** DSpace context */ + private Context context; + + public BrowseItemDAOPostgres(Context context) + throws BrowseException + { + this.context = context; + } + + public BrowseItem[] findAll() throws SQLException + { + TableRowIterator tri = DatabaseManager.query(context, findAll); + ArrayList items = new ArrayList(); + + while (tri.hasNext()) + { + TableRow row = tri.next(); + items.add(new BrowseItem(context, row.getIntColumn("item_id"), + row.getBooleanColumn("in_archive"), + row.getBooleanColumn("withdrawn"))); + } + + BrowseItem[] bis = new BrowseItem[items.size()]; + return (BrowseItem[]) items.toArray((BrowseItem[]) bis); + } + + public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang) + throws SQLException + { + ArrayList values = new ArrayList(); + TableRowIterator tri; + + if (qualifier == null) + { + Object[] params = { new Integer(itemId), element, schema }; + tri = DatabaseManager.query(context, getByMetadataElement, params); + } + else if (Item.ANY.equals(qualifier)) + { + Object[] params = { new Integer(itemId), element, schema }; + tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); + } + else + { + Object[] params = { new Integer(itemId), element, qualifier, schema }; + tri = DatabaseManager.query(context, getByMetadata, params); + } + + if (!tri.hasNext()) + { + return null; + } + + while (tri.hasNext()) + { + TableRow tr = tri.next(); + DCValue dcv = new DCValue(); + dcv.schema = schema; + dcv.element = tr.getStringColumn("element"); + dcv.qualifier = tr.getStringColumn("qualifier"); + dcv.language = tr.getStringColumn("text_lang"); + dcv.value = tr.getStringColumn("text_value"); + values.add(dcv); + } + + DCValue[] dcvs = new DCValue[values.size()]; + return (DCValue[]) values.toArray(dcvs); + } +} diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowserScope.java b/dspace-api/src/main/java/org/dspace/browse/BrowserScope.java index 5a3ae0b3b8..8d2f65bcb5 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowserScope.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowserScope.java @@ -35,8 +35,6 @@ */ package org.dspace.browse; -import java.util.Map; - import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DSpaceObject; @@ -96,7 +94,9 @@ public class BrowserScope /** the browse level */ private int level = 0; - + + /** the number of authors to display in the results */ + private int etAl = 0; /** * Construct a new BrowserScope using the given Context * @@ -208,6 +208,22 @@ public class BrowserScope this.browseIndex = browseIndex; } + /** + * @return Returns the author limit. + */ + public int getEtAl() + { + return etAl; + } + + /** + * @param etAl the author limit + */ + public void setEtAl(int etAl) + { + this.etAl = etAl; + } + /** * @return Returns the collection. */ diff --git a/dspace-api/src/main/java/org/dspace/browse/IndexBrowse.java b/dspace-api/src/main/java/org/dspace/browse/IndexBrowse.java index 1d06ba2a27..9f480d003e 100644 --- a/dspace-api/src/main/java/org/dspace/browse/IndexBrowse.java +++ b/dspace-api/src/main/java/org/dspace/browse/IndexBrowse.java @@ -40,10 +40,8 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.StringTokenizer; import org.apache.commons.cli.CommandLine; @@ -360,21 +358,17 @@ public class IndexBrowse removeIndex(item.getID(), BrowseIndex.getItemBrowseIndex().getTableName()); removeIndex(item.getID(), BrowseIndex.getWithdrawnBrowseIndex().getTableName()); - // Index any archived item - if (item.isArchived()) + // Index any archived item that isn't withdrawn + if (item.isArchived() && !item.isWithdrawn()) + { + Map sortMap = getSortValues(item, itemMDMap); + dao.insertIndex(BrowseIndex.getItemBrowseIndex().getTableName(), item.getID(), sortMap); + } + else if (item.isWithdrawn()) { // If it's withdrawn, add it to the withdrawn items index - if (item.isWithdrawn()) - { - Map sortMap = getSortValues(item, itemMDMap); - dao.insertIndex(BrowseIndex.getWithdrawnBrowseIndex().getTableName(), item.getID(), sortMap); - } - else - { - // Otherwise, add it to the main item index - Map sortMap = getSortValues(item, itemMDMap); - dao.insertIndex(BrowseIndex.getItemBrowseIndex().getTableName(), item.getID(), sortMap); - } + Map sortMap = getSortValues(item, itemMDMap); + dao.insertIndex(BrowseIndex.getWithdrawnBrowseIndex().getTableName(), item.getID(), sortMap); } // Now update the metadata indexes @@ -1041,16 +1035,15 @@ public class IndexBrowse } // now get the ids of ALL the items in the database - BrowseItem bi = new BrowseItem(context, -1); - Integer[] ids = bi.findAll(); + BrowseItemDAO biDao = BrowseDAOFactory.getItemInstance(context); + BrowseItem[] items = biDao.findAll(); // go through every item id, grab the relevant metadata // and write it into the database - for (int j = 0; j < ids.length; j++) + for (int j = 0; j < items.length; j++) { - BrowseItem item = new BrowseItem(context, ids[j].intValue()); - indexItem(new ItemMetadataProxy(ids[j].intValue(), item)); + indexItem(new ItemMetadataProxy(items[j].getID(), items[j])); // after each item we commit the context and clear the cache context.commit(); @@ -1074,7 +1067,7 @@ public class IndexBrowse // Make sure the deletes are written back context.commit(); - return ids.length; + return items.length; } catch (SQLException e) { @@ -1170,7 +1163,6 @@ public class IndexBrowse /** * Is the Item archived? - * If we only have a cut down BrowseItem, assume that it is * @return */ public boolean isArchived() @@ -1180,12 +1172,11 @@ public class IndexBrowse return item.isArchived(); } - return true; + return browseItem.isArchived(); } /** * Is the Item withdrawn? - * If we only have a cut down BrowseItem, assume that it is not * @return */ public boolean isWithdrawn() @@ -1195,7 +1186,7 @@ public class IndexBrowse return item.isWithdrawn(); } - return false; + return browseItem.isWithdrawn(); } } } diff --git a/dspace-api/src/main/resources/Messages.properties b/dspace-api/src/main/resources/Messages.properties index 2933ebdeb8..23be69de8c 100644 --- a/dspace-api/src/main/resources/Messages.properties +++ b/dspace-api/src/main/resources/Messages.properties @@ -531,6 +531,7 @@ jsp.layout.navbar-admin.logout = Log Out jsp.layout.navbar-admin.metadataregistry = Metadata
Registry jsp.layout.navbar-admin.statistics = Statistics jsp.layout.navbar-admin.supervisors = Supervisors +jsp.layout.navbar-admin.withdrawn = Withdrawn Items jsp.layout.navbar-admin.workflow = Workflow jsp.layout.navbar-default.about = About DSpace jsp.layout.navbar-default.advanced = Advanced Search diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/AbstractBrowserServlet.java b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/AbstractBrowserServlet.java new file mode 100644 index 0000000000..d37690e439 --- /dev/null +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/AbstractBrowserServlet.java @@ -0,0 +1,353 @@ +package org.dspace.app.webui.servlet; + +import java.io.IOException; +import java.sql.SQLException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.dspace.app.webui.util.UIUtil; +import org.dspace.authorize.AuthorizeException; +import org.dspace.browse.BrowseEngine; +import org.dspace.browse.BrowseException; +import org.dspace.browse.BrowseIndex; +import org.dspace.browse.BrowseInfo; +import org.dspace.browse.BrowserScope; +import org.dspace.browse.SortOption; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.core.ConfigurationManager; +import org.dspace.core.Context; +import org.dspace.core.LogManager; + +/** + * Servlet for browsing through indices, as they are defined in + * the configuration. This class can take a wide variety of inputs from + * the user interface: + * + * - type: the type of browse (index name) being performed + * - order: (ASC | DESC) the direction for result sorting + * - value: A specific value to find items around. For example the author name or subject + * - month: integer specification of the month of a date browse + * - year: integer specification of the year of a date browse + * - starts_with: string value at which to start browsing + * - vfocus: start browsing with a value of this string + * - focus: integer id of the item at which to start browsing + * - rpp: integer number of results per page to display + * - sort_by: integer specification of the field to search on + * - etal: integer number to limit multiple value items specified in config to + * + * @author Richard Jones + * @version $Revision: $ + */ +public abstract class AbstractBrowserServlet extends DSpaceServlet +{ + /** log4j category */ + private static Logger log = Logger.getLogger(AbstractBrowserServlet.class); + + public AbstractBrowserServlet() + { + super(); + } + + /** + * Create a BrowserScope from the current request + * + * @param context The database context + * @param request The servlet request + * @param response The servlet response + * @return A BrowserScope for the current parameters + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected BrowserScope getBrowserScopeForRequest(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, AuthorizeException + { + try + { + // first, lift all the stuff out of the request that we might need + String type = request.getParameter("type"); + String order = request.getParameter("order"); + String value = request.getParameter("value"); + String valueLang = request.getParameter("value_lang"); + String month = request.getParameter("month"); + String year = request.getParameter("year"); + String startsWith = request.getParameter("starts_with"); + String valueFocus = request.getParameter("vfocus"); + String valueFocusLang = request.getParameter("vfocus_lang"); + int focus = UIUtil.getIntParameter(request, "focus"); + int resultsperpage = UIUtil.getIntParameter(request, "rpp"); + int sortBy = UIUtil.getIntParameter(request, "sort_by"); + int etAl = UIUtil.getIntParameter(request, "etal"); + + // get the community or collection location for the browse request + // Note that we are only interested in getting the "smallest" container, + // so if we find a collection, we don't bother looking up the community + Collection collection = null; + Community community = null; + collection = UIUtil.getCollectionLocation(request); + if (collection == null) + { + community = UIUtil.getCommunityLocation(request); + } + + // process the input, performing some inline validation + BrowseIndex bi = null; + if (type != null && !"".equals(type)) + { + bi = BrowseIndex.getBrowseIndex(type); + } + + if (bi == null) + { + if (sortBy > 0) + bi = BrowseIndex.getBrowseIndex(SortOption.getSortOption(sortBy)); + else + bi = BrowseIndex.getBrowseIndex(SortOption.getDefaultSortOption()); + } + + // If we don't have a sort column + if (bi != null && sortBy == -1) + { + // Get the default one + SortOption so = bi.getSortOption(); + if (so != null) + { + sortBy = so.getNumber(); + } + } + else if (bi != null && bi.isItemIndex() && !bi.isInternalIndex()) + { + // If a default sort option is specified by the index, but it isn't + // 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 (newBi != null) + { + bi = newBi; + type = bi.getName(); + } + } + } + + // if no resultsperpage set, default to 20 + if (resultsperpage == -1) + { + resultsperpage = 20; + } + + // if no order parameter, default to ascending + if (order == null || "".equals(order)) + { + order = "ASC"; + } + + // if year and perhaps month have been selected, we translate these into "startsWith" + // if startsWith has already been defined then it is overwritten + if (year != null && !"".equals(year) && !"-1".equals(year)) + { + startsWith = year; + if ((month != null) && !"-1".equals(month) && !"".equals(month)) + { + // subtract 1 from the month, so the match works appropriately + if ("ASC".equals(order)) + { + month = Integer.toString((Integer.parseInt(month) - 1)); + } + + // They've selected a month as well + if (month.length() == 1) + { + // Ensure double-digit month number + month = "0" + month; + } + + startsWith = year + "-" + month; + } + } + + // determine which level of the browse we are at: 0 for top, 1 for second + int level = 0; + if (value != null) + { + level = 1; + } + + // if sortBy is still not set, set it to 0, which is default to use the primary index value + if (sortBy == -1) + { + sortBy = 0; + } + + // figure out the setting for author list truncation + if (etAl == -1) // there is no limit, or the UI says to use the default + { + int limitLine = ConfigurationManager.getIntProperty("webui.browse.author-limit"); + if (limitLine != 0) + { + etAl = limitLine; + } + } + else // if the user has set a limit + { + if (etAl == 0) // 0 is the user setting for unlimited + { + etAl = -1; // but -1 is the application setting for unlimited + } + } + + // log the request + String comHandle = "n/a"; + if (community != null) + { + comHandle = community.getHandle(); + } + String colHandle = "n/a"; + if (collection != null) + { + colHandle = collection.getHandle(); + } + + String arguments = "type=" + type + ",order=" + order + ",value=" + value + + ",month=" + month + ",year=" + year + ",starts_with=" + startsWith + + ",vfocus=" + valueFocus + ",focus=" + focus + ",rpp=" + resultsperpage + + ",sort_by=" + sortBy + ",community=" + comHandle + ",collection=" + colHandle + + ",level=" + level + ",etal=" + etAl; + + log.info(LogManager.getHeader(context, "browse", arguments)); + + // set up a BrowseScope and start loading the values into it + BrowserScope scope = new BrowserScope(context); + scope.setBrowseIndex(bi); + scope.setOrder(order); + scope.setFilterValue(value); + scope.setFilterValueLang(valueLang); + scope.setJumpToItem(focus); + scope.setJumpToValue(valueFocus); + scope.setJumpToValueLang(valueFocusLang); + scope.setStartsWith(startsWith); + scope.setResultsPerPage(resultsperpage); + scope.setSortBy(sortBy); + scope.setBrowseLevel(level); + scope.setEtAl(etAl); + + // assign the scope of either Community or Collection if necessary + if (community != null) + { + scope.setBrowseContainer(community); + } + else if (collection != null) + { + scope.setBrowseContainer(collection); + } + + return scope; + } + catch (BrowseException e) + { + log.error("caught exception: ", e); + throw new ServletException(e); + } + } + + /** + * Do the usual DSpace GET method. You will notice that browse does not currently + * respond to POST requests. + */ + protected void processBrowse(Context context, BrowserScope scope, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + try + { + BrowseIndex bi = scope.getBrowseIndex(); + + // now start up a browse engine and get it to do the work for us + BrowseEngine be = new BrowseEngine(context); + BrowseInfo binfo = be.browse(scope); + + request.setAttribute("browse.info", binfo); + + if (binfo.hasResults()) + { + if (bi.isMetadataIndex() && !scope.isSecondLevel()) + { + showSinglePage(context, request, response); + } + else + { + showFullPage(context, request, response); + } + } + else + { + showNoResultsPage(context, request, response); + } + } + catch (BrowseException e) + { + log.error("caught exception: ", e); + throw new ServletException(e); + } + } + + /** + * Display the error page + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected abstract void showError(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException; + + /** + * Display the No Results page + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected abstract void showNoResultsPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException; + + /** + * Display the single page. This is the page which lists just the single values of a + * metadata browse, not individual items. Single values are links through to all the items + * that match that metadata value + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected abstract void showSinglePage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException; + + protected abstract void showFullPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException; +} diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/BrowserServlet.java b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/BrowserServlet.java index d081af2883..b616c306b6 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/BrowserServlet.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/BrowserServlet.java @@ -48,21 +48,11 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.log4j.Logger; import org.dspace.app.webui.util.JSPManager; -import org.dspace.app.webui.util.UIUtil; import org.dspace.authorize.AuthorizeException; -import org.dspace.browse.BrowseEngine; import org.dspace.browse.BrowseException; -import org.dspace.browse.BrowseIndex; -import org.dspace.browse.BrowseInfo; import org.dspace.browse.BrowserScope; -import org.dspace.browse.SortOption; -import org.dspace.content.Collection; -import org.dspace.content.Community; -import org.dspace.core.ConfigurationManager; import org.dspace.core.Context; -import org.dspace.core.LogManager; /** * Servlet for browsing through indices, as they are defined in @@ -84,231 +74,28 @@ import org.dspace.core.LogManager; * @author Richard Jones * @version $Revision: $ */ -public class BrowserServlet extends DSpaceServlet +public class BrowserServlet extends AbstractBrowserServlet { - /** log4j category */ - private static Logger log = Logger.getLogger(BrowserServlet.class); - /** * Do the usual DSpace GET method. You will notice that browse does not currently * respond to POST requests. */ - protected void doDSGet(Context context, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, - SQLException, AuthorizeException + protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException { - try - { - // all browse requests currently come to GET. - - // first, lift all the stuff out of the request that we might need - String type = request.getParameter("type"); - String order = request.getParameter("order"); - String value = request.getParameter("value"); - String valueLang = request.getParameter("value_lang"); - String month = request.getParameter("month"); - String year = request.getParameter("year"); - String startsWith = request.getParameter("starts_with"); - String valueFocus = request.getParameter("vfocus"); - String valueFocusLang = request.getParameter("vfocus_lang"); - int focus = UIUtil.getIntParameter(request, "focus"); - int resultsperpage = UIUtil.getIntParameter(request, "rpp"); - int sortBy = UIUtil.getIntParameter(request, "sort_by"); - int etAl = UIUtil.getIntParameter(request, "etal"); - - // get the community or collection location for the browse request - // Note that we are only interested in getting the "smallest" container, - // so if we find a collection, we don't bother looking up the community - Collection collection = null; - Community community = null; - collection = UIUtil.getCollectionLocation(request); - if (collection == null) - { - community = UIUtil.getCommunityLocation(request); - } - - // process the input, performing some inline validation - if (type == null || "".equals(type)) - { - showError(context, request, response); - } + // all browse requests currently come to GET. + BrowserScope scope = getBrowserScopeForRequest(context, request, response); - BrowseIndex bi = BrowseIndex.getBrowseIndex(type); - if (bi == null) - { - throw new BrowseException("There is no browse index of the type: " + type); - } - - // If we don't have a sort column - if (sortBy == -1) - { - // Get the default one - SortOption so = bi.getSortOption(); - if (so != null) - { - sortBy = so.getNumber(); - } - } - else if (bi.isItemIndex() && !bi.isInternalIndex()) - { - // If a default sort option is specified by the index, but it isn't - // 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 (newBi != null) - { - bi = newBi; - type = bi.getName(); - } - } - } - - // if no resultsperpage set, default to 20 - if (resultsperpage == -1) - { - resultsperpage = 20; - } - - // if no order parameter, default to ascending - if (order == null || "".equals(order)) - { - order = "ASC"; - } - - // if year and perhaps month have been selected, we translate these into "startsWith" - // if startsWith has already been defined then it is overwritten - if (year != null && !"".equals(year) && !"-1".equals(year)) - { - startsWith = year; - if ((month != null) && !"-1".equals(month) && !"".equals(month)) - { - // subtract 1 from the month, so the match works appropriately - if ("ASC".equals(order)) - { - month = Integer.toString((Integer.parseInt(month) - 1)); - } - - // They've selected a month as well - if (month.length() == 1) - { - // Ensure double-digit month number - month = "0" + month; - } - - startsWith = year + "-" + month; - } - } - - // determine which level of the browse we are at: 0 for top, 1 for second - int level = 0; - if (value != null) - { - level = 1; - } - - // if sortBy is still not set, set it to 0, which is default to use the primary index value - if (sortBy == -1) - { - sortBy = 0; - } - - // figure out the setting for author list truncation - if (etAl == -1) // there is no limit, or the UI says to use the default - { - int limitLine = ConfigurationManager.getIntProperty("webui.browse.author-limit"); - if (limitLine != 0) - { - etAl = limitLine; - } - } - else // if the user has set a limit - { - if (etAl == 0) // 0 is the user setting for unlimited - { - etAl = -1; // but -1 is the application setting for unlimited - } - } - - // log the request - String comHandle = "n/a"; - if (community != null) - { - comHandle = community.getHandle(); - } - String colHandle = "n/a"; - if (collection != null) - { - colHandle = collection.getHandle(); - } - - String arguments = "type=" + type + ",order=" + order + ",value=" + value + - ",month=" + month + ",year=" + year + ",starts_with=" + startsWith + - ",vfocus=" + valueFocus + ",focus=" + focus + ",rpp=" + resultsperpage + - ",sort_by=" + sortBy + ",community=" + comHandle + ",collection=" + colHandle + - ",level=" + level + ",etal=" + etAl; - - log.info(LogManager.getHeader(context, "browse", arguments)); - - // set up a BrowseScope and start loading the values into it - BrowserScope scope = new BrowserScope(context); - scope.setBrowseIndex(bi); - scope.setOrder(order); - scope.setFilterValue(value); - scope.setFilterValueLang(valueLang); - scope.setJumpToItem(focus); - scope.setJumpToValue(valueFocus); - scope.setJumpToValueLang(valueFocusLang); - scope.setStartsWith(startsWith); - scope.setResultsPerPage(resultsperpage); - scope.setSortBy(sortBy); - scope.setBrowseLevel(level); - - // assign the scope of either Community or Collection if necessary - if (community != null) - { - scope.setBrowseContainer(community); - } - else if (collection != null) - { - scope.setBrowseContainer(collection); - } - - // now start up a browse engine and get it to do the work for us - BrowseEngine be = new BrowseEngine(context); - BrowseInfo binfo = be.browse(scope); - - // add the etAl limit to the BrowseInfo object - binfo.setEtAl(etAl); - - request.setAttribute("browse.info", binfo); - - if (binfo.hasResults()) - { - if (bi.isMetadataIndex() && !scope.isSecondLevel()) - { - showSinglePage(context, request, response); - } - else - { - showFullPage(context, request, response); - } - } - else - { - showNoResultsPage(context, request, response); - } - } - catch (BrowseException e) + if (scope.getBrowseIndex() == null) { - log.error("caught exception: ", e); - throw new ServletException(e); + throw new ServletException("There is no browse index for the request"); } + + // execute browse request + processBrowse(context, scope, request, response); } + /** * Display the error page @@ -321,13 +108,13 @@ public class BrowserServlet extends DSpaceServlet * @throws SQLException * @throws AuthorizeException */ - protected void showError(Context context, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, - SQLException, AuthorizeException + protected void showError(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException { - JSPManager.showJSP(request, response, "/browse/error.jsp"); + JSPManager.showJSP(request, response, "/browse/error.jsp"); } - + /** * Display the No Results page * @@ -339,14 +126,14 @@ public class BrowserServlet extends DSpaceServlet * @throws SQLException * @throws AuthorizeException */ - protected void showNoResultsPage(Context context, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, - SQLException, AuthorizeException + protected void showNoResultsPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException { - - JSPManager.showJSP(request, response, "/browse/no-results.jsp"); + + JSPManager.showJSP(request, response, "/browse/no-results.jsp"); } - + /** * Display the single page. This is the page which lists just the single values of a * metadata browse, not individual items. Single values are links through to all the items @@ -360,14 +147,14 @@ public class BrowserServlet extends DSpaceServlet * @throws SQLException * @throws AuthorizeException */ - protected void showSinglePage(Context context, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, - SQLException, AuthorizeException + protected void showSinglePage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException { - - JSPManager.showJSP(request, response, "/browse/single.jsp"); + + JSPManager.showJSP(request, response, "/browse/single.jsp"); } - + /** * Display a full item listing. * @@ -379,11 +166,11 @@ public class BrowserServlet extends DSpaceServlet * @throws SQLException * @throws AuthorizeException */ - protected void showFullPage(Context context, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, - SQLException, AuthorizeException + protected void showFullPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException { - - JSPManager.showJSP(request, response, "/browse/full.jsp"); + + JSPManager.showJSP(request, response, "/browse/full.jsp"); } } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/admin/WithdrawnBrowserServlet.java b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/admin/WithdrawnBrowserServlet.java new file mode 100644 index 0000000000..1f77dc7280 --- /dev/null +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/admin/WithdrawnBrowserServlet.java @@ -0,0 +1,187 @@ +/* + * BrowserServlet.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.app.webui.servlet.admin; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.dspace.authorize.AuthorizeException; +import org.dspace.browse.BrowseException; +import org.dspace.browse.BrowseIndex; +import org.dspace.browse.BrowserScope; +import org.dspace.core.Context; + +import org.dspace.app.webui.servlet.AbstractBrowserServlet; +import org.dspace.app.webui.util.JSPManager; + +/** + * Servlet for browsing through withdrawn items: + * + * @author Graham Triggs + * @version $Revision: $ + */ +public class WithdrawnBrowserServlet extends AbstractBrowserServlet +{ + /** log4j category */ + private static Logger log = Logger.getLogger(WithdrawnBrowserServlet.class); + + /** + * Do the usual DSpace GET method. You will notice that browse does not currently + * respond to POST requests. + */ + protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + try + { + // all browse requests currently come to GET. + BrowserScope scope = getBrowserScopeForRequest(context, request, response); + + // Check that we are doing an item browse + if (scope.getBrowseIndex() == null || scope.getBrowseIndex().isItemIndex()) + { + // And override the index in the scope with the withdrawn items + scope.setBrowseIndex(BrowseIndex.getWithdrawnBrowseIndex()); + } + else + { + showError(context, request, response); + } + + // execute browse request + processBrowse(context, scope, request, response); + } + catch (BrowseException be) + { + log.error("caught exception: ", be); + throw new ServletException(be); + } + } + + + /** + * Display the error page + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected void showError(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + request.setAttribute("useAdminLayout", "yes"); + + JSPManager.showJSP(request, response, "/browse/error.jsp"); + } + + /** + * Display the No Results page + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected void showNoResultsPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + request.setAttribute("browseWithdrawn", "yes"); + + JSPManager.showJSP(request, response, "/browse/no-results.jsp"); + } + + /** + * Display the single page. This is the page which lists just the single values of a + * metadata browse, not individual items. Single values are links through to all the items + * that match that metadata value + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected void showSinglePage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + // Show an error as this currently isn't supported + showError(context, request, response); + } + + /** + * Display a full item listing. + * + * @param context + * @param request + * @param response + * @throws ServletException + * @throws IOException + * @throws SQLException + * @throws AuthorizeException + */ + protected void showFullPage(Context context, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, SQLException, + AuthorizeException + { + request.setAttribute("browseWithdrawn", "yes"); + + JSPManager.showJSP(request, response, "/browse/full.jsp"); + } +} diff --git a/dspace-jspui/src/main/webapp/WEB-INF/web.xml b/dspace-jspui/src/main/webapp/WEB-INF/web.xml index 97e2c92cb7..2d5111c5df 100644 --- a/dspace-jspui/src/main/webapp/WEB-INF/web.xml +++ b/dspace-jspui/src/main/webapp/WEB-INF/web.xml @@ -159,6 +159,11 @@ org.dspace.app.webui.servlet.BrowserServlet + + browsewithdrawn + org.dspace.app.webui.servlet.admin.WithdrawnBrowserServlet + + collection-wizard org.dspace.app.webui.servlet.admin.CollectionWizardServlet @@ -398,6 +403,11 @@ /browse + + browsewithdrawn + /dspace-admin/withdrawn + + community-list /community-list diff --git a/dspace-jspui/src/main/webapp/browse/full.jsp b/dspace-jspui/src/main/webapp/browse/full.jsp index 067d559d0d..a5ea160d16 100644 --- a/dspace-jspui/src/main/webapp/browse/full.jsp +++ b/dspace-jspui/src/main/webapp/browse/full.jsp @@ -62,6 +62,14 @@ <%@ page import="org.dspace.app.webui.util.UIUtil" %> <% + String urlFragment = "browse"; + String layoutNavbar = "default"; + if (request.getAttribute("browseWithdrawn") != null) + { + layoutNavbar = "admin"; + urlFragment = "dspace-admin/withdrawn"; + } + // First, get the browse info object BrowseInfo bi = (BrowseInfo) request.getAttribute("browse.info"); BrowseIndex bix = bi.getBrowseIndex(); @@ -119,12 +127,17 @@ { valueString = "&value=" + URLEncoder.encode(bi.getValue()); } - String sharedLink = linkBase + "browse?type=" + URLEncoder.encode(bix.getName()) + - "&sort_by=" + URLEncoder.encode(Integer.toString(so.getNumber())) + - "&order=" + URLEncoder.encode(direction) + - "&rpp=" + URLEncoder.encode(Integer.toString(bi.getResultsPerPage())) + - "&etal=" + URLEncoder.encode(Integer.toString(bi.getEtAl())) + - valueString; + + String sharedLink = linkBase + urlFragment + "?"; + + if (bix.getName() != null) + sharedLink += "type=" + URLEncoder.encode(bix.getName()); + + sharedLink += "&sort_by=" + URLEncoder.encode(Integer.toString(so.getNumber())) + + "&order=" + URLEncoder.encode(direction) + + "&rpp=" + URLEncoder.encode(Integer.toString(bi.getResultsPerPage())) + + "&etal=" + URLEncoder.encode(Integer.toString(bi.getEtAl())) + + valueString; String next = sharedLink; String prev = sharedLink; @@ -165,7 +178,7 @@ { formaction = formaction + "handle/" + community.getHandle() + "/"; } - formaction = formaction + "browse"; + formaction = formaction + urlFragment; // prepare the known information about sorting, ordering and results per page String sortedBy = so.getName(); @@ -187,7 +200,7 @@ <%-- OK, so here we start to develop the various components we will use in the UI --%> <%@page import="java.util.Set"%> - + <%-- Build the header (careful use of spacing) --%>

diff --git a/dspace-jspui/src/main/webapp/browse/no-results.jsp b/dspace-jspui/src/main/webapp/browse/no-results.jsp index 1e7be22d1b..f828cab2f7 100644 --- a/dspace-jspui/src/main/webapp/browse/no-results.jsp +++ b/dspace-jspui/src/main/webapp/browse/no-results.jsp @@ -59,6 +59,12 @@ <%@ page import="org.dspace.content.Collection" %> <% + String layoutNavbar = "default"; + if (request.getAttribute("browseWithdrawn") != null) + { + layoutNavbar = "admin"; + } + // get the BrowseInfo object BrowseInfo bi = (BrowseInfo) request.getAttribute("browse.info"); @@ -93,7 +99,7 @@ } %> - +

diff --git a/dspace-jspui/src/main/webapp/layout/navbar-admin.jsp b/dspace-jspui/src/main/webapp/layout/navbar-admin.jsp index 31ca14858f..0da1cf3259 100644 --- a/dspace-jspui/src/main/webapp/layout/navbar-admin.jsp +++ b/dspace-jspui/src/main/webapp/layout/navbar-admin.jsp @@ -49,6 +49,8 @@ <%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %> +<%@ page import="org.dspace.browse.BrowseInfo" %> +<%@ page import="org.dspace.browse.SortOption" %> <%@ page import="org.dspace.app.webui.util.UIUtil" %> @@ -179,6 +181,23 @@   + +<% + // get the browse indices + BrowseInfo binfo = (BrowseInfo) request.getAttribute("browse.info"); +%> + + + .gif" width="16" height="16"/> + + + + + + + +   + diff --git a/dspace-jspui/src/main/webapp/layout/navbar-default.jsp b/dspace-jspui/src/main/webapp/layout/navbar-default.jsp index 4b66c41031..8959c2f99e 100644 --- a/dspace-jspui/src/main/webapp/layout/navbar-default.jsp +++ b/dspace-jspui/src/main/webapp/layout/navbar-default.jsp @@ -98,7 +98,10 @@ // Only highlight the current browse, only if it is a metadata index, // or the selected sort option is the default for the index if (bix.isMetadataIndex() || bix.getSortOption() == binfo.getSortOption()) - browseCurrent = bix.getName(); + { + if (bix.getName() != null) + browseCurrent = bix.getName(); + } } %>