Option to generate community and collection "strength" as a batch job

git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2328 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Richard Jones
2007-11-12 11:59:47 +00:00
parent 8a7e41a5fe
commit 8d7b59f45d
17 changed files with 1315 additions and 12 deletions

View File

@@ -0,0 +1,98 @@
/*
* ItemCountDAO.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.Community;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.content.DSpaceObject;
/**
* Interface for data access of cached community and collection item count
* information
*
* @author Richard Jones
*
*/
public interface ItemCountDAO
{
/**
* Set the DSpace Context to use during data access
*
* @param context
* @throws ItemCountException
*/
public void setContext(Context context) throws ItemCountException;
/**
* Set the given count as the number of items in the given community
*
* @param community
* @param count
* @throws ItemCountException
*/
public void communityCount(Community community, int count) throws ItemCountException;
/**
* Set the given count as the number of items in the given collection
*
* @param collection
* @param count
* @throws ItemCountException
*/
public void collectionCount(Collection collection, int count) throws ItemCountException;
/**
* Get the number of items in the given DSpaceObject container. This method will
* only succeed if the DSpaceObject is an instance of either a Community or a
* Collection. Otherwise it will throw an exception
*
* @param dso
* @return
* @throws ItemCountException
*/
public int getCount(DSpaceObject dso) throws ItemCountException;
/**
* Remove any cached data regarding the given DSpaceObject container. This method will
* only succeed if the DSpaceObject is an instance of either a Community or a
* Collection. Otherwise it will throw an exception
*
* @param dso
* @throws ItemCountException
*/
public void remove(DSpaceObject dso) throws ItemCountException;
}

View File

@@ -0,0 +1,79 @@
/*
* ItemCountDAOFactory.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.core.Context;
import org.dspace.core.ConfigurationManager;
/**
* Factory class to allow us to load the correct DAO for registering
* item count information
*
* @author Richard Jones
*
*/
public class ItemCountDAOFactory
{
/**
* Get an instance of ItemCountDAO which supports the correct database
* for the specific DSpace instance.
*
* @param context
* @return
* @throws ItemCountException
*/
public static ItemCountDAO getInstance(Context context)
throws ItemCountException
{
String db = ConfigurationManager.getProperty("db.name");
ItemCountDAO dao;
if ("postgres".equals(db))
{
dao = new ItemCountDAOPostgres();
}
else if ("oracle".equals(db))
{
dao = new ItemCountDAOOracle();
}
else
{
throw new ItemCountException("Database type: " + db + " is not currently supported");
}
dao.setContext(context);
return dao;
}
}

View File

