/** * 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.xmlworkflow.storedcomponents; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.InProgressSubmission; import org.dspace.core.ConfigurationManager; import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.storage.rdbms.TableRow; import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.authorize.AuthorizeException; import org.dspace.eperson.EPerson; import org.apache.log4j.Logger; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.XmlWorkflowManager; import java.util.List; import java.util.ArrayList; import java.sql.SQLException; import java.io.IOException; /** * Class representing an item going through the workflow process in DSpace * * @author Bram De Schouwer (bram.deschouwer at dot com) * @author Kevin Van de Velde (kevin at atmire dot com) * @author Ben Bosman (ben at atmire dot com) * @author Mark Diggory (markd at atmire dot com) */ public class XmlWorkflowItem implements InProgressSubmission { /* * The current step in the workflow system in which this workflow item is present */ private static Logger log = Logger.getLogger(XmlWorkflowItem.class); private Collection collection; private Item item; private TableRow wfRow; private Context ourContext; public static XmlWorkflowItem create(Context context) throws AuthorizeException, IOException, SQLException { TableRow row = DatabaseManager.create(context, "cwf_workflowitem"); return new XmlWorkflowItem(context, row); } /* * In the case where multiple epersons can claim and perform an action, this map will represent the progress * of each of these epersons in the step */ // private ArrayList<StepRecord> activeSteps; XmlWorkflowItem(Context context, TableRow row) throws SQLException, AuthorizeException, IOException { ourContext = context; wfRow = row; // activeSteps = new ArrayList<StepRecord>(); item = Item.find(context, wfRow.getIntColumn("item_id")); collection = Collection.find(context, wfRow.getIntColumn("collection_id")); // Cache ourselves context.cache(this, row.getIntColumn("workflowitem_id")); // initialize(); // update(); } /** * Get a workflow item from the database. The item, collection and submitter * are loaded into memory. * * @param context * DSpace context object * @param id * ID of the workspace item * * @return the workflow item, or null if the ID is invalid. */ public static XmlWorkflowItem find(Context context, int id) throws SQLException, AuthorizeException, IOException { // First check the cache XmlWorkflowItem fromCache = (XmlWorkflowItem) context.fromCache( XmlWorkflowItem.class, id); if (fromCache != null) { return fromCache; } TableRow row = DatabaseManager.find(context, "cwf_workflowitem", id); // TableRow row = DatabaseManager.querySingle(context, "SELECT * FROM workflowitem WHERE item_id= "+id); if (row == null) { if (log.isDebugEnabled()) { log.debug(LogManager.getHeader(context, "find_workflow_item", "not_found,workflowitem_id=" + id)); } return null; } else { if (log.isDebugEnabled()) { log.debug(LogManager.getHeader(context, "find_workflow_item", "workflowitem_id=" + id)); } return new XmlWorkflowItem(context, row); } } /** * return all workflowitems * * @param c active context * @return WorkflowItem [] of all workflows in system */ public static XmlWorkflowItem[] findAll(Context c) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { List wfItems = new ArrayList(); TableRowIterator tri = DatabaseManager.queryTable(c, "cwf_workflowitem", "SELECT * FROM cwf_workflowitem"); try { // make a list of workflow items while (tri.hasNext()) { TableRow row = tri.next(); XmlWorkflowItem wi = new XmlWorkflowItem(c, row); wfItems.add(wi); } } finally { if (tri != null) tri.close(); } XmlWorkflowItem[] wfArray = new XmlWorkflowItem[wfItems.size()]; wfArray = (XmlWorkflowItem[]) wfItems.toArray(wfArray); return wfArray; } /** * return all workflowitems for a certain page * * @param c active context * @return WorkflowItem [] of all workflows in system */ public static XmlWorkflowItem[] findAll(Context c, int page, int pagesize) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { return findAllInCollection(c, page, pagesize, -1); } /** * return all workflowitems for a certain page with a certain collection * * @param c active context * @return WorkflowItem [] of all workflows in system */ public static XmlWorkflowItem[] findAllInCollection(Context c, int page, int pagesize, int collectionId) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { List wfItems = new ArrayList(); StringBuffer query = new StringBuffer(); query.append("SELECT * FROM cwf_workflowitem "); if(collectionId != -1){ query.append("WHERE collection_id=").append(collectionId); } int offset = (page - 1) * pagesize; if ("oracle".equals(ConfigurationManager.getProperty("db.name"))) { // First prepare the query to generate row numbers if (pagesize > 0 || offset > 0) { query.insert(0, "SELECT /*+ FIRST_ROWS(n) */ rec.*, ROWNUM rnum FROM ("); query.append(") "); } // Restrict the number of rows returned based on the limit if (pagesize > 0) { query.append("rec WHERE rownum<=? "); // If we also have an offset, then convert the limit into the maximum row number if (offset > 0) { pagesize += offset; } } // Return only the records after the specified offset (row number) if (offset > 0) { query.insert(0, "SELECT * FROM ("); query.append(") WHERE rnum>?"); } } else { if (pagesize > 0) { query.append(" LIMIT ? "); } if (offset > 0) { query.append(" OFFSET ? "); } } String queryString = query.toString(); Object[] paramArr = new Object[]{}; if (pagesize > 0 && offset > 0) { paramArr = new Object[]{pagesize, offset}; } else if (pagesize > 0) { paramArr = new Object[]{pagesize}; } else if (offset > 0) { paramArr = new Object[]{offset}; } // Get all the epeople that match the query TableRowIterator tri = DatabaseManager.query(c, queryString, paramArr); try { // make a list of workflow items while (tri.hasNext()) { TableRow row = tri.next(); XmlWorkflowItem wi = new XmlWorkflowItem(c, row); wfItems.add(wi); } } finally { if (tri != null) tri.close(); } XmlWorkflowItem[] wfArray = new XmlWorkflowItem[wfItems.size()]; wfArray = (XmlWorkflowItem[]) wfItems.toArray(wfArray); return wfArray; } /** * return all workflowitems * * @param c active context * @return WorkflowItem [] of all workflows in system */ public static int countAll(Context c) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { return countAllInCollection(c, -1); } /** * return all workflowitems * * @param c active context * @return WorkflowItem [] of all workflows in system */ public static int countAllInCollection(Context c, int collId) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { StringBuffer query = new StringBuffer(); query.append("SELECT count(*) AS count FROM cwf_workflowitem "); if(collId != -1){ query.append(" WHERE collection_id= ").append(collId); } TableRow tr = DatabaseManager.querySingle(c,query.toString()); return new Long(tr.getLongColumn("count")).intValue(); } /* * Returns all workflow items submitted by an eperson */ public static XmlWorkflowItem[] findByEPerson(Context context, EPerson ep) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { List wfItems = new ArrayList(); TableRowIterator tri = DatabaseManager.queryTable(context, "cwf_workflowitem", "SELECT cwf_workflowitem.* FROM cwf_workflowitem, item WHERE " + "cwf_workflowitem.item_id=item.item_id AND " + "item.submitter_id= ? " + "ORDER BY cwf_workflowitem.workflowitem_id", ep.getID()); while (tri.hasNext()) { TableRow row = tri.next(); // Check the cache XmlWorkflowItem wi = (XmlWorkflowItem) context.fromCache( XmlWorkflowItem.class, row.getIntColumn("workflowitem_id")); if (wi == null) { wi = new XmlWorkflowItem(context, row); } wfItems.add(wi); } tri.close(); XmlWorkflowItem[] wfArray = new XmlWorkflowItem[wfItems.size()]; wfArray = (XmlWorkflowItem[]) wfItems.toArray(wfArray); return wfArray; } /** * Get all workflow items for a particular collection. * * @param context * the context object * @param c * the collection * * @return array of the corresponding workflow items */ public static XmlWorkflowItem[] findByCollection(Context context, Collection c) throws SQLException, AuthorizeException, IOException { List wsItems = new ArrayList(); TableRowIterator tri = DatabaseManager.queryTable(context, "cwf_workflowitem", "SELECT cwf_workflowitem.* FROM cwf_workflowitem WHERE " + "cwf_workflowitem.collection_id= ? ", c.getID()); try { while (tri.hasNext()) { TableRow row = tri.next(); // Check the cache XmlWorkflowItem wi = (XmlWorkflowItem) context.fromCache( XmlWorkflowItem.class, row.getIntColumn("workflowitem_id")); // not in cache? turn row into workflowitem if (wi == null) { wi = new XmlWorkflowItem(context, row); } wsItems.add(wi); } } finally { if (tri != null) tri.close(); } XmlWorkflowItem[] wsArray = new XmlWorkflowItem[wsItems.size()]; wsArray = (XmlWorkflowItem[]) wsItems.toArray(wsArray); return wsArray; } /** * Update the workflow item, including the unarchived item. */ public void update() throws SQLException, IOException, AuthorizeException { // FIXME check auth log.info(LogManager.getHeader(ourContext, "update_workflow_item", "workflowitem_id=" + getID())); // Update the item item.update(); // Update ourselves DatabaseManager.update(ourContext, wfRow); } /** * Get the internal ID of this workflow item * * @return the internal identifier */ public int getID() { return wfRow.getIntColumn("workflowitem_id"); } public Collection getCollection(){ return this.collection; } public void setCollection(Collection collection){ this.collection = collection; wfRow.setColumn("collection_id", collection.getID()); } public Item getItem() { return item; } public void setItem(Item item){ this.item = item; wfRow.setColumn("item_id", item.getID()); } public EPerson getSubmitter() throws SQLException { return item.getSubmitter(); } public boolean hasMultipleFiles() { return wfRow.getBooleanColumn("multiple_files"); } public void setMultipleFiles(boolean b) { wfRow.setColumn("multiple_files", b); } public boolean hasMultipleTitles() { return wfRow.getBooleanColumn("multiple_titles"); } public void setMultipleTitles(boolean b) { wfRow.setColumn("multiple_titles", b); } public boolean isPublishedBefore() { return wfRow.getBooleanColumn("published_before"); } public void setPublishedBefore(boolean b) { wfRow.setColumn("published_before", b); } /** * delete the WorkflowItem, retaining the Item */ public void deleteWrapper() throws SQLException, IOException, AuthorizeException { // Remove from cache ourContext.removeCached(this, getID()); WorkflowItemRole[] roles = WorkflowItemRole.findAllForItem(ourContext, this.getID()); for(WorkflowItemRole role: roles){ role.delete(); } XmlWorkflowManager.deleteAllTasks(ourContext, this); // FIXME - auth? DatabaseManager.delete(ourContext, wfRow); } }