/** * 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.app.xmlui.aspect.xmlworkflow; import org.apache.log4j.Logger; import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer; import org.dspace.app.xmlui.utils.UIException; import org.dspace.app.xmlui.wing.Message; import org.dspace.app.xmlui.wing.WingException; import org.dspace.app.xmlui.wing.element.*; import org.dspace.authorize.AuthorizeException; import org.dspace.content.*; import org.dspace.content.Item; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.WorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.xml.sax.SAXException; import java.io.IOException; import java.sql.SQLException; /** * @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 Submissions extends AbstractDSpaceTransformer { /** General Language Strings */ protected static final Message T_title = message("xmlui.Submission.Submissions.title"); protected static final Message T_dspace_home = message("xmlui.general.dspace_home"); protected static final Message T_trail = message("xmlui.Submission.Submissions.trail"); protected static final Message T_head = message("xmlui.Submission.Submissions.head"); protected static final Message T_untitled = message("xmlui.Submission.Submissions.untitled"); protected static final Message T_email = message("xmlui.Submission.Submissions.email"); // used by the workflow section protected static final Message T_w_head1 = message("xmlui.Submission.Submissions.workflow_head1"); protected static final Message T_w_info1 = message("xmlui.Submission.Submissions.workflow_info1"); protected static final Message T_w_head2 = message("xmlui.Submission.Submissions.workflow_head2"); protected static final Message T_w_column1 = message("xmlui.Submission.Submissions.workflow_column1"); protected static final Message T_w_column2 = message("xmlui.Submission.Submissions.workflow_column2"); protected static final Message T_w_column3 = message("xmlui.Submission.Submissions.workflow_column3"); protected static final Message T_w_column4 = message("xmlui.Submission.Submissions.workflow_column4"); protected static final Message T_w_column5 = message("xmlui.Submission.Submissions.workflow_column5"); protected static final Message T_w_submit_return = message("xmlui.Submission.Submissions.workflow_submit_return"); protected static final Message T_w_info2 = message("xmlui.Submission.Submissions.workflow_info2"); protected static final Message T_w_head3 = message("xmlui.Submission.Submissions.workflow_head3"); protected static final Message T_w_submit_take = message("xmlui.Submission.Submissions.workflow_submit_take"); protected static final Message T_w_info3 = message("xmlui.Submission.Submissions.workflow_info3"); // Used in the in progress section protected static final Message T_p_head1 = message("xmlui.Submission.Submissions.progress_head1"); protected static final Message T_p_info1 = message("xmlui.Submission.Submissions.progress_info1"); protected static final Message T_p_column1 = message("xmlui.Submission.Submissions.progress_column1"); protected static final Message T_p_column2 = message("xmlui.Submission.Submissions.progress_column2"); protected static final Message T_p_column3 = message("xmlui.Submission.Submissions.progress_column3"); private static final Logger log = Logger.getLogger(Submissions.class); public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, SQLException, IOException, AuthorizeException { pageMeta.addMetadata("title").addContent(T_title); pageMeta.addTrailLink(contextPath + "/",T_dspace_home); pageMeta.addTrailLink(contextPath + "/submissions",T_trail); } public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException { Division div = body.addInteractiveDivision("submissions", contextPath+"/submissions", Division.METHOD_POST,"primary"); div.setHead(T_head); this.addWorkflowTasks(div); // this.addUnfinishedSubmissions(div); this.addSubmissionsInWorkflow(div); // this.addPreviousSubmissions(div); } private void addWorkflowTasksDiv(Division division) throws SQLException, WingException, AuthorizeException, IOException { division.addDivision("start-submision"); } /** * If the user has any workflow tasks, either assigned to them or in an * available pool of tasks, then build two tables listing each of these queues. * * If the user dosn't have any workflows then don't do anything. * * @param division The division to add the two queues too. */ private void addWorkflowTasks(Division division) throws SQLException, WingException, AuthorizeException, IOException { @SuppressWarnings("unchecked") // This cast is correct java.util.List<ClaimedTask> ownedItems = ClaimedTask.findByEperson(context, context.getCurrentUser().getID()); @SuppressWarnings("unchecked") // This cast is correct. java.util.List<PoolTask> pooledItems = PoolTask.findByEperson(context, context.getCurrentUser().getID()); if (!(ownedItems.size() > 0 || pooledItems.size() > 0)) // No tasks, so don't show the table. return; Division workflow = division.addDivision("workflow-tasks"); workflow.setHead(T_w_head1); workflow.addPara(T_w_info1); // Tasks you own Table table = workflow.addTable("workflow-tasks",ownedItems.size() + 2,5); table.setHead(T_w_head2); Row header = table.addRow(Row.ROLE_HEADER); header.addCellContent(T_w_column1); header.addCellContent(T_w_column2); header.addCellContent(T_w_column3); header.addCellContent(T_w_column4); header.addCellContent(T_w_column5); //Only show our return to pool button if we have a task that CAN be returned to a pool boolean showReturnToPoolButton = false; if (ownedItems.size() > 0) { for (ClaimedTask owned : ownedItems) { int workflowItemID = owned.getWorkflowItemID(); String stepID = owned.getStepID(); String actionID = owned.getActionID(); XmlWorkflowItem item = null; try { item = XmlWorkflowItem.find(context, workflowItemID); Workflow wf = WorkflowFactory.getWorkflow(item.getCollection()); Step step = wf.getStep(stepID); WorkflowActionConfig action = step.getActionConfig(actionID); String url = contextPath+"/handle/"+item.getCollection().getHandle()+"/xmlworkflow?workflowID="+workflowItemID+"&stepID="+stepID+"&actionID="+actionID; DCValue[] titles = item.getItem().getDC("title", null, Item.ANY); String collectionName = item.getCollection().getMetadata("name"); EPerson submitter = item.getSubmitter(); String submitterName = submitter.getFullName(); String submitterEmail = submitter.getEmail(); // Message state = getWorkflowStateMessage(owned); boolean taskHasPool = step.getUserSelectionMethod().getProcessingAction().usesTaskPool(); if(taskHasPool){ //We have a workflow item that uses a pool, ensure we see the return to pool button showReturnToPoolButton = true; } Row row = table.addRow(); Cell firstCell = row.addCell(); if(taskHasPool){ CheckBox remove = firstCell.addCheckBox("workflowandstepID"); remove.setLabel("selected"); remove.addOption(workflowItemID + ":" + step.getId()); } // The task description row.addCell().addXref(url,message("xmlui.XMLWorkflow." + wf.getID() + "." + stepID + "." + actionID)); // The item description if (titles != null && titles.length > 0) { String displayTitle = titles[0].value; if (displayTitle.length() > 50) displayTitle = displayTitle.substring(0,50)+ " ..."; row.addCell().addXref(url,displayTitle); } else row.addCell().addXref(url,T_untitled); // Submitted too row.addCell().addXref(url,collectionName); // Submitted by Cell cell = row.addCell(); cell.addContent(T_email); cell.addXref("mailto:"+submitterEmail,submitterName); } catch (WorkflowConfigurationException e) { Row row = table.addRow(); row.addCell().addContent("Error: Configuration error in workflow."); log.error(LogManager.getHeader(context, "Error while adding owned tasks on the submissions page", ""), e); } catch (Exception e) { log.error(LogManager.getHeader(context, "Error while adding owned tasks on the submissions page", ""), e); } } if(showReturnToPoolButton){ Row row = table.addRow(); row.addCell(0,5).addButton("submit_return_tasks").setValue(T_w_submit_return); } } else { Row row = table.addRow(); row.addCell(0,5).addHighlight("italic").addContent(T_w_info2); } // Tasks in the pool table = workflow.addTable("workflow-tasks",pooledItems.size()+2,5); table.setHead(T_w_head3); header = table.addRow(Row.ROLE_HEADER); header.addCellContent(T_w_column1); header.addCellContent(T_w_column2); header.addCellContent(T_w_column3); header.addCellContent(T_w_column4); header.addCellContent(T_w_column5); if (pooledItems.size() > 0) { for (PoolTask pooled : pooledItems) { String stepID = pooled.getStepID(); int workflowItemID = pooled.getWorkflowItemID(); String actionID = pooled.getActionID(); XmlWorkflowItem item; try { item = XmlWorkflowItem.find(context, workflowItemID); Workflow wf = WorkflowFactory.getWorkflow(item.getCollection()); String url = contextPath+"/handle/"+item.getCollection().getHandle()+"/xmlworkflow?workflowID="+workflowItemID+"&stepID="+stepID+"&actionID="+actionID; DCValue[] titles = item.getItem().getDC("title", null, Item.ANY); String collectionName = item.getCollection().getMetadata("name"); EPerson submitter = item.getSubmitter(); String submitterName = submitter.getFullName(); String submitterEmail = submitter.getEmail(); // Message state = getWorkflowStateMessage(pooled); Row row = table.addRow(); CheckBox claimTask = row.addCell().addCheckBox("workflowID"); claimTask.setLabel("selected"); claimTask.addOption(workflowItemID); // The task description // row.addCell().addXref(url,message("xmlui.Submission.Submissions.claimAction")); row.addCell().addXref(url,message("xmlui.XMLWorkflow." + wf.getID() + "." + stepID + "." + actionID)); // The item description if (titles != null && titles.length > 0) { String displayTitle = titles[0].value; if (displayTitle.length() > 50) displayTitle = displayTitle.substring(0,50)+ " ..."; row.addCell().addXref(url,displayTitle); } else row.addCell().addXref(url,T_untitled); // Submitted too row.addCell().addXref(url,collectionName); // Submitted by Cell cell = row.addCell(); cell.addContent(T_email); cell.addXref("mailto:"+submitterEmail,submitterName); } catch (WorkflowConfigurationException e) { Row row = table.addRow(); row.addCell().addContent("Error: Configuration error in workflow."); log.error(LogManager.getHeader(context, "Error while adding pooled tasks on the submissions page", ""), e); } catch (Exception e) { log.error(LogManager.getHeader(context, "Error while adding pooled tasks on the submissions page", ""), e); } } Row row = table.addRow(); row.addCell(0,5).addButton("submit_take_tasks").setValue(T_w_submit_take); } else { Row row = table.addRow(); row.addCell(0,4).addHighlight("italic").addContent(T_w_info3); } } /** * There are two options, the user has some unfinished submissions * or the user does not. * * If the user does not, then we just display a simple paragraph * explaining that the user may submit new items to dspace. * * If the user does have unfinisshed submissions then a table is * presented listing all the unfinished submissions that this user has. * */ private void addUnfinishedSubmissions(Division division) throws SQLException, WingException { division.addInteractiveDivision("unfinished-submisions", contextPath+"/submit", Division.METHOD_POST); } /** * This section lists all the submissions that this user has submitted which are currently under review. * * If the user has none, this nothing is displayed. */ private void addSubmissionsInWorkflow(Division division) throws SQLException, WingException, AuthorizeException, IOException { XmlWorkflowItem[] inprogressItems; try { inprogressItems = XmlWorkflowItem.findByEPerson(context,context.getCurrentUser()); // If there is nothing in progress then don't add anything. if (!(inprogressItems.length > 0)) return; Division inprogress = division.addDivision("submissions-inprogress"); inprogress.setHead(T_p_head1); inprogress.addPara(T_p_info1); Table table = inprogress.addTable("submissions-inprogress",inprogressItems.length+1,3); Row header = table.addRow(Row.ROLE_HEADER); header.addCellContent(T_p_column1); header.addCellContent(T_p_column2); header.addCellContent(T_p_column3); for (XmlWorkflowItem workflowItem : inprogressItems) { DCValue[] titles = workflowItem.getItem().getDC("title", null, Item.ANY); String collectionName = workflowItem.getCollection().getMetadata("name"); java.util.List<PoolTask> pooltasks = PoolTask.find(context,workflowItem); java.util.List<ClaimedTask> claimedtasks = ClaimedTask.find(context, workflowItem); Message state = message("xmlui.XMLWorkflow.step.unknown"); for(PoolTask task: pooltasks){ Workflow wf = WorkflowFactory.getWorkflow(workflowItem.getCollection()); Step step = wf.getStep(task.getStepID()); state = message("xmlui.XMLWorkflow." + wf.getID() + "." + step.getId() + "." + task.getActionID()); } for(ClaimedTask task: claimedtasks){ Workflow wf = WorkflowFactory.getWorkflow(workflowItem.getCollection()); Step step = wf.getStep(task.getStepID()); state = message("xmlui.XMLWorkflow." + wf.getID() + "." + step.getId() + "." + task.getActionID()); } Row row = table.addRow(); // Add the title column if (titles.length > 0) { String displayTitle = titles[0].value; if (displayTitle.length() > 50) displayTitle = displayTitle.substring(0,50)+ " ..."; row.addCellContent(displayTitle); } else row.addCellContent(T_untitled); // Collection name column row.addCellContent(collectionName); // Status column row.addCellContent(state); } } catch (Exception e) { Row row = division.addTable("table0",1,1).addRow(); row.addCell().addContent("Error: Configuration error in workflow."); } } /** * Show the user's completed submissions. * * If the user has no completed submissions, display nothing. * If 'displayAll' is true, then display all user's archived submissions. * Otherwise, default to only displaying 50 archived submissions. * * @param division div to put archived submissions in */ private void addPreviousSubmissions(Division division) throws SQLException,WingException { division.addDivision("completed-submissions"); } }