📄 browse.java
字号:
* <li>DC values are added, removed, or modified * <li>the value of the in_archive flag changes * </ul> * * @param context - * The database context * @param item - * The item which has been added * @exception SQLException - * If a database error occurs */ public static void itemChanged(Context context, Item item) throws SQLException { // This is a bit heavy-weight, but without knowing what // changed, it's easiest just to replace the values // en masse. itemRemoved(context, item.getID()); if (!item.isArchived()) { return; } itemAdded(context, item); } /** * This method should be called whenever an item is added. * * @param context * The current DSpace context * @param item * The item which has been added * @exception SQLException * If a database error occurs */ public static void itemAdded(Context context, Item item) throws SQLException { // add all parent communities to communities2item table Community[] parents = item.getCommunities(); for (int j = 0; j < parents.length; j++) { TableRow row = DatabaseManager.create(context, "Communities2Item"); row.setColumn("item_id", item.getID()); row.setColumn("community_id", parents[j].getID()); DatabaseManager.update(context, row); } // get the metadata fields to index in the title and date tables // get the date, title and author fields String dateField = ConfigurationManager.getProperty("webui.browse.index.date"); if (dateField == null) { dateField = "dc.date.issued"; } String titleField = ConfigurationManager.getProperty("webui.browse.index.title"); if (titleField == null) { titleField = "dc.title"; } String authorField = ConfigurationManager.getProperty("webui.browse.index.author"); if (authorField == null) { authorField = "dc.contributor.*"; } String subjectField = ConfigurationManager.getProperty("webui.browse.index.subject"); if (subjectField == null) { subjectField = "dc.subject.*"; } // get the DC values for each of these fields DCValue[] titleArray = getDCField(item, titleField); DCValue[] dateArray = getDCField(item, dateField); DCValue[] authorArray = getDCField(item, authorField); DCValue[] subjectArray = getDCField(item, subjectField); // now build the data map Map table2dc = new HashMap(); table2dc.put("ItemsByTitle", titleArray); table2dc.put("ItemsByAuthor", authorArray); table2dc.put("ItemsByDate", dateArray); table2dc.put("ItemsByDateAccessioned", item.getDC("date", "accessioned", Item.ANY)); table2dc.put("ItemsBySubject", subjectArray); for (Iterator iterator = table2dc.keySet().iterator(); iterator .hasNext();) { String table = (String) iterator.next(); DCValue[] dc = (DCValue[]) table2dc.get(table); for (int i = 0; i < dc.length; i++) { TableRow row = DatabaseManager.create(context, table); row.setColumn("item_id", item.getID()); String value = dc[i].value; if ("ItemsByDateAccessioned".equals(table)) { row.setColumn("date_accessioned", value); } else if ("ItemsByDate".equals(table)) { row.setColumn("date_issued", value); } else if ("ItemsByAuthor".equals(table)) { // author name, and normalized sorting name // (which for now is simple lower-case) row.setColumn("author", value); row.setColumn("sort_author", value.toLowerCase()); } else if ("ItemsByTitle".equals(table)) { String title = NormalizedTitle.normalize(value, dc[i].language); row.setColumn("title", value); row.setColumn("sort_title", title.toLowerCase()); } else if ("ItemsBySubject".equals(table)) { row.setColumn("subject", value); row.setColumn("sort_subject", value.toLowerCase()); } DatabaseManager.update(context, row); } } } /** * Index all items in DSpace. This method may be resource-intensive. * * @param context * Current DSpace context * @return The number of items indexed. * @exception SQLException * If a database error occurs */ public static int indexAll(Context context) throws SQLException { indexRemoveAll(context); int count = 0; ItemIterator iterator = Item.findAll(context); while (iterator.hasNext()) { itemAdded(context, iterator.next()); count++; } return count; } /** * Remove all items in DSpace from the Browse index. * * @param context * Current DSpace context * @return The number of items removed. * @exception SQLException * If a database error occurs */ public static int indexRemoveAll(Context context) throws SQLException { int total = 0; String[] browseTables = BrowseTables.tables(); for (int i = 0; i < browseTables.length; i++) { String sql = "delete from " + browseTables[i]; total += DatabaseManager.updateQuery(context, sql); } return total; } //////////////////////////////////////// // Other methods //////////////////////////////////////// /** * Return the normalized form of title. * * @param title * @param lang * @return title */ public static String getNormalizedTitle(String title, String lang) { return NormalizedTitle.normalize(title, lang); } //////////////////////////////////////// // Private methods //////////////////////////////////////// private static DCValue[] getDCField(Item item, String dc) { StringTokenizer dcf = new StringTokenizer(dc, "."); String[] tokens = { "", "", "" }; int i = 0; while(dcf.hasMoreTokens()) { tokens[i] = dcf.nextToken().toLowerCase().trim(); i++; } String schema = tokens[0]; String element = tokens[1]; String qualifier = tokens[2]; DCValue[] values; if ("*".equals(qualifier)) { values = item.getDC(element, Item.ANY, Item.ANY); } else if ("".equals(qualifier)) { values = item.getDC(element, null, Item.ANY); } else { values = item.getDC(element, qualifier, Item.ANY); } return values; } /** * Workhorse method for browse functionality. * * @param scope * @return BrowseInfo * @throws SQLException */ private static BrowseInfo doBrowse(BrowseScope scope) throws SQLException { // Check for a cached browse BrowseInfo cachedInfo = BrowseCache.get(scope); if (cachedInfo != null) { return cachedInfo; } // Run the Browse queries // If the focus is an Item, this returns the value String itemValue = getItemValue(scope); List results = new ArrayList(); results.addAll(getResultsBeforeFocus(scope, itemValue)); int beforeFocus = results.size(); results.addAll(getResultsAfterFocus(scope, itemValue, beforeFocus)); // Find out the total in the index, and the number of // matches for the query int total = countTotalInIndex(scope, results.size()); int matches = countMatches(scope, itemValue, total, results.size()); if (log.isDebugEnabled()) { log.debug("Number of matches " + matches); } int position = getPosition(total, matches, beforeFocus); sortResults(scope, results); BrowseInfo info = new BrowseInfo(results, position, total, beforeFocus); logInfo(info); BrowseCache.add(scope, info); return info; } /** * If focus refers to an Item, return a value for the item (its title, * author, accession date, etc). Otherwise return null. * * In general, the queries for these values look like this: select * max(date_issued) from ItemsByDate where item_id = 7; * * The max operator ensures that only one value is returned. * * If limiting to a community or collection, we add a clause like: * community_id = 7 collection_id = 201 * * @param scope * @return desired value for the item * @throws SQLException */ protected static String getItemValue(BrowseScope scope) throws SQLException { if (!scope.focusIsItem()) { return null; } PreparedStatement statement = null; ResultSet results = null; try { String tablename = BrowseTables.getTable(scope); String column = BrowseTables.getValueColumn(scope); String itemValueQuery = new StringBuffer().append("select ") .append("max(").append(column).append(") from ").append( tablename).append(" where ").append(" item_id = ") .append(scope.getFocusItemId()).append( getScopeClause(scope, "and")).toString(); statement = createStatement(scope, itemValueQuery); results = statement.executeQuery(); String itemValue = results.next() ? results.getString(1) : null; if (log.isDebugEnabled()) { log.debug("Subquery value is " + itemValue); } return itemValue; } finally { if (statement != null) { statement.close(); } if (results != null) { results.close(); } } } /** * Run a database query and return results before the focus. * * @param scope * The Browse Scope * @param itemValue * If the focus is an Item, this is its value in the index (its * title, author, etc). * @return list of Item results * @throws SQLException */ protected static List getResultsBeforeFocus(BrowseScope scope, String itemValue) throws SQLException { // Starting from beginning of index if (!scope.hasFocus()) { return Collections.EMPTY_LIST; } // No previous results desired if (scope.getNumberBefore() == 0) { return Collections.EMPTY_LIST; } // ItemsByAuthor. Since this is an exact match, it // does not make sense to return values before the // query. if (scope.getBrowseType() == ITEMS_BY_AUTHOR_BROWSE || scope.getBrowseType() == ITEMS_BY_SUBJECT_BROWSE) { return Collections.EMPTY_LIST; } PreparedStatement statement = createSql(scope, itemValue, false, false); List qresults = DatabaseManager.query(statement).toList(); int numberDesired = scope.getNumberBefore(); List results = getResults(scope, qresults, numberDesired); if (!results.isEmpty()) { Collections.reverse(results); } return results; } /** * Run a database query and return results after the focus. * * @param scope * The Browse Scope * @param itemValue * If the focus is an Item, this is its value in the index (its * title, author, etc). * @param count * @return list of results after the focus * @throws SQLException */ protected static List getResultsAfterFocus(BrowseScope scope, String itemValue, int count) throws SQLException { // No results desired if (scope.getTotal() == 0) { return Collections.EMPTY_LIST; } PreparedStatement statement = createSql(scope, itemValue, true, false); List qresults = DatabaseManager.query(statement).toList(); // The number of results we want is either -1 (everything) // or the total, less the number already retrieved. int numberDesired = -1; if (!scope.hasNoLimit()) { numberDesired = Math.max(scope.getTotal() - count, 0); } return getResults(scope, qresults, numberDesired); } /* * Return the total number of values in an index. * * <p> We total Authors with SQL like: select count(distinct author) from * ItemsByAuthor; ItemsByAuthor with: select count(*) from ItemsByAuthor * where author = ?; and every other index with: select count(*) from * ItemsByTitle; </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -