diff --git a/dspace-api/src/main/java/org/dspace/browse/ItemCounter.java b/dspace-api/src/main/java/org/dspace/browse/ItemCounter.java index b6e5e6c77e..bd7e4a8f2b 100644 --- a/dspace-api/src/main/java/org/dspace/browse/ItemCounter.java +++ b/dspace-api/src/main/java/org/dspace/browse/ItemCounter.java @@ -15,10 +15,11 @@ import org.dspace.content.service.CommunityService; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.content.DSpaceObject; -import org.dspace.core.ConfigurationManager; import java.sql.SQLException; import java.util.List; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; /** * This class provides a standard interface to all item counting @@ -37,189 +38,191 @@ import java.util.List; */ 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; + /** 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; protected CommunityService communityService; protected ItemService itemService; + protected ConfigurationService configurationService; - /** - * 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, SQLException - { + /** + * 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, SQLException + { Context context = new Context(); ItemCounter ic = new ItemCounter(context); - ic.buildItemCounts(); + ic.buildItemCounts(); context.complete(); - } + } - /** - * 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); + /** + * 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); this.communityService = ContentServiceFactory.getInstance().getCommunityService(); this.itemService = ContentServiceFactory.getInstance().getItemService(); - } + this.configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + } - /** - * 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 - { - List tlc = communityService.findAllTop(context); + /** + * 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 + { + List tlc = communityService.findAllTop(context); for (Community aTlc : tlc) { count(aTlc); } - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new ItemCountException(e); - } - } + } + 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 - * @throws ItemCountException - * @throws SQLException - */ - public int getCount(DSpaceObject dso) - throws ItemCountException - { - boolean useCache = ConfigurationManager.getBooleanProperty( - "webui.strengths.cache", true); - - if (useCache) - { - return dao.getCount(dso); - } - - // if we make it this far, we need to manually count - if (dso instanceof Collection) - { - try { - return itemService.countItems(context, (Collection) dso); - } catch (SQLException e) { - log.error("caught exception: ", e); - throw new ItemCountException(e); - } - } - - if (dso instanceof Community) - { - try { - return communityService.countItems(context, ((Community) dso)); - } catch (SQLException e) { - log.error("caught exception: ", e); - throw new ItemCountException(e); - } - } - - return 0; - } + /** + * 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 + * @throws ItemCountException + * @throws SQLException + */ + public int getCount(DSpaceObject dso) + throws ItemCountException + { + boolean useCache = configurationService.getBooleanProperty( + "webui.strengths.cache", true); + + if (useCache) + { + return dao.getCount(dso); + } + + // if we make it this far, we need to manually count + if (dso instanceof Collection) + { + try { + return itemService.countItems(context, (Collection) dso); + } catch (SQLException e) { + log.error("caught exception: ", e); + throw new ItemCountException(e); + } + } + + if (dso instanceof Community) + { + try { + return itemService.countItems(context, ((Community) dso)); + } catch (SQLException e) { + log.error("caught exception: ", e); + throw new ItemCountException(e); + } + } + + return 0; + } - /** - * Remove any cached data for the given container - * - * @param dso - * @throws ItemCountException - */ - public void remove(DSpaceObject dso) - throws ItemCountException - { - dao.remove(dso); - } + /** + * 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 - */ + /** + * 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 + */ protected void count(Community community) - throws ItemCountException - { - try - { - // first count the community we are in - int count = communityService.countItems(context, community); - dao.communityCount(community, count); - - // now get the sub-communities - List scs = community.getSubcommunities(); + throws ItemCountException + { + try + { + // first count the community we are in + int count = itemService.countItems(context, community); + dao.communityCount(community, count); + + // now get the sub-communities + List scs = community.getSubcommunities(); for (Community sc : scs) { count(sc); } - - // now get the collections - List cols = community.getCollections(); + + // now get the collections + List cols = community.getCollections(); for (Collection col : cols) { count(col); } - } - 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 - */ - protected void count(Collection collection) - throws ItemCountException - { - try - { - int ccount = itemService.countItems(context, collection); - dao.collectionCount(collection, ccount); - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new ItemCountException(e); - } - } + } + 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 + */ + protected void count(Collection collection) + throws ItemCountException + { + try + { + int ccount = itemService.countItems(context, collection); + dao.collectionCount(collection, ccount); + } + catch (SQLException e) + { + log.error("caught exception: ", e); + throw new ItemCountException(e); + } + } } diff --git a/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java index 877d9032e2..9775ba9d92 100644 --- a/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CommunityServiceImpl.java @@ -576,22 +576,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl imp authorizeService.authorizeAction(context, community, Constants.WRITE); } - @Override - public int countItems(Context context, Community community) throws SQLException { - int total = 0; - // add collection counts - List cols = community.getCollections(); - for (Collection col : cols) { - total += itemService.countItems(context, col); - } - // add sub-community counts - List comms = community.getSubcommunities(); - for (int j = 0; j < comms.size(); j++) { - total += countItems(context, comms.get(j)); - } - return total; - } - @Override public Community findByAdminGroup(Context context, Group group) throws SQLException { return communityDAO.findByAdminGroup(context, group); diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 9e821cf0e7..30b43f68e0 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -1121,12 +1121,11 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It @Override public int countItems(Context context, Community community) throws SQLException { + // First we need a list of all collections under this community in the hierarchy List collections = communityService.getAllCollections(context, community); - int itemCount = 0; - for(Collection collection : collections) { - itemCount += countItems(context, collection); - } - return itemCount; + + // Now, lets count unique items across that list of collections + return itemDAO.countItems(context, collections, true, false); } @Override @@ -1166,12 +1165,14 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It } @Override - public int getNotArchivedItemsCount(Context context) throws SQLException { - return itemDAO.countNotArchived(context); + public int countNotArchivedItems(Context context) throws SQLException { + // return count of items not in archive and also not withdrawn + return itemDAO.countItems(context, false, false); } @Override public int countWithdrawnItems(Context context) throws SQLException { - return itemDAO.countWithdrawn(context); + // return count of items that are in archive and withdrawn + return itemDAO.countItems(context, true, true); } } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/ItemDAO.java b/dspace-api/src/main/java/org/dspace/content/dao/ItemDAO.java index fae6b7b2fc..1a21b4c645 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/ItemDAO.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/ItemDAO.java @@ -56,7 +56,31 @@ public interface ItemDAO extends DSpaceObjectLegacySupportDAO public Iterator findAllByCollection(Context context, Collection collection) throws SQLException; + /** + * Count number of items in a given collection + * @param context + * @param collection the collection + * @param includeArchived whether to include archived items in count + * @param includeWithdrawn whether to include withdrawn items in count + * @return item count + * @throws SQLException + */ public int countItems(Context context, Collection collection, boolean includeArchived, boolean includeWithdrawn) throws SQLException; + + /** + * Count number of unique items across several collections at once. + * This method can be used with + * {@link org.dspace.content.service.CommunityService#getAllCollections(Context,Community)} + * to determine the unique number of items in a Community. + * + * @param context + * @param collections the list of collections + * @param includeArchived whether to include archived items in count + * @param includeWithdrawn whether to include withdrawn items in count + * @return item count + * @throws SQLException + */ + public int countItems(Context context, List collections, boolean includeArchived, boolean includeWithdrawn) throws SQLException; /** * Get all Items installed or withdrawn, discoverable, and modified since a Date. @@ -71,9 +95,22 @@ public interface ItemDAO extends DSpaceObjectLegacySupportDAO boolean withdrawn, boolean discoverable, Date lastModified) throws SQLException; + /** + * Count total number of items (rows in item table) + * @param context + * @return total count + * @throws SQLException + */ int countRows(Context context) throws SQLException; - int countNotArchived(Context context) throws SQLException; - - int countWithdrawn(Context context) throws SQLException; + /** + * Count number of items based on specific status flags + * @param context + * @param includeArchived whether to include archived items in count + * @param includeWithdrawn whether to include withdrawn items in count + * @return count of items + * @throws SQLException + */ + int countItems(Context context, boolean includeArchived, boolean includeWithdrawn) throws SQLException; + } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java index 698b484e4c..4f8b21487e 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java @@ -11,7 +11,6 @@ import org.apache.log4j.Logger; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.MetadataField; -import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataValue; import org.dspace.content.dao.ItemDAO; import org.dspace.core.Context; @@ -25,10 +24,8 @@ import org.hibernate.criterion.Property; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Subqueries; import org.hibernate.type.StandardBasicTypes; -import org.hibernate.type.Type; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Iterator; @@ -244,6 +241,18 @@ public class ItemDAOImpl extends AbstractHibernateDSODAO implements ItemDA return count(query); } + + @Override + public int countItems(Context context, List collections, boolean includeArchived, boolean includeWithdrawn) throws SQLException { + Query query = createQuery(context, "select count(distinct i) from Item i " + + "join i.collections collection " + + "WHERE collection IN (:collections) AND i.inArchive=:in_archive AND i.withdrawn=:withdrawn"); + query.setParameterList("collections", collections); + query.setParameter("in_archive", includeArchived); + query.setParameter("withdrawn", includeWithdrawn); + + return count(query); + } @Override public Iterator findByLastModifiedSince(Context context, Date since) @@ -260,12 +269,10 @@ public class ItemDAOImpl extends AbstractHibernateDSODAO implements ItemDA } @Override - public int countNotArchived(Context context) throws SQLException { - return count(createQuery(context, "SELECT count(*) FROM Item i WHERE i.inArchive=false AND i.withdrawn=false")); - } - - @Override - public int countWithdrawn(Context context) throws SQLException { - return count(createQuery(context, "SELECT count(*) FROM Item i WHERE i.withdrawn=true")); + public int countItems(Context context, boolean includeArchived, boolean includeWithdrawn) throws SQLException { + Query query = createQuery(context, "SELECT count(*) FROM Item i WHERE i.inArchive=:in_archive AND i.withdrawn=:withdrawn"); + query.setParameter("in_archive", includeArchived); + query.setParameter("withdrawn", includeWithdrawn); + return count(query); } } diff --git a/dspace-api/src/main/java/org/dspace/content/service/CommunityService.java b/dspace-api/src/main/java/org/dspace/content/service/CommunityService.java index 39b5f5bd3f..3c56062714 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/CommunityService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/CommunityService.java @@ -243,13 +243,6 @@ public interface CommunityService extends DSpaceObjectService, DSpace public void canEdit(Context context, Community community) throws AuthorizeException, SQLException; - /** - * counts items in this community - * - * @return total items - */ - public int countItems(Context context, Community community) throws SQLException; - public Community findByAdminGroup(Context context, Group group) throws SQLException; public List findAuthorized(Context context, List actions) throws SQLException; diff --git a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java index f3083a2f17..aad6852f44 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java @@ -453,7 +453,7 @@ public interface ItemService extends DSpaceObjectService, DSpaceObjectLega public Iterator findByLastModifiedSince(Context context, Date last) throws SQLException; -/** + /** * counts items in the given community * * @return total items @@ -462,7 +462,7 @@ public interface ItemService extends DSpaceObjectService, DSpaceObjectLega int countTotal(Context context) throws SQLException; - int getNotArchivedItemsCount(Context context) throws SQLException; + int countNotArchivedItems(Context context) throws SQLException; int countWithdrawnItems(Context context) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java index 12d6fd9c9f..a0aae9392e 100644 --- a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java +++ b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java @@ -74,7 +74,7 @@ public class ItemCheck extends Check { "Withdrawn items: %d\n", itemService.countWithdrawnItems(context)); ret += String.format( "Not published items (in workspace or workflow mode): %d\n", - itemService.getNotArchivedItemsCount(context)); + itemService.countNotArchivedItems(context)); for (Map.Entry row : workspaceItemService.getStageReachedCounts(context)) { ret += String.format("\tIn Stage %s: %s\n", diff --git a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java index 850c3e3338..52c36e1d22 100644 --- a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java @@ -1961,6 +1961,8 @@ public class CollectionTest extends AbstractDSpaceObjectTest { //0 by default assertTrue("testCountItems 0", itemService.countItems(context, collection) == 0); + + //NOTE: a more thorough test of item counting is in ITCommunityCollection integration test } /** diff --git a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java index b93d06229e..48d7745412 100644 --- a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java @@ -1480,7 +1480,9 @@ public class CommunityTest extends AbstractDSpaceObjectTest public void testCountItems() throws Exception { //0 by default - assertTrue("testCountItems 0", communityService.countItems(context, c) == 0); + assertTrue("testCountItems 0", itemService.countItems(context, c) == 0); + + //NOTE: a more thorough test of item counting is in ITCommunityCollection integration test } /** diff --git a/dspace-api/src/test/java/org/dspace/content/ITCommunityCollection.java b/dspace-api/src/test/java/org/dspace/content/ITCommunityCollection.java index 9dd15e6672..418fc2e781 100644 --- a/dspace-api/src/test/java/org/dspace/content/ITCommunityCollection.java +++ b/dspace-api/src/test/java/org/dspace/content/ITCommunityCollection.java @@ -96,38 +96,75 @@ public class ITCommunityCollection extends AbstractIntegrationTest assertThat("testCreateTree 2", (Community) collectionService.getParentObject(context, col1), equalTo(child1)); assertThat("testCreateTree 3", (Community) collectionService.getParentObject(context, col2), equalTo(child1)); } - - /** - * Tests that count items works as expected - */ + + /** + * Tests the creation of items in a community/collection tree + */ @Test - @PerfTest(invocations = 50, threads = 1) - @Required(percentile95 = 2000, average= 1800) - public void testCountItems() throws SQLException, AuthorizeException, IOException { - //make it an even number, not too high to reduce time during testing - int totalitems = 4; - + @PerfTest(invocations = 25, threads = 1) + @Required(percentile95 = 1200, average = 700, throughput = 1) + public void testCreateItems() throws SQLException, AuthorizeException + { //we create the structure context.turnOffAuthorisationSystem(); Community parent = communityService.create(null, context); Community child1 = communityService.create(parent, context); - + Collection col1 = collectionService.create(context, child1); Collection col2 = collectionService.create(context, child1); - - for(int count = 0; count < totalitems/2; count++) - { - - Item item1 = installItemService.installItem(context, workspaceItemService.create(context, col1, false)); - Item item2 = installItemService.installItem(context, workspaceItemService.create(context, col2, false)); - } + + Item item1 = installItemService.installItem(context, workspaceItemService.create(context, col1, false)); + Item item2 = installItemService.installItem(context, workspaceItemService.create(context, col2, false)); context.restoreAuthSystemState(); //verify it works as expected - assertThat("testCountItems 0", itemService.countItems(context, col1), equalTo(totalitems/2)); - assertThat("testCountItems 1", itemService.countItems(context, col2), equalTo(totalitems/2)); - assertThat("testCountItems 2", communityService.countItems(context, child1), equalTo(totalitems)); - assertThat("testCountItems 3", communityService.countItems(context, parent), equalTo(totalitems)); + assertThat("testCreateItems 0", (Collection) itemService.getParentObject(context, item1), equalTo(col1)); + assertThat("testCreateItems 1", (Collection) itemService.getParentObject(context, item2), equalTo(col2)); + } + + /** + * Tests that count items works as expected + * NOTE: Counts are currently expensive (take a while) + */ + @Test + @PerfTest(invocations = 10, threads = 1) + @Required(percentile95 = 2000, average= 1800) + public void testCountItems() throws SQLException, AuthorizeException, IOException { + int items_per_collection = 2; + + //we create the structure + context.turnOffAuthorisationSystem(); + Community parentCom = communityService.create(null, context); + Community childCom = communityService.create(parentCom, context); + + Collection col1 = collectionService.create(context, childCom); + Collection col2 = collectionService.create(context, childCom); + + // Add same number of items to each collection + for(int count = 0; count < items_per_collection; count++) + { + Item item1 = installItemService.installItem(context, workspaceItemService.create(context, col1, false)); + Item item2 = installItemService.installItem(context, workspaceItemService.create(context, col2, false)); + } + + // Finally, let's throw in a small wrench and add a mapped item + // Add it to collection 1 + Item item3 = installItemService.installItem(context, workspaceItemService.create(context, col1, false)); + // Map it into collection 2 + collectionService.addItem(context, col2, item3); + + // Our total number of items should be + int totalitems = items_per_collection*2 + 1; + // Our collection counts should be + int collTotalItems = items_per_collection + 1; + + context.restoreAuthSystemState(); + + //verify it works as expected + assertThat("testCountItems 0", itemService.countItems(context, col1), equalTo(collTotalItems)); + assertThat("testCountItems 1", itemService.countItems(context, col2), equalTo(collTotalItems)); + assertThat("testCountItems 2", itemService.countItems(context, childCom), equalTo(totalitems)); + assertThat("testCountItems 3", itemService.countItems(context, parentCom), equalTo(totalitems)); } } diff --git a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/discovery/CommunityRecentSubmissions.java b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/discovery/CommunityRecentSubmissions.java index 6ac3253b73..5c940dd9ea 100644 --- a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/discovery/CommunityRecentSubmissions.java +++ b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/discovery/CommunityRecentSubmissions.java @@ -21,7 +21,7 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.Community; import org.dspace.content.DSpaceObject; import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.content.service.CommunityService; +import org.dspace.content.service.ItemService; import org.xml.sax.SAXException; /** @@ -36,7 +36,7 @@ public class CommunityRecentSubmissions extends AbstractRecentSubmissionTransfor private static final Message T_head_recent_submissions = message("xmlui.ArtifactBrowser.CommunityViewer.head_recent_submissions"); - protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); + protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); /** * Displays the recent submissions for this community @@ -80,7 +80,7 @@ public class CommunityRecentSubmissions extends AbstractRecentSubmissionTransfor Community community = (Community) dso; - if (communityService.countItems(context, community) > maxRecentSubmissions) + if (itemService.countItems(context, community) > maxRecentSubmissions) addViewMoreLink(lastSubmittedDiv, dso); } }