001: /*
002: * ItemCounter.java
003: *
004: * Copyright (c) 2002-2007, Hewlett-Packard Company and Massachusetts
005: * Institute of Technology. All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions are
009: * met:
010: *
011: * - Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in the
016: * documentation and/or other materials provided with the distribution.
017: *
018: * - Neither the name of the Hewlett-Packard Company nor the name of the
019: * Massachusetts Institute of Technology nor the names of their
020: * contributors may be used to endorse or promote products derived from
021: * this software without specific prior written permission.
022: *
023: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
028: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
029: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
030: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
031: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
032: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
033: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
034: * DAMAGE.
035: */
036: package org.dspace.browse;
037:
038: import org.apache.log4j.Logger;
039: import org.dspace.content.Community;
040: import org.dspace.content.Collection;
041: import org.dspace.core.Context;
042: import org.dspace.content.DSpaceObject;
043: import org.dspace.core.ConfigurationManager;
044:
045: import java.sql.SQLException;
046:
047: /**
048: * This class provides a standard interface to all item counting
049: * operations for communities and collections. It can be run from the
050: * command line to prepare the cached data if desired, simply by
051: * running:
052: *
053: * java org.dspace.browse.ItemCounter
054: *
055: * It can also be invoked via its standard API. In the event that
056: * the data cache is not being used, this class will return direct
057: * real time counts of content.
058: *
059: * @author Richard Jones
060: *
061: */
062: public class ItemCounter {
063: /** Log4j logger */
064: private static Logger log = Logger.getLogger(ItemCounter.class);
065:
066: /** DAO to use to store and retrieve data */
067: private ItemCountDAO dao;
068:
069: /** DSpace Context */
070: private Context context;
071:
072: /**
073: * method invoked by CLI which will result in the number of items
074: * in each community and collection being cached. These counts will
075: * not update themselves until this is run again.
076: *
077: * @param args
078: */
079: public static void main(String[] args) throws ItemCountException,
080: SQLException {
081: Context context = new Context();
082: ItemCounter ic = new ItemCounter(context);
083: ic.buildItemCounts();
084: context.complete();
085: }
086:
087: /**
088: * Construct a new item counter which will use the give DSpace Context
089: *
090: * @param context
091: * @throws ItemCountException
092: */
093: public ItemCounter(Context context) throws ItemCountException
094:
095: {
096: this .context = context;
097: this .dao = ItemCountDAOFactory.getInstance(this .context);
098: }
099:
100: /**
101: * This method does the grunt work of drilling through and iterating
102: * over all of the communities and collections in the system and
103: * obtaining and caching the item counts for each one.
104: *
105: * @throws ItemCountException
106: */
107: public void buildItemCounts() throws ItemCountException {
108: try {
109: Community[] tlc = Community.findAllTop(context);
110: for (int i = 0; i < tlc.length; i++) {
111: count(tlc[i]);
112: }
113: } catch (SQLException e) {
114: log.error("caught exception: ", e);
115: throw new ItemCountException(e);
116: }
117: }
118:
119: /**
120: * Get the count of the items in the given container. If the configuration
121: * value webui.strengths.cache is equal to 'true' this will return the
122: * cached value if it exists. If it is equal to 'false' it will count
123: * the number of items in the container in real time
124: *
125: * @param dso
126: * @return
127: * @throws ItemCountException
128: * @throws SQLException
129: */
130: public int getCount(DSpaceObject dso) throws ItemCountException {
131: boolean useCache = ConfigurationManager
132: .getBooleanProperty("webui.strengths.cache");
133:
134: if (useCache) {
135: return dao.getCount(dso);
136: }
137:
138: // if we make it this far, we need to manually count
139: if (dso instanceof Collection) {
140: try {
141: return ((Collection) dso).countItems();
142: } catch (SQLException e) {
143: log.error("caught exception: ", e);
144: throw new ItemCountException(e);
145: }
146: }
147:
148: if (dso instanceof Community) {
149: try {
150: return ((Community) dso).countItems();
151: } catch (SQLException e) {
152: log.error("caught exception: ", e);
153: throw new ItemCountException(e);
154: }
155: }
156:
157: return 0;
158: }
159:
160: /**
161: * Remove any cached data for the given container
162: *
163: * @param dso
164: * @throws ItemCountException
165: */
166: public void remove(DSpaceObject dso) throws ItemCountException {
167: dao.remove(dso);
168: }
169:
170: /**
171: * count and cache the number of items in the community. This
172: * will include all sub-communities and collections in the
173: * community. It will also recurse into sub-communities and
174: * collections and call count() on them also.
175: *
176: * Therefore, the count the contents of the entire system, it is
177: * necessary just to call this method on each top level community
178: *
179: * @param community
180: * @throws ItemCountException
181: */
182: private void count(Community community) throws ItemCountException {
183: try {
184: // first count the community we are in
185: int count = community.countItems();
186: dao.communityCount(community, count);
187:
188: // now get the sub-communities
189: Community[] scs = community.getSubcommunities();
190: for (int i = 0; i < scs.length; i++) {
191: count(scs[i]);
192: }
193:
194: // now get the collections
195: Collection[] cols = community.getCollections();
196: for (int i = 0; i < cols.length; i++) {
197: count(cols[i]);
198: }
199: } catch (SQLException e) {
200: log.error("caught exception: ", e);
201: throw new ItemCountException(e);
202: }
203: }
204:
205: /**
206: * count and cache the number of items in the given collection
207: *
208: * @param collection
209: * @throws ItemCountException
210: */
211: private void count(Collection collection) throws ItemCountException {
212: try {
213: int ccount = collection.countItems();
214: dao.collectionCount(collection, ccount);
215: } catch (SQLException e) {
216: log.error("caught exception: ", e);
217: throw new ItemCountException(e);
218: }
219: }
220: }
|