/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.curate; import java.io.IOException; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CommunityService; import org.dspace.content.service.ItemService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; /** * AbstractCurationTask encapsulates a few common patterns of task use, * resources, and convenience methods. * * @author richardrodgers */ public abstract class AbstractCurationTask implements CurationTask { // invoking curator protected Curator curator = null; // curator-assigned taskId protected String taskId = null; // logger private static Logger log = Logger.getLogger(AbstractCurationTask.class); protected CommunityService communityService; protected ItemService itemService; protected HandleService handleService; protected ConfigurationService configurationService; @Override public void init(Curator curator, String taskId) throws IOException { this.curator = curator; this.taskId = taskId; communityService = ContentServiceFactory.getInstance().getCommunityService(); itemService = ContentServiceFactory.getInstance().getItemService(); handleService = HandleServiceFactory.getInstance().getHandleService(); configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); } @Override public abstract int perform(DSpaceObject dso) throws IOException; /** * Distributes a task through a DSpace container - a convenience method * for tasks declaring the @Distributive property. *

* This method invokes the 'performObject()' method on the current DSO, and * then recursively invokes the 'performObject()' method on all DSOs contained * within the current DSO. For example: if a Community is passed in, then * 'performObject()' will be called on that Community object, as well as * on all SubCommunities/Collections/Items contained in that Community. *

* Individual tasks MUST override either the performObject method or * the performItem method to ensure the task is run on either all * DSOs or just all Items, respectively. * * @param dso current DSpaceObject * @throws IOException if IO error */ protected void distribute(DSpaceObject dso) throws IOException { try { //perform task on this current object performObject(dso); //next, we'll try to distribute to all child objects, based on container type int type = dso.getType(); if (Constants.COLLECTION == type) { Iterator iter = itemService.findByCollection(Curator.curationContext(), (Collection) dso); while (iter.hasNext()) { Item item = iter.next(); performObject(item); Curator.curationContext().uncacheEntity(item); } } else if (Constants.COMMUNITY == type) { Community comm = (Community) dso; for (Community subcomm : comm.getSubcommunities()) { distribute(subcomm); } for (Collection coll : comm.getCollections()) { distribute(coll); } } else if (Constants.SITE == type) { List topComm = communityService.findAllTop(Curator.curationContext()); for (Community comm : topComm) { distribute(comm); } } } catch (SQLException sqlE) { throw new IOException(sqlE.getMessage(), sqlE); } } /** * Performs task upon a single DSpaceObject. Used in conjunction with the * distribute method to run a single task across multiple DSpaceObjects. *

* By default, this method just wraps a call to performItem * for each Item Object. *

* You should override this method if you want to use * distribute to run your task across multiple DSpace Objects. *

* Either this method or performItem should be overridden if * distribute method is used. * * @param dso the DSpaceObject * @throws SQLException if database error * @throws IOException if IO error */ protected void performObject(DSpaceObject dso) throws SQLException, IOException { // By default this method only performs tasks on Items // (You should override this method if you want to perform task on all objects) if (dso.getType() == Constants.ITEM) { performItem((Item) dso); } //no-op for all other types of DSpace Objects } /** * Performs task upon a single DSpace Item. Used in conjunction with the * distribute method to run a single task across multiple Items. *

* You should override this method if you want to use * distribute to run your task across multiple DSpace Items. *

* Either this method or performObject should be overridden if * distribute method is used. * * @param item the DSpace Item * @throws SQLException if database error * @throws IOException if IO error */ protected void performItem(Item item) throws SQLException, IOException { // no-op - override when using 'distribute' method } @Override public int perform(Context ctx, String id) throws IOException { DSpaceObject dso = dereference(ctx, id); return (dso != null) ? perform(dso) : Curator.CURATE_FAIL; } /** * Returns a DSpaceObject for passed identifier, if it exists * * @param ctx DSpace context * @param id canonical id of object * @return dso * DSpace object, or null if no object with id exists * @throws IOException if IO error */ protected DSpaceObject dereference(Context ctx, String id) throws IOException { try { return handleService.resolveToObject(ctx, id); } catch (SQLException sqlE) { throw new IOException(sqlE.getMessage(), sqlE); } } /** * Sends message to the reporting stream * * @param message the message to stream */ protected void report(String message) { curator.report(message); } /** * Assigns the result of the task performance * * @param result the result string */ protected void setResult(String result) { curator.setResult(taskId, result); } /** * Returns task configuration property value for passed name, else * null if no properties defined or no value for passed key. * * @param name the property name * @return value * the property value, or null */ protected String taskProperty(String name) { // If a taskID/Name is specified, prepend it on the configuration name if (StringUtils.isNotBlank(taskId)) { return configurationService.getProperty(taskId + "." + name); } else { return configurationService.getProperty(name); } } /** * Returns task configuration integer property value for passed name, else * passed default value if no properties defined or no value for passed key. * * @param name the property name * @param defaultValue value * the default value * @return value * the property value, or default value */ protected int taskIntProperty(String name, int defaultValue) { // If a taskID/Name is specified, prepend it on the configuration name if (StringUtils.isNotBlank(taskId)) { return configurationService.getIntProperty(taskId + "." + name, defaultValue); } else { return configurationService.getIntProperty(name, defaultValue); } } /** * Returns task configuration long property value for passed name, else * passed default value if no properties defined or no value for passed key. * * @param name the property name * @param defaultValue value * the default value * @return value * the property value, or default */ protected long taskLongProperty(String name, long defaultValue) { // If a taskID/Name is specified, prepend it on the configuration name if (StringUtils.isNotBlank(taskId)) { return configurationService.getLongProperty(taskId + "." + name, defaultValue); } else { return configurationService.getLongProperty(name, defaultValue); } } /** * Returns task configuration boolean property value for passed name, else * passed default value if no properties defined or no value for passed key. * * @param name the property name * @param defaultValue value * the default value * @return value * the property value, or default */ protected boolean taskBooleanProperty(String name, boolean defaultValue) { // If a taskID/Name is specified, prepend it on the configuration name if (StringUtils.isNotBlank(taskId)) { return configurationService.getBooleanProperty(taskId + "." + name, defaultValue); } else { return configurationService.getBooleanProperty(name, defaultValue); } } /** * Returns task configuration Array property value for passed name, else * null if no properties defined or no value for passed key. * * @param name the property name * @return value * the property value, or null */ protected String[] taskArrayProperty(String name) { // If a taskID/Name is specified, prepend it on the configuration name if (StringUtils.isNotBlank(taskId)) { return configurationService.getArrayProperty(taskId + "." + name); } else { return configurationService.getArrayProperty(name); } } }