/* * BookmarkManager.java * * Version: $Revision: $ * * Date: $Date: $ * * Copyright (c) 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.eperson; import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.content.Item; import org.dspace.core.ConfigurationManager; import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.TableRow; import org.dspace.eperson.Tag; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; import java.util.StringTokenizer; /** * Class defining methods for bookmarking items in the repository. Based heavily on the work from Subscribe.java * * @author Desmond Elliott * @version $Revision: $ */ public class BookmarkManager { /** log4j logger */ private static Logger log = Logger.getLogger(BookmarkManager.class); private Context currentContext = null; /** * Bookmark this item * * @param context * DSpace context * @param eperson * EPerson to associate this bookmark with * @param item * Item to bookmark */ public static void bookmark(Context context, EPerson eperson, Item item, String tag) throws AuthorizeException, SQLException { if ( (tag == null) || "".equals(tag) ) { BookmarkManager.unBookmark(context, eperson, item); return; } StringTokenizer st = new StringTokenizer(tag,";"); if (!st.hasMoreTokens()) BookmarkManager.unBookmark(context, eperson, item); // Check authorisation. Must be administrator, or the eperson. EPerson currentUser = context.getCurrentUser(); if (AuthorizeManager.isAdmin(context) || ((eperson != null) && (currentUser != null) && (currentUser.getID() == eperson.getID()))) { String oldTag = getBookmarkTag(context, eperson, item); if ((oldTag != null) && !oldTag.equals(tag) ) { DatabaseManager.updateQuery(context, "DELETE FROM bookmark WHERE eperson_id= ? " + "AND item_id= ? ", eperson.getID(), item.getID()); log.info(LogManager.getHeader(context, "unbookmark", "eperson_id=" + eperson.getID() + ",item_id=" + item.getID())); } if ((oldTag == null) || !oldTag.equals(tag) ) { while(st.hasMoreTokens()){ String oneTag = st.nextToken().trim(); if (oneTag.length() > 0) { TableRow row = DatabaseManager.create(context, "bookmark"); row.setColumn("eperson_id", eperson.getID()); row.setColumn("item_id", item.getID()); row.setColumn("tag_value", oneTag); DatabaseManager.update(context, row); } } log.info(LogManager.getHeader(context, "bookmark ", "eperson_id=" + eperson.getID() + ", item_id=" + item.getID() + ", tag=" + tag)); } } else { throw new AuthorizeException( "Only admin or e-person themselves can bookmark"); } } /** * Unbookmark an item * * @param context * DSpace context * @param eperson * EPerson associated with this bookmarked item * @param item * Item to unbookmark */ public static void unBookmark(Context context, EPerson eperson, Item item) throws AuthorizeException, SQLException { // Check authorisation. Must be administrator, or the eperson. EPerson currentUser = context.getCurrentUser(); if (AuthorizeManager.isAdmin(context) || ((eperson != null) && (currentUser != null) && (currentUser.getID() == eperson.getID()))) { if (item != null) { if (isBookmarked(context, eperson, item)) { DatabaseManager.updateQuery(context, "DELETE FROM bookmark WHERE eperson_id= ? " + "AND item_id= ? ", eperson.getID(), item.getID()); log.info(LogManager.getHeader(context, "unbookmark", "eperson_id=" + eperson.getID() + ",item_id=" + item.getID())); } else { log.info(LogManager.getHeader(context, "unbookmark", "not_bookmarked,item_id=" + item.getID())); } } else { log.debug(LogManager.getHeader(context, "unbookmark","no item")); } } else { throw new AuthorizeException( "Only admin or e-person themselves can unbookmark"); } } /** * Bookmark this item with one tag (may be added to existing one) * * @param context * DSpace context * @param eperson * EPerson to associate this bookmark with * @param item * Item to bookmark */ public static void bookmarkOne(Context context, EPerson eperson, Item item, String oneTag) throws AuthorizeException, SQLException { // Check authorisation. Must be administrator, or the eperson. EPerson currentUser = context.getCurrentUser(); if (AuthorizeManager.isAdmin(context) || ((eperson != null) && (currentUser != null) && (currentUser.getID() == eperson.getID()))) { if (item != null) { boolean there = false; try { Object[] parameters = new Object[3]; parameters[0] = new Integer(eperson.getID()); parameters[1] = new Integer(item.getID()); parameters[2] = oneTag; TableRowIterator tri = DatabaseManager.query(context, "SELECT tag_value FROM bookmark WHERE eperson_id= ? AND item_id = ? AND tag_value = ? ", parameters ); there = tri.hasNext(); tri.close(); } catch (SQLException e) { log.info(LogManager.getHeader(context, "bookmark ", "eperson_id=" + eperson.getID() + ", item_id=" + item.getID() + ", added tag=" + oneTag + ", Exception:" + e.toString() )); } if ( ! there ) { TableRow row = DatabaseManager.create(context, "bookmark"); row.setColumn("eperson_id", eperson.getID()); row.setColumn("item_id", item.getID()); row.setColumn("tag_value", oneTag); DatabaseManager.update(context, row); log.info(LogManager.getHeader(context, "bookmark ", "eperson_id=" + eperson.getID() + ", item_id=" + item.getID() + ", added tag=" + oneTag)); } } else { log.debug(LogManager.getHeader(context, "bookmark "+oneTag,"no item")); } } else { throw new AuthorizeException( "Only admin or e-person themselves can bookmark"); } } /** * Unbookmark an item * * @param context * DSpace context * @param eperson * EPerson associated with this bookmarked item * @param item * Item to unbookmark */ public static void unBookmarkOne(Context context, EPerson eperson, Item item, String oneTag) throws AuthorizeException, SQLException { // Check authorisation. Must be administrator, or the eperson. EPerson currentUser = context.getCurrentUser(); if (AuthorizeManager.isAdmin(context) || ((eperson != null) && (currentUser != null) && (currentUser.getID() == eperson.getID()))) { if (item != null) { Object[] parameters = new Object[3]; parameters[0] = new Integer(eperson.getID()); parameters[1] = new Integer(item.getID()); parameters[2] = oneTag; DatabaseManager.updateQuery(context, "DELETE FROM bookmark WHERE eperson_id= ? " + "AND item_id= ? AND tag_value= ? ", parameters ); log.info(LogManager.getHeader(context, "unbookmark", "eperson_id=" + eperson.getID() + ",item_id=" + item.getID() + ", tag=" + oneTag )); } else { log.debug(LogManager.getHeader(context, "unbookmark "+oneTag,"no item")); } } else { throw new AuthorizeException( "Only admin or e-person themselves can unbookmark"); } } /** * Find out which items a person has bookmarked * * @param context * DSpace context * @param eperson * EPerson * @return array of items e-person has bookmarked */ public static Item[] getBookmarks(Context context, EPerson eperson) throws SQLException { TableRowIterator tri = DatabaseManager.query(context, "SELECT item_id FROM bookmark WHERE eperson_id= ? ", eperson.getID()); List items = new ArrayList(); while (tri.hasNext()) { TableRow row = tri.next(); items.add(Item.find(context, row.getIntColumn("item_id"))); } tri.close(); Item[] itemArray = new Item[items.size()]; return (Item[]) items.toArray(itemArray); } public static Item[] getBookmarks(Context context, EPerson eperson, String tag) throws SQLException { if ((tag == null) || "".equals(tag)) return getBookmarks(context,eperson); TableRowIterator tri = DatabaseManager.query(context, "SELECT item_id FROM bookmark WHERE tag_value= ? AND eperson_id= ?", tag, eperson.getID()); List items = new ArrayList(); while (tri.hasNext()) { TableRow row = tri.next(); items.add(Item.find(context, row.getIntColumn("item_id"))); } tri.close(); Item[] itemArray = new Item[items.size()]; return (Item[]) items.toArray(itemArray); } public static Item[] getBookmarks(Context context, String tag) throws SQLException { if ((tag == null) || "".equals(tag)) return null; TableRowIterator tri = DatabaseManager.query(context, "SELECT item_id FROM bookmark WHERE tag_value= ?", tag); List items = new ArrayList(); while (tri.hasNext()) { TableRow row = tri.next(); items.add(Item.find(context, row.getIntColumn("item_id"))); } tri.close(); Item[] itemArray = new Item[items.size()]; return (Item[]) items.toArray(itemArray); } /** * Find out what is the tag a person has bookmarked for an item * * @param context * DSpace context * @param eperson * EPerson * @return array of items e-person has bookmarked */ public static String getBookmarkTag(Context context, EPerson eperson, Item item) { String tag = null; try { TableRowIterator tri = DatabaseManager.query(context, "SELECT tag_value FROM bookmark WHERE eperson_id= ? AND item_id= ?", eperson.getID(),item.getID()); tag = ""; while (tri.hasNext()) { TableRow row = tri.next(); String aTag = row.getStringColumn("tag_value"); if ("".equals(aTag)) aTag = "SELECTED"; tag = tag+aTag+"; "; } tri.close(); tag = tag.trim(); } catch (SQLException e) { } return tag; } /** * Find out what is the tag OTHER persons have bookmarked for an item * * @param context * DSpace context * @param eperson * EPerson * @return array of items e-person has bookmarked */ public static String getBookmarkOtherTag(Context context, EPerson eperson, Item item) { String tag = null; try { TableRowIterator tri = null; if (eperson == null) tri = DatabaseManager.query(context, "SELECT tag_value FROM bookmark WHERE item_id= ?", item.getID()); else tri = DatabaseManager.query(context, "SELECT tag_value FROM bookmark WHERE eperson_id != ? AND item_id= ?", eperson.getID(),item.getID()); tag = ""; while (tri.hasNext()) { TableRow row = tri.next(); String aTag = row.getStringColumn("tag_value"); if ("".equals(aTag)) aTag = "SELECTED"; tag = tag+aTag+"; "; } tri.close(); tag = tag.trim(); } catch (SQLException e) { } return tag; } /** * Find out what is the tag a person has bookmarked for an item * * @param context * DSpace context * @param eperson * EPerson * @return array of items e-person has bookmarked */ public static TreeMap getBookmarkTags(Context context, EPerson eperson) { TreeMap tags = new TreeMap(); try { TableRowIterator tri = DatabaseManager.query(context, "SELECT tag_value, count(eperson_id) AS freq FROM bookmark WHERE eperson_id= ? GROUP BY tag_value", eperson.getID() ); while (tri.hasNext()) { TableRow row = tri.next(); String aTag = row.getStringColumn("tag_value"); int freq = row.getIntColumn("freq"); if (aTag != null) tags.put(aTag,new Integer(freq)); } tri.close(); } catch (SQLException e) { } return tags; } public static TreeMap getBookmarkAllTags(Context context) { TreeMap tags = new TreeMap(); try { TableRowIterator tri = DatabaseManager.query(context, "SELECT tag_value, count(eperson_id) AS freq FROM bookmark GROUP BY tag_value" ); while (tri.hasNext()) { TableRow row = tri.next(); String aTag = row.getStringColumn("tag_value"); int freq = row.getIntColumn("freq"); if (aTag != null) tags.put(aTag,new Integer(freq)); } tri.close(); } catch (SQLException e) { } return tags; } /** * Has this eperson bookmarked this item? * * @param context * DSpace context * @param eperson * find out if this e-person has bookmarked * @param item * find out if this item has been bookmarked * @return true if they are bookmarked */ public static boolean isBookmarked(Context context, EPerson eperson, Item item) throws SQLException { TableRowIterator tri = DatabaseManager.query(context, "SELECT * FROM bookmark WHERE eperson_id= ? " + "AND item_id= ? ", eperson.getID(), item.getID()); boolean result = tri.hasNext(); tri.close(); return result; } public void setContext(Context context) { this.currentContext = context; } public Context getContext() { return this.currentContext; } public ArrayList getAllTags() { if (currentContext == null) return null; EPerson currentUser = currentContext.getCurrentUser(); ArrayList tags = new ArrayList(); try { TableRowIterator tri = DatabaseManager.query(currentContext, "SELECT tag_value, sum (case when eperson_id= ? then 1 else 0 end) AS freqUser, count(eperson_id) AS freq FROM bookmark GROUP BY tag_value", currentUser == null? 0 : currentUser.getID() ); while (tri.hasNext()) { TableRow row = tri.next(); Tag aTag = new Tag ( row.getStringColumn("tag_value"), currentUser, row.getIntColumn("freq"), row.getIntColumn("freqUser") ); tags.add(aTag); } tri.close(); } catch (SQLException e) { } return tags; } public static String getStatsTags(Context context) { if (context == null) return null; String tagVu = ConfigurationManager.getProperty("webui.itemlist.tagviewed"); if (tagVu == null || tagVu.length()==0) tagVu = "v"; String result = ""; try { TableRowIterator tri = DatabaseManager.query(context, "SELECT sum (case when tag_value ILIKE ? then 1 else 0 end) AS viewed, count(*) AS total FROM bookmark", tagVu ); if (tri.hasNext()) { TableRow row = tri.next(); result = row.getIntColumn("total") + " (" + tagVu +":"+ row.getIntColumn("viewed") + ")"; } tri.close(); } catch (SQLException e) { } return result; } }