@@ -0,0 +1,336 @@
/*
* ItemCountDAOOracle.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.apache.log4j.Logger;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.storage.rdbms.TableRowIterator;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.DatabaseManager;
import java.sql.SQLException;
/**
* Oracle driver implementing ItemCountDAO interface to cache item
* count information in communities and collections
*
* @author Richard Jones
*
*/
public class ItemCountDAOOracle implements ItemCountDAO
{
/** Log4j logger */
private static Logger log = Logger.getLogger(ItemCountDAOOracle.class);
/** DSpace context */
private Context context;
/** SQL to select on a collection id */
private String collectionSelect = "SELECT * FROM collection_item_count WHERE collection_id = ?";
/** SQL to insert a new collection record */
private String collectionInsert = "INSERT INTO collection_item_count (collection_id, number) VALUES (?, ?)";
/** SQL to update an existing collection record */
private String collectionUpdate = "UPDATE collection_item_count SET number = ? WHERE collection_id = ?";
/** SQL to remove a collection record */
private String collectionRemove = "DELETE FROM collection_item_count WHERE collection_id = ?";
/** SQL to select on a community id */
private String communitySelect = "SELECT * FROM community_item_count WHERE community_id = ?";
/** SQL to insert a new community record */
private String communityInsert = "INSERT INTO community_item_count (community_id, number) VALUES (?, ?)";
/** SQL to update an existing community record */
private String communityUpdate = "UPDATE community_item_count SET number = ? WHERE community_id = ?";
/** SQL to remove a community record */
private String communityRemove = "DELETE FROM community_item_count WHERE community_id = ?";
/**
* Store the count of the given collection
*
* @param collection
* @param count
* @throws ItemCountException
*/
public void collectionCount(Collection collection, int count)
throws ItemCountException
{
try
{
// first find out if we have a record
Object[] sparams = { new Integer(collection.getID()) };
TableRowIterator tri = DatabaseManager.query(context, collectionSelect, sparams);
if (tri.hasNext())
{
Object[] params = { new Integer(count), new Integer(collection.getID()) };
DatabaseManager.updateQuery(context, collectionUpdate, params);
}
else
{
Object[] params = { new Integer(collection.getID()), new Integer(count) };
DatabaseManager.updateQuery(context, collectionInsert, params);
}
tri.close();
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Store the count of the given community
*
* @param community
* @param count
* @throws ItemCountException
*/
public void communityCount(Community community, int count)
throws ItemCountException
{
try
{
// first find out if we have a record
Object[] sparams = { new Integer(community.getID()) };
TableRowIterator tri = DatabaseManager.query(context, communitySelect, sparams);
if (tri.hasNext())
{
Object[] params = { new Integer(count), new Integer(community.getID()) };
DatabaseManager.updateQuery(context, communityUpdate, params);
}
else
{
Object[] params = { new Integer(community.getID()), new Integer(count) };
DatabaseManager.updateQuery(context, communityInsert, params);
}
tri.close();
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Set the dspace context to use
*
* @param context
* @throws ItemCountException
*/
public void setContext(Context context)
throws ItemCountException
{
this.context = context;
}
/**
* get the count of the items in the given container
*
* @param dso
* @return
* @throws ItemCountException
*/
public int getCount(DSpaceObject dso)
throws ItemCountException
{
if (dso instanceof Collection)
{
return getCollectionCount((Collection) dso);
}
else if (dso instanceof Community)
{
return getCommunityCount((Community) dso);
}
else
{
throw new ItemCountException("We can only count items in Communities or Collections");
}
}
/**
* remove the cache for the given container
*
* @param dso
* @throws ItemCountException
*/
public void remove(DSpaceObject dso) throws ItemCountException
{
if (dso instanceof Collection)
{
removeCollection((Collection) dso);
}
else if (dso instanceof Community)
{
removeCommunity((Community) dso);
}
else
{
throw new ItemCountException("We can only delete count of items from Communities or Collections");
}
}
/**
* remove the cache for the given collection
*
* @param collection
* @throws ItemCountException
*/
private void removeCollection(Collection collection)
throws ItemCountException
{
try
{
Object[] params = { new Integer(collection.getID()) };
DatabaseManager.updateQuery(context, collectionRemove, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Remove the cache for the given community
*
* @param community
* @throws ItemCountException
*/
private void removeCommunity(Community community)
throws ItemCountException
{
try
{
Object[] params = { new Integer(community.getID()) };
DatabaseManager.updateQuery(context, communityRemove, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Get the count for the given collection
*
* @param collection
* @return
* @throws ItemCountException
*/
private int getCollectionCount(Collection collection)
throws ItemCountException
{
try
{
Object[] params = { new Integer(collection.getID()) };
TableRowIterator tri = DatabaseManager.query(context, collectionSelect, params);
if (!tri.hasNext())
{
return 0;
}
TableRow tr = tri.next();
if (tri.hasNext())
{
throw new ItemCountException("More than one count row in the database");
}
tri.close();
return tr.getIntColumn("number");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* get the count for the given community
*
* @param community
* @return
* @throws ItemCountException
*/
private int getCommunityCount(Community community)
throws ItemCountException
{
try
{
Object[] params = { new Integer(community.getID()) };
TableRowIterator tri = DatabaseManager.query(context, communitySelect, params);
if (!tri.hasNext())
{
return 0;
}
TableRow tr = tri.next();
if (tri.hasNext())
{
throw new ItemCountException("More than one count row in the database");
}
tri.close();
return tr.getIntColumn("number");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
}

View File

@@ -0,0 +1,336 @@
/*
* ItemCountDAOPostgres.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.apache.log4j.Logger;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.storage.rdbms.TableRowIterator;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.DatabaseManager;
import java.sql.SQLException;
/**
* Postgres driver implementing ItemCountDAO interface to cache item
* count information in communities and collections
*
* @author Richard Jones
*
*/
public class ItemCountDAOPostgres implements ItemCountDAO
{
/** Log4j logger */
private static Logger log = Logger.getLogger(ItemCountDAOPostgres.class);
/** DSpace context */
private Context context;
/** SQL to select on a collection id */
private String collectionSelect = "SELECT * FROM collection_item_count WHERE collection_id = ?";
/** SQL to insert a new collection record */
private String collectionInsert = "INSERT INTO collection_item_count (collection_id, number) VALUES (?, ?)";
/** SQL to update an existing collection record */
private String collectionUpdate = "UPDATE collection_item_count SET number = ? WHERE collection_id = ?";
/** SQL to remove a collection record */
private String collectionRemove = "DELETE FROM collection_item_count WHERE collection_id = ?";
/** SQL to select on a community id */
private String communitySelect = "SELECT * FROM community_item_count WHERE community_id = ?";
/** SQL to insert a new community record */
private String communityInsert = "INSERT INTO community_item_count (community_id, number) VALUES (?, ?)";
/** SQL to update an existing community record */
private String communityUpdate = "UPDATE community_item_count SET number = ? WHERE community_id = ?";
/** SQL to remove a community record */
private String communityRemove = "DELETE FROM community_item_count WHERE community_id = ?";
/**
* Store the count of the given collection
*
* @param collection
* @param count
* @throws ItemCountException
*/
public void collectionCount(Collection collection, int count)
throws ItemCountException
{
try
{
// first find out if we have a record
Object[] sparams = { new Integer(collection.getID()) };
TableRowIterator tri = DatabaseManager.query(context, collectionSelect, sparams);
if (tri.hasNext())
{
Object[] params = { new Integer(count), new Integer(collection.getID()) };
DatabaseManager.updateQuery(context, collectionUpdate, params);
}
else
{
Object[] params = { new Integer(collection.getID()), new Integer(count) };
DatabaseManager.updateQuery(context, collectionInsert, params);
}
tri.close();
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Store the count of the given community
*
* @param community
* @param count
* @throws ItemCountException
*/
public void communityCount(Community community, int count)
throws ItemCountException
{
try
{
// first find out if we have a record
Object[] sparams = { new Integer(community.getID()) };
TableRowIterator tri = DatabaseManager.query(context, communitySelect, sparams);
if (tri.hasNext())
{
Object[] params = { new Integer(count), new Integer(community.getID()) };
DatabaseManager.updateQuery(context, communityUpdate, params);
}
else
{
Object[] params = { new Integer(community.getID()), new Integer(count) };
DatabaseManager.updateQuery(context, communityInsert, params);
}
tri.close();
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Set the dspace context to use
*
* @param context
* @throws ItemCountException
*/
public void setContext(Context context)
throws ItemCountException
{
this.context = context;
}
/**
* get the count of the items in the given container
*
* @param dso
* @return
* @throws ItemCountException
*/
public int getCount(DSpaceObject dso)
throws ItemCountException
{
if (dso instanceof Collection)
{
return getCollectionCount((Collection) dso);
}
else if (dso instanceof Community)
{
return getCommunityCount((Community) dso);
}
else
{
throw new ItemCountException("We can only count items in Communities or Collections");
}
}
/**
* remove the cache for the given container
*
* @param dso
* @throws ItemCountException
*/
public void remove(DSpaceObject dso) throws ItemCountException
{
if (dso instanceof Collection)
{
removeCollection((Collection) dso);
}
else if (dso instanceof Community)
{
removeCommunity((Community) dso);
}
else
{
throw new ItemCountException("We can only delete count of items from Communities or Collections");
}
}
/**
* remove the cache for the given collection
*
* @param collection
* @throws ItemCountException
*/
private void removeCollection(Collection collection)
throws ItemCountException
{
try
{
Object[] params = { new Integer(collection.getID()) };
DatabaseManager.updateQuery(context, collectionRemove, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Remove the cache for the given community
*
* @param community
* @throws ItemCountException
*/
private void removeCommunity(Community community)
throws ItemCountException
{
try
{
Object[] params = { new Integer(community.getID()) };
DatabaseManager.updateQuery(context, communityRemove, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Get the count for the given collection
*
* @param collection
* @return
* @throws ItemCountException
*/
private int getCollectionCount(Collection collection)
throws ItemCountException
{
try
{
Object[] params = { new Integer(collection.getID()) };
TableRowIterator tri = DatabaseManager.query(context, collectionSelect, params);
if (!tri.hasNext())
{
return 0;
}
TableRow tr = tri.next();
if (tri.hasNext())
{
throw new ItemCountException("More than one count row in the database");
}
tri.close();
return tr.getIntColumn("number");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* get the count for the given community
*
* @param community
* @return
* @throws ItemCountException
*/
private int getCommunityCount(Community community)
throws ItemCountException
{
try
{
Object[] params = { new Integer(community.getID()) };
TableRowIterator tri = DatabaseManager.query(context, communitySelect, params);
if (!tri.hasNext())
{
return 0;
}
TableRow tr = tri.next();
if (tri.hasNext())
{
throw new ItemCountException("More than one count row in the database");
}
tri.close();
return tr.getIntColumn("number");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* ItemCountException.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;
/**
* Exception type to handle item count specific problems
*
* @author Richard Jones
*
*/
public class ItemCountException extends Exception
{
public ItemCountException()
{
}
public ItemCountException(String message)
{
super(message);
}
public ItemCountException(Throwable cause)
{
super(cause);
}
public ItemCountException(String message, Throwable cause)
{
super(message, cause);
}
}

View File

@@ -0,0 +1,280 @@
/*
* ItemCounter.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.apache.log4j.Logger;
import org.dspace.content.Community;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.content.DSpaceObject;
import org.dspace.core.ConfigurationManager;
import java.sql.SQLException;
/**
* This class provides a standard interface to all item counting
* operations for communities and collections. It can be run from the
* command line to prepare the cached data if desired, simply by
* running:
*
* java org.dspace.browse.ItemCounter
*
* It can also be invoked via its standard API. In the event that
* the data cache is not being used, this class will return direct
* real time counts of content.
*
* @author Richard Jones
*
*/
public class ItemCounter
{
/** Log4j logger */
private static Logger log = Logger.getLogger(ItemCounter.class);
/** DAO to use to store and retrieve data */
private ItemCountDAO dao;
/** DSpace Context */
private Context context;
/**
* method invoked by CLI which will result in the number of items
* in each community and collection being cached. These counts will
* not update themselves until this is run again.
*
* @param args
*/
public static void main(String[] args)
throws ItemCountException
{
ItemCounter ic = new ItemCounter();
ic.buildItemCounts();
ic.completeContext();
}
/**
* Construct a new item counter which will create its own
* DSpace Context
*
* @throws ItemCountException
*/
public ItemCounter()
throws ItemCountException
{
try
{
this.context = new Context();
this.dao = ItemCountDAOFactory.getInstance(this.context);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Construct a new item counter which will use the give DSpace Context
*
* @param context
* @throws ItemCountException
*/
public ItemCounter(Context context)
throws ItemCountException
{
this.context = context;
this.dao = ItemCountDAOFactory.getInstance(this.context);
}
/**
* Complete the context being used by this class. This exists so that
* instances of this class which created their own instance of the
* DSpace Context can also terminate it. For Context object which were
* passed in by the constructor, the caller is responsible for
* either calling this method themselves or completing the context
* when they need to.
*
* @throws ItemCountException
*/
public void completeContext()
throws ItemCountException
{
try
{
this.context.complete();
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* This method does the grunt work of drilling through and iterating
* over all of the communities and collections in the system and
* obtaining and caching the item counts for each one.
*
* @throws ItemCountException
*/
public void buildItemCounts()
throws ItemCountException
{
try
{
Community[] tlc = Community.findAllTop(context);
for (int i = 0; i < tlc.length; i++)
{
count(tlc[i]);
}
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* Get the count of the items in the given container. If the configuration
* value webui.strengths.cache is equal to 'true' this will return the
* cached value if it exists. If it is equal to 'false' it will count
* the number of items in the container in real time
*
* @param dso
* @return
* @throws ItemCountException
*/
public int getCount(DSpaceObject dso)
throws ItemCountException
{
boolean useCache = ConfigurationManager.getBooleanProperty("webui.strengths.cache");
if (useCache)
{
return dao.getCount(dso);
}
// if we make it this far, we need to manually count
if (dso instanceof Collection)
{
return ((Collection) dso).countItems();
}
if (dso instanceof Community)
{
return ((Collection) dso).countItems();
}
return 0;
}
/**
* Remove any cached data for the given container
*
* @param dso
* @throws ItemCountException
*/
public void remove(DSpaceObject dso)
throws ItemCountException
{
dao.remove(dso);
}
/**
* count and cache the number of items in the community. This
* will include all sub-communities and collections in the
* community. It will also recurse into sub-communities and
* collections and call count() on them also.
*
* Therefore, the count the contents of the entire system, it is
* necessary just to call this method on each top level community
*
* @param community
* @throws ItemCountException
*/
private void count(Community community)
throws ItemCountException
{
try
{
// first count the community we are in
int count = community.countItems();
dao.communityCount(community, count);
// now get the sub-communities
Community[] scs = community.getSubcommunities();
for (int i = 0; i < scs.length; i++)
{
count(scs[i]);
}
// now get the collections
Collection[] cols = community.getCollections();
for (int i = 0; i < cols.length; i++)
{
count(cols[i]);
}
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
/**
* count and cache the number of items in the given collection
*
* @param collection
* @throws ItemCountException
*/
private void count(Collection collection)
throws ItemCountException
{
try
{
int ccount = collection.countItems();
dao.collectionCount(collection, ccount);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new ItemCountException(e);
}
}
}

View File

@@ -1053,6 +1053,19 @@ public class Collection extends DSpaceObject
wsarray[x].deleteAll(); wsarray[x].deleteAll();
} }
// get rid of the content count cache if it exists
try
{
ItemCounter ic = new ItemCounter(ourContext);
ic.remove(this);
}
catch (ItemCountException e)
{
// FIXME: upside down exception handling due to lack of good
// exception framework
throw new SQLException(e);
}
// Delete collection row // Delete collection row
DatabaseManager.delete(ourContext, collectionRow); DatabaseManager.delete(ourContext, collectionRow);

View File

@@ -906,6 +906,19 @@ public class Community extends DSpaceObject
// Remove all authorization policies // Remove all authorization policies
AuthorizeManager.removeAllPolicies(ourContext, this); AuthorizeManager.removeAllPolicies(ourContext, this);
// get rid of the content count cache if it exists
try
{
ItemCounter ic = new ItemCounter(ourContext);
ic.remove(this);
}
catch (ItemCountException e)
{
// FIXME: upside down exception handling due to lack of good
// exception framework
throw new SQLException(e);
}
// Delete community row // Delete community row
DatabaseManager.delete(ourContext, communityRow); DatabaseManager.delete(ourContext, communityRow);
} }

View File

@@ -67,6 +67,7 @@
<%@ page import="org.dspace.core.ConfigurationManager"%> <%@ page import="org.dspace.core.ConfigurationManager"%>
<%@ page import="org.dspace.eperson.Group" %> <%@ page import="org.dspace.eperson.Group" %>
<%@ page import="org.dspace.browse.BrowseIndex" %> <%@ page import="org.dspace.browse.BrowseIndex" %>
<%@ page import="org.dspace.browse.ItemCounter" %>
<%@ page import="org.dspace.app.webui.components.RecentSubmissions" %> <%@ page import="org.dspace.app.webui.components.RecentSubmissions" %>
<%@ page import="org.dspace.content.Item" %> <%@ page import="org.dspace.content.Item" %>
@@ -127,6 +128,8 @@
{ {
feedData = "coll:" + ConfigurationManager.getProperty("webui.feed.formats"); feedData = "coll:" + ConfigurationManager.getProperty("webui.feed.formats");
} }
ItemCounter ic = new ItemCounter();
%> %>
<dspace:layout locbar="commLink" title="<%= name %>" feedData="<%= feedData %>"> <dspace:layout locbar="commLink" title="<%= name %>" feedData="<%= feedData %>">
@@ -139,7 +142,7 @@
if(ConfigurationManager.getBooleanProperty("webui.strengths.show")) if(ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
: [<%= collection.countItems() %>] : [<%= ic.getCount(collection) %>]
<% <%
} }
%> %>

View File

@@ -64,6 +64,7 @@
<%@ page import="org.dspace.core.Utils" %> <%@ page import="org.dspace.core.Utils" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ page import="org.dspace.core.ConfigurationManager" %>
<%@ page import="org.dspace.browse.BrowseIndex" %> <%@ page import="org.dspace.browse.BrowseIndex" %>
<%@ page import="org.dspace.browse.ItemCounter" %>
<%@ page import="org.dspace.app.webui.components.RecentSubmissions" %> <%@ page import="org.dspace.app.webui.components.RecentSubmissions" %>
<%@ page import="org.dspace.content.Item" %> <%@ page import="org.dspace.content.Item" %>
@@ -104,6 +105,8 @@
{ {
feedData = "comm:" + ConfigurationManager.getProperty("webui.feed.formats"); feedData = "comm:" + ConfigurationManager.getProperty("webui.feed.formats");
} }
ItemCounter ic = new ItemCounter();
%> %>
<dspace:layout locbar="commLink" title="<%= name %>" feedData="<%= feedData %>"> <dspace:layout locbar="commLink" title="<%= name %>" feedData="<%= feedData %>">
@@ -111,7 +114,16 @@
<table border="0" cellpadding="5" width="100%"> <table border="0" cellpadding="5" width="100%">
<tr> <tr>
<td width="100%"> <td width="100%">
<h1><%= name %></h1> <h1><%= name %>
<%
if(ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{
%>
: [<%= ic.getCount(community) %>]
<%
}
%>
</h1>
<h3><fmt:message key="jsp.community-home.heading1"/></h3> <h3><fmt:message key="jsp.community-home.heading1"/></h3>
</td> </td>
<td valign="top"> <td valign="top">
@@ -209,7 +221,7 @@
if(ConfigurationManager.getBooleanProperty("webui.strengths.show")) if(ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
[<%= collections[i].countItems() %>] [<%= ic.getCount(collections[i]) %>]
<% <%
} }
%> %>
@@ -259,7 +271,7 @@
if (ConfigurationManager.getBooleanProperty("webui.strengths.show")) if (ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
[<%= subcommunities[j].countItems() %>] [<%= ic.getCount(subcommunities[j]) %>]
<% <%
} }
%> %>

View File

@@ -62,7 +62,8 @@
<%@ page import="org.dspace.content.Collection" %> <%@ page import="org.dspace.content.Collection" %>
<%@ page import="org.dspace.app.webui.servlet.admin.EditCommunitiesServlet" %> <%@ page import="org.dspace.app.webui.servlet.admin.EditCommunitiesServlet" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ page import="org.dspace.core.ConfigurationManager" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %> <%@ page import="org.dspace.browse.ItemCounter" %>
<%@ page import="org.dspace.browse.ItemCountException" %>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
@@ -73,6 +74,7 @@
Boolean admin_b = (Boolean)request.getAttribute("admin_button"); Boolean admin_b = (Boolean)request.getAttribute("admin_button");
boolean admin_button = (admin_b == null ? false : admin_b.booleanValue()); boolean admin_button = (admin_b == null ? false : admin_b.booleanValue());
boolean showAll = true; boolean showAll = true;
ItemCounter ic = new ItemCounter();
%> %>
<%! <%!
@@ -87,8 +89,15 @@
void showCommunity(Community c) throws IOException, SQLException void showCommunity(Community c) throws IOException, SQLException
{ {
try
{
ItemCounter ic = new ItemCounter();
out.println( "<li class=\"communityLink\">" ); out.println( "<li class=\"communityLink\">" );
out.println( "<strong><a href=\"" + request.getContextPath() + "/handle/" + c.getHandle() + "\">" + c.getMetadata("name") + "</a></strong>"); out.println( "<strong><a href=\"" + request.getContextPath() + "/handle/" + c.getHandle() + "\">" + c.getMetadata("name") + "</a></strong>");
if(ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{
out.println(" <span class=\"communityStrength\">[" + ic.getCount(c) + "]</span>");
}
// Get the collections in this community // Get the collections in this community
Collection[] cols = c.getCollections(); Collection[] cols = c.getCollections();
@@ -101,7 +110,7 @@
out.println("<a href=\"" + request.getContextPath() + "/handle/" + cols[j].getHandle() + "\">" + cols[j].getMetadata("name") +"</a>"); out.println("<a href=\"" + request.getContextPath() + "/handle/" + cols[j].getHandle() + "\">" + cols[j].getMetadata("name") +"</a>");
if(ConfigurationManager.getBooleanProperty("webui.strengths.show")) if(ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
out.println(" [" + cols[j].countItems() + "]"); out.println(" [" + ic.getCount(cols[j]) + "]");
} }
out.println("</li>"); out.println("</li>");
@@ -123,6 +132,12 @@
out.println("<br />"); out.println("<br />");
out.println("</li>"); out.println("</li>");
} }
catch (ItemCountException e)
{
// FIXME: except it's not
throw new SQLException(e);
}
}
%> %>
<dspace:layout titlekey="jsp.community-list.title"> <dspace:layout titlekey="jsp.community-list.title">
@@ -216,7 +231,7 @@
if (ConfigurationManager.getBooleanProperty("webui.strengths.show")) if (ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
[<%= cols[j].countItems() %>] [<%= ic.getCount(cols[j]) %>]
<% <%
} }
%> %>
@@ -241,7 +256,7 @@
if (ConfigurationManager.getBooleanProperty("webui.strengths.show")) if (ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
[<%= comms[k].countItems() %>] [<%= ic.getCount(comms[k]) %>]
<% <%
} }
%> %>

View File

@@ -60,6 +60,7 @@
<%@ page import="org.dspace.app.webui.util.UIUtil" %> <%@ page import="org.dspace.app.webui.util.UIUtil" %>
<%@ page import="org.dspace.content.Community" %> <%@ page import="org.dspace.content.Community" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ page import="org.dspace.core.ConfigurationManager" %>
<%@ page import="org.dspace.browse.ItemCounter" %>
<% <%
Community[] communities = (Community[]) request.getAttribute("communities"); Community[] communities = (Community[]) request.getAttribute("communities");
@@ -77,6 +78,7 @@
feedData = "ALL:" + ConfigurationManager.getProperty("webui.feed.formats"); feedData = "ALL:" + ConfigurationManager.getProperty("webui.feed.formats");
} }
ItemCounter ic = new ItemCounter();
%> %>
<dspace:layout locbar="nolink" titlekey="jsp.home.title" feedData="<%= feedData %>"> <dspace:layout locbar="nolink" titlekey="jsp.home.title" feedData="<%= feedData %>">
@@ -145,7 +147,7 @@ for (int i = supportedLocales.length-1; i >= 0; i--)
if (ConfigurationManager.getBooleanProperty("webui.strengths.show")) if (ConfigurationManager.getBooleanProperty("webui.strengths.show"))
{ {
%> %>
[<%= communities[i].countItems() %>] [<%= ic.getCount(communities[i]) %>]
<% <%
} }

View File

@@ -253,6 +253,11 @@ UL { font-family: "verdana", "Arial", "Helvetica", sans-serif;
font-size: 14pt; font-size: 14pt;
font-weight: bold } font-weight: bold }
.communityStrength {
font-family: "verdana", "Arial", "Helvetica", sans-serif;
font-size: 12pt;
font-weight: normal }
.communityDescription { margin-left: 20px; .communityDescription { margin-left: 20px;
margin-right: 10px; margin-right: 10px;
font-family: "verdana", "Arial", "Helvetica", sans-serif; font-family: "verdana", "Arial", "Helvetica", sans-serif;

View File

@@ -1,4 +1,4 @@
(Graham Triggs/Mark Diggory (Graham Triggs/Mark Diggory)
- S.F. Bug 1824710 Creative Commons RDF has changed. Adjusted CC processing to be XSL driven - S.F. Bug 1824710 Creative Commons RDF has changed. Adjusted CC processing to be XSL driven
and adjusted generated XML/RDF. Created LicenseCleanup CLI to process existing CC license_rdf and adjusted generated XML/RDF. Created LicenseCleanup CLI to process existing CC license_rdf
@@ -11,6 +11,7 @@ SF Patch 1794700 Bug fix for stat-monthly and stat-report-monthly
(Richard Jones) (Richard Jones)
- S.F. Patch 1670093 More stable metadata and schema registry import - S.F. Patch 1670093 More stable metadata and schema registry import
- Option to generate community and collection "strength" as a batch job
(Richard Jones / Graham Triggs) (Richard Jones / Graham Triggs)
- New Browse code that allows customisation of the available indexes via dspace.cfg, - New Browse code that allows customisation of the available indexes via dspace.cfg,

View File

@@ -313,9 +313,26 @@ webui.preview.brand.font = SansSerif
webui.preview.brand.fontpoint = 12 webui.preview.brand.fontpoint = 12
#webui.preview.dc = rights #webui.preview.dc = rights
##### Settings for content count/strength information ####
# whether to display collection and community strengths # whether to display collection and community strengths
#
webui.strengths.show = false webui.strengths.show = false
# if showing the strengths, should they be counted in real time or
# fetched from cache?
#
# Counts fetched in real time will perform an actual count of the
# database contents every time a page with this feature is requested,
# which will not scale. If the below setting is to use the cache, you
# must run the following command periodically to update the count:
#
# [dspace]/bin/dsrun org.dspace.browse.ItemCounter
#
# The default is to count in real time
#
webui.strengths.cache = false
# whether to display the contents of the licence bundle (often just the deposit # whether to display the contents of the licence bundle (often just the deposit
# licence in standard DSpace installation # licence in standard DSpace installation
webui.licence_bundle.show = false webui.licence_bundle.show = false

View File

@@ -736,6 +736,19 @@ FROM ItemsBySubject, Communities2Item
WHERE ItemsBySubject.item_id = Communities2Item.item_id WHERE ItemsBySubject.item_id = Communities2Item.item_id
; ;
-------------------------------------------------------------------------
-- Tables to manage cache of item counts for communities and collections
-------------------------------------------------------------------------
CREATE TABLE collection_item_count (
collection_id INTEGER REFERENCES collection(collection_id),
number INTEGER
);
CREATE TABLE community_item_count (
community_id INTEGER REFERENCES community(community_id),
number INTEGER
);
------------------------------------------------------- -------------------------------------------------------
-- Create 'special' groups, for anonymous access -- Create 'special' groups, for anonymous access

View File

@@ -61,3 +61,17 @@ alter table bundle drop column mets_bitstream_id; -- totally unused column
-- of the last page reached within a step in the Configurable Submission Process -- of the last page reached within a step in the Configurable Submission Process
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
ALTER TABLE workspaceitem ADD page_reached INTEGER; ALTER TABLE workspaceitem ADD page_reached INTEGER;
-------------------------------------------------------------------------
-- Tables to manage cache of item counts for communities and collections
-------------------------------------------------------------------------
CREATE TABLE collection_item_count (
collection_id INTEGER REFERENCES collection(collection_id),
number INTEGER
);
CREATE TABLE community_item_count (
community_id INTEGER REFERENCES community(community_id),
number INTEGER
);