mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 15:03:18 +00:00
[DS-2058] First cut at adding curation to Configurable Workflow
This commit is contained in:

committed by
Mark H. Wood

parent
5cb853d92b
commit
a5dc6d1c34
@@ -0,0 +1,298 @@
|
||||
/**
|
||||
* 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.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.curate.service.XmlWorkflowCuratorService;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.workflow.CurationTaskConfig;
|
||||
import org.dspace.xmlworkflow.RoleMembers;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.service.XmlWorkflowService;
|
||||
import org.dspace.xmlworkflow.state.Step;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Manage interactions between curation and workflow. A curation task can be
|
||||
* attached to a workflow step, to be executed during the step.
|
||||
*
|
||||
* @see CurationTaskConfig
|
||||
* @author mwood
|
||||
*/
|
||||
@Service
|
||||
public class XmlWorkflowCuratorServiceImpl
|
||||
implements XmlWorkflowCuratorService
|
||||
{
|
||||
private static final Logger LOG
|
||||
= LoggerFactory.getLogger(XmlWorkflowCuratorServiceImpl.class);
|
||||
|
||||
@Autowired(required = true)
|
||||
protected XmlWorkflowFactory workflowFactory;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected XmlWorkflowServiceFactory workflowServiceFactory;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected ConfigurationService configurationService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected GroupService groupService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected EPersonService ePersonService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected CollectionService collectionService;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected ClaimedTaskService claimedTaskService;
|
||||
|
||||
protected XmlWorkflowService workflowService;
|
||||
protected XmlWorkflowItemService workflowItemService;
|
||||
|
||||
/**
|
||||
* Initialize the bean (after dependency injection has already taken place).
|
||||
* Called by "init-method" in Spring configuration.
|
||||
*
|
||||
* @throws Exception passed through.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init()
|
||||
throws Exception
|
||||
{
|
||||
workflowService = workflowServiceFactory.getXmlWorkflowService();
|
||||
workflowItemService = workflowServiceFactory.getXmlWorkflowItemService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsCuration(XmlWorkflowItem wfi)
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported yet."); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doCuration(Context c, XmlWorkflowItem wfi)
|
||||
throws AuthorizeException, IOException, SQLException
|
||||
{
|
||||
Curator curator = new Curator();
|
||||
return curate(curator, c, wfi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean curate(Curator curator, Context c, String wfId)
|
||||
throws AuthorizeException, IOException, SQLException
|
||||
{
|
||||
XmlWorkflowItem wfi = workflowItemService.find(c, Integer.parseInt(wfId));
|
||||
if (wfi != null) {
|
||||
return curate(curator, c, wfi);
|
||||
} else {
|
||||
LOG.warn(LogManager.getHeader(c, "No workflow item found for id: {}", null), wfId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean curate(Curator curator, Context c, XmlWorkflowItem wfi)
|
||||
throws AuthorizeException, IOException, SQLException
|
||||
{
|
||||
CurationTaskConfig.FlowStep step = getFlowStep(c, wfi);
|
||||
if (step != null) {
|
||||
// assign collection to item in case task needs it
|
||||
Item item = wfi.getItem();
|
||||
item.setOwningCollection(wfi.getCollection());
|
||||
for (CurationTaskConfig.Task task : step.tasks) {
|
||||
curator.addTask(task.name);
|
||||
curator.curate(item);
|
||||
int status = curator.getStatus(task.name);
|
||||
String result = curator.getResult(task.name);
|
||||
String action = "none";
|
||||
switch (status)
|
||||
{
|
||||
case Curator.CURATE_FAIL:
|
||||
// task failed - notify any contacts the task has assigned
|
||||
if (task.powers.contains("reject"))
|
||||
{
|
||||
action = "reject";
|
||||
}
|
||||
notifyContacts(c, wfi, task, "fail", action, result);
|
||||
// if task so empowered, reject submission and terminate
|
||||
if ("reject".equals(action))
|
||||
{
|
||||
workflowService.sendWorkflowItemBackSubmission(c, wfi,
|
||||
c.getCurrentUser(), null,
|
||||
task.name + ": " + result);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Curator.CURATE_SUCCESS:
|
||||
if (task.powers.contains("approve"))
|
||||
{
|
||||
action = "approve";
|
||||
}
|
||||
notifyContacts(c, wfi, task, "success", action, result);
|
||||
if ("approve".equals(action))
|
||||
{
|
||||
// cease further task processing and advance submission
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case Curator.CURATE_ERROR:
|
||||
notifyContacts(c, wfi, task, "error", action, result);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
curator.clear();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the flow step occupied by a work flow item.
|
||||
* @param c session context.
|
||||
* @param wfi the work flow item in question.
|
||||
* @return the current flow step for the item, or null.
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
*/
|
||||
protected CurationTaskConfig.FlowStep getFlowStep(Context c, XmlWorkflowItem wfi)
|
||||
throws SQLException, IOException
|
||||
{
|
||||
Collection coll = wfi.getCollection();
|
||||
String key = CurationTaskConfig.containsKey(coll.getHandle()) ? coll.getHandle() : "default";
|
||||
|
||||
ClaimedTask claimedTask
|
||||
= claimedTaskService.findByWorkflowIdAndEPerson(c, wfi, c.getCurrentUser());
|
||||
CurationTaskConfig.TaskSet ts = CurationTaskConfig.findTaskSet(key);
|
||||
if (ts != null)
|
||||
{
|
||||
for (CurationTaskConfig.FlowStep fstep : ts.steps)
|
||||
{
|
||||
if (fstep.step.equals(claimedTask.getStepID()))
|
||||
{
|
||||
return fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to people who should be notified when curation tasks are run.
|
||||
*
|
||||
* @param c session context.
|
||||
* @param wfi the work flow item being curated.
|
||||
* @param task the curation task being applied.
|
||||
* @param status status returned by the task.
|
||||
* @param action action to be taken as a result of task status.
|
||||
* @param message anything the code wants to say about the task run.
|
||||
* @throws AuthorizeException passed through.
|
||||
* @throws IOException passed through.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
protected void notifyContacts(Context c, XmlWorkflowItem wfi,
|
||||
CurationTaskConfig.Task task,
|
||||
String status, String action, String message)
|
||||
throws AuthorizeException, IOException, SQLException
|
||||
{
|
||||
List<EPerson> epa = resolveContacts(c, task.getContacts(status), wfi);
|
||||
if (epa.size() > 0) {
|
||||
workflowService.notifyOfCuration(c, wfi, epa, task.name, action, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Develop a list of EPerson from a list of perhaps symbolic "contact" names.
|
||||
*
|
||||
* @param c session context.
|
||||
* @param contacts the list of concrete and symbolic groups to resolve.
|
||||
* @param wfi the work flow item associated with these groups via its current work flow step.
|
||||
* @return the EPersons associated with the current state of {@code wfi}
|
||||
* @throws AuthorizeException passed through.
|
||||
* @throws IOException passed through.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
protected List<EPerson> resolveContacts(Context c, List<String> contacts,
|
||||
XmlWorkflowItem wfi)
|
||||
throws AuthorizeException, IOException, SQLException
|
||||
{
|
||||
List<EPerson> epList = new ArrayList<>();
|
||||
for (String contact : contacts) {
|
||||
// decode contacts
|
||||
if ("$flowgroup".equals(contact)) {
|
||||
// special literal for current flowgoup
|
||||
ClaimedTask claimedTask = claimedTaskService.findByWorkflowIdAndEPerson(c, wfi, c.getCurrentUser());
|
||||
String stepID = claimedTask.getStepID();
|
||||
Step step;
|
||||
try {
|
||||
Workflow workflow = workflowFactory.getWorkflow(wfi.getCollection());
|
||||
step = workflow.getStep(stepID);
|
||||
} catch (WorkflowConfigurationException e) {
|
||||
LOG.error("Failed to locate current workflow step for workflow item "
|
||||
+ String.valueOf(wfi.getID()), e);
|
||||
return epList;
|
||||
}
|
||||
RoleMembers roleMembers = step.getRole().getMembers(c, wfi);
|
||||
for (EPerson ep : roleMembers.getEPersons())
|
||||
epList.add(ep);
|
||||
for (Group group : roleMembers.getGroups())
|
||||
epList.addAll(group.getMembers());
|
||||
} else if ("$colladmin".equals(contact)) {
|
||||
Group adGroup = wfi.getCollection().getAdministrators();
|
||||
if (adGroup != null) {
|
||||
epList.addAll(groupService.allMembers(c, adGroup));
|
||||
}
|
||||
} else if ("$siteadmin".equals(contact)) {
|
||||
EPerson siteEp = ePersonService.findByEmail(c,
|
||||
configurationService.getProperty("mail.admin"));
|
||||
if (siteEp != null) {
|
||||
epList.add(siteEp);
|
||||
}
|
||||
} else if (contact.indexOf("@") > 0) {
|
||||
// little shaky heuristic here - assume an eperson email name
|
||||
EPerson ep = ePersonService.findByEmail(c, contact);
|
||||
if (ep != null) {
|
||||
epList.add(ep);
|
||||
}
|
||||
} else {
|
||||
// assume it is an arbitrary group name
|
||||
Group group = groupService.findByName(c, contact);
|
||||
if (group != null) {
|
||||
epList.addAll(groupService.allMembers(c, group));
|
||||
}
|
||||
}
|
||||
}
|
||||
return epList;
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 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.service;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.curate.Curator;
|
||||
import org.dspace.workflowbasic.BasicWorkflowItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import org.dspace.workflow.WorkflowItem;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
|
||||
/**
|
||||
* Manage interactions between curation and workflow.
|
||||
* Specifically, it is invoked in XmlWorkflowService to allow the
|
||||
* performance of curation tasks during workflow.
|
||||
*
|
||||
* Copied from {@link WorkflowCurator} with minor refactoring.
|
||||
*
|
||||
* @author mwood
|
||||
*/
|
||||
public interface XmlWorkflowCuratorService
|
||||
{
|
||||
/**
|
||||
* Does this workflow item need curation now?
|
||||
*
|
||||
* @param wfi the item in question.
|
||||
* @return true if the item is in a state needing curation.
|
||||
*/
|
||||
public boolean needsCuration(XmlWorkflowItem wfi);
|
||||
|
||||
/**
|
||||
* Determines and executes curation on a Workflow item.
|
||||
*
|
||||
* @param c the context
|
||||
* @param wfi the workflow item
|
||||
* @return true if curation was completed or not required,
|
||||
* false if tasks were queued for later completion,
|
||||
* or item was rejected
|
||||
* @throws AuthorizeException if authorization error
|
||||
* @throws IOException if IO error
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public boolean doCuration(Context c, XmlWorkflowItem wfi)
|
||||
throws AuthorizeException, IOException, SQLException;
|
||||
|
||||
/**
|
||||
* Determines and executes curation of a Workflow item by ID.
|
||||
*
|
||||
* @param curator the curation context
|
||||
* @param c the user context
|
||||
* @param wfId the workflow item's ID
|
||||
* @return true if TODO
|
||||
* @throws AuthorizeException if authorization error
|
||||
* @throws IOException if IO error
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public boolean curate(Curator curator, Context c, String wfId)
|
||||
throws AuthorizeException, IOException, SQLException;
|
||||
|
||||
/**
|
||||
* Determines and executes curation of a Workflow item.
|
||||
*
|
||||
* @param curator the curation context
|
||||
* @param c the user context
|
||||
* @param wfi the workflow item
|
||||
* @return true if TODO
|
||||
* @throws AuthorizeException if authorization error
|
||||
* @throws IOException if IO error
|
||||
* @throws SQLException if database error
|
||||
*/
|
||||
public boolean curate(Curator curator, Context c, XmlWorkflowItem wfi)
|
||||
throws AuthorizeException, IOException, SQLException;
|
||||
}
|
@@ -0,0 +1,232 @@
|
||||
|
||||
package org.dspace.workflow;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
|
||||
import static javax.xml.stream.XMLStreamConstants.CHARACTERS;
|
||||
import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
|
||||
import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
|
||||
|
||||
/**
|
||||
* Represent the mapping between collection workflows and curation tasks.
|
||||
* This mapping is defined in {@code [DSpace]/config/workflow-curation.xml}.
|
||||
*
|
||||
* <p>Copied from {@link WorkflowCuratorServiceImpl}.
|
||||
*
|
||||
* @author mwood
|
||||
*/
|
||||
public class CurationTaskConfig
|
||||
{
|
||||
private static final Map<String, TaskSet> tsMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Look up a TaskSet by name.
|
||||
*
|
||||
* @param setName name of the sought TaskSet: collection handle or "default".
|
||||
* @return the named TaskSet, or the default TaskSet if not found, or
|
||||
* {@code null} if there is no default either.
|
||||
* @throws IOException passed through.
|
||||
*/
|
||||
static public TaskSet findTaskSet(String setName)
|
||||
throws IOException
|
||||
{
|
||||
if (tsMap.isEmpty())
|
||||
{
|
||||
ConfigurationService configurationService
|
||||
= DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
File cfgFile = new File(configurationService.getProperty("dspace.dir") +
|
||||
File.separator + "config" + File.separator +
|
||||
"workflow-curation.xml");
|
||||
loadTaskConfig(cfgFile);
|
||||
}
|
||||
|
||||
if (tsMap.containsKey(setName))
|
||||
return tsMap.get(setName);
|
||||
else
|
||||
return tsMap.get("default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this task set name defined?
|
||||
*
|
||||
* @param name name of the task set sought.
|
||||
* @return true if a set by that name is known.
|
||||
*/
|
||||
public static boolean containsKey(String name)
|
||||
{
|
||||
return tsMap.containsKey(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
static protected void loadTaskConfig(File cfgFile) throws IOException
|
||||
{
|
||||
final Map<String, String> collMap = new HashMap<>();
|
||||
final Map<String, TaskSet> setMap = new HashMap<>();
|
||||
TaskSet taskSet = null;
|
||||
FlowStep flowStep = null;
|
||||
Task task = null;
|
||||
String type = null;
|
||||
try {
|
||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||
XMLStreamReader reader = factory.createXMLStreamReader(
|
||||
new FileInputStream(cfgFile), "UTF-8");
|
||||
while (reader.hasNext())
|
||||
{
|
||||
switch (reader.next())
|
||||
{
|
||||
case START_ELEMENT:
|
||||
{
|
||||
String eName = reader.getLocalName();
|
||||
if (null != eName) switch (eName)
|
||||
{
|
||||
case "mapping":
|
||||
collMap.put(reader.getAttributeValue(0),
|
||||
reader.getAttributeValue(1));
|
||||
break;
|
||||
case "taskset":
|
||||
taskSet = new TaskSet(reader.getAttributeValue(0));
|
||||
break;
|
||||
case "flowstep":
|
||||
int count = reader.getAttributeCount();
|
||||
String queue = (count == 2) ?
|
||||
reader.getAttributeValue(1) : null;
|
||||
flowStep = new FlowStep(reader.getAttributeValue(0), queue);
|
||||
break;
|
||||
case "task":
|
||||
task = new Task(reader.getAttributeValue(0));
|
||||
break;
|
||||
case "workflow":
|
||||
type = "power";
|
||||
break;
|
||||
case "notify":
|
||||
type = reader.getAttributeValue(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHARACTERS:
|
||||
if (task != null) {
|
||||
if ("power".equals(type)) {
|
||||
task.addPower(reader.getText());
|
||||
} else {
|
||||
task.addContact(type, reader.getText());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case END_ELEMENT:
|
||||
{
|
||||
String eName = reader.getLocalName();
|
||||
if (null != eName) switch (eName)
|
||||
{
|
||||
case "task":
|
||||
flowStep.addTask(task);
|
||||
task = null;
|
||||
break;
|
||||
case "flowstep":
|
||||
taskSet.addStep(flowStep);
|
||||
break;
|
||||
case "taskset":
|
||||
setMap.put(taskSet.setName, taskSet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
|
||||
// stitch maps together
|
||||
for (Map.Entry<String, String> collEntry : collMap.entrySet())
|
||||
{
|
||||
if (! "none".equals(collEntry.getValue()) && setMap.containsKey(collEntry.getValue()))
|
||||
{
|
||||
tsMap.put(collEntry.getKey(), setMap.get(collEntry.getValue()));
|
||||
}
|
||||
}
|
||||
} catch (XMLStreamException xsE) {
|
||||
throw new IOException(xsE.getMessage(), xsE);
|
||||
}
|
||||
}
|
||||
|
||||
static public class TaskSet
|
||||
{
|
||||
public String setName = null;
|
||||
public List<FlowStep> steps = null;
|
||||
|
||||
public TaskSet(String setName)
|
||||
{
|
||||
this.setName = setName;
|
||||
steps = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addStep(FlowStep step)
|
||||
{
|
||||
steps.add(step);
|
||||
}
|
||||
}
|
||||
|
||||
static public class FlowStep
|
||||
{
|
||||
public String step = null;
|
||||
public String queue = null;
|
||||
public List<Task> tasks = null;
|
||||
|
||||
public FlowStep(String stepStr, String queueStr)
|
||||
{
|
||||
this.step = stepStr;
|
||||
this.queue = queueStr;
|
||||
tasks = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addTask(Task task)
|
||||
{
|
||||
tasks.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
static public class Task
|
||||
{
|
||||
public String name = null;
|
||||
public List<String> powers = new ArrayList<>();
|
||||
public Map<String, List<String>> contacts = new HashMap<>();
|
||||
|
||||
public Task(String name) { this.name = name; }
|
||||
|
||||
public void addPower(String power) {
|
||||
powers.add(power);
|
||||
}
|
||||
|
||||
public void addContact(String status, String contact)
|
||||
{
|
||||
List<String> sContacts = contacts.get(status);
|
||||
if (sContacts == null)
|
||||
{
|
||||
sContacts = new ArrayList<>();
|
||||
contacts.put(status, sContacts);
|
||||
}
|
||||
sContacts.add(contact);
|
||||
}
|
||||
|
||||
public List<String> getContacts(String status)
|
||||
{
|
||||
List<String> ret = contacts.get(status);
|
||||
return (ret != null) ? ret : new ArrayList<String>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -22,6 +22,7 @@ import javax.mail.MessagingException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
@@ -45,6 +46,7 @@ import org.dspace.core.Context;
|
||||
import org.dspace.core.Email;
|
||||
import org.dspace.core.I18nUtil;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.curate.service.XmlWorkflowCuratorService;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
@@ -124,6 +126,8 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService {
|
||||
protected BitstreamService bitstreamService;
|
||||
@Autowired(required = true)
|
||||
protected ConfigurationService configurationService;
|
||||
@Autowired(required = true)
|
||||
protected XmlWorkflowCuratorService xmlWorkflowCuratorService;
|
||||
|
||||
protected XmlWorkflowServiceImpl() {
|
||||
|
||||
@@ -318,9 +322,12 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService {
|
||||
* Executes an action and returns the next.
|
||||
*/
|
||||
@Override
|
||||
public WorkflowActionConfig doState(Context c, EPerson user, HttpServletRequest request, int workflowItemId,
|
||||
Workflow workflow, WorkflowActionConfig currentActionConfig)
|
||||
throws SQLException, AuthorizeException, IOException, WorkflowException {
|
||||
public WorkflowActionConfig doState(Context c, EPerson user,
|
||||
HttpServletRequest request, int workflowItemId, Workflow workflow,
|
||||
WorkflowActionConfig currentActionConfig)
|
||||
throws SQLException, AuthorizeException, IOException,
|
||||
MessagingException, WorkflowException
|
||||
{
|
||||
try {
|
||||
XmlWorkflowItem wi = xmlWorkflowItemService.find(c, workflowItemId);
|
||||
Step currentStep = currentActionConfig.getStep();
|
||||
@@ -333,6 +340,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService {
|
||||
}
|
||||
c.addEvent(new Event(Event.MODIFY, Constants.ITEM, wi.getItem().getID(), null,
|
||||
itemService.getIdentifiers(c, wi.getItem())));
|
||||
xmlWorkflowCuratorService.doCuration(c, wi);
|
||||
return processOutcome(c, user, workflow, currentStep, currentActionConfig, outcome, wi, false);
|
||||
} else {
|
||||
throw new AuthorizeException("You are not allowed to to perform this task.");
|
||||
@@ -631,6 +639,68 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService {
|
||||
}
|
||||
}
|
||||
|
||||
// send notices of curation activity
|
||||
@Override
|
||||
public void notifyOfCuration(Context c, XmlWorkflowItem wi,
|
||||
List<EPerson> ePeople, String taskName, String action, String message)
|
||||
throws SQLException, IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the item title
|
||||
String title = getItemTitle(wi);
|
||||
|
||||
// Get the submitter's name
|
||||
String submitter = getSubmitterName(wi);
|
||||
|
||||
// Get the collection
|
||||
Collection coll = wi.getCollection();
|
||||
|
||||
for (EPerson epa : ePeople)
|
||||
{
|
||||
Locale supportedLocale = I18nUtil.getEPersonLocale(epa);
|
||||
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "flowtask_notify"));
|
||||
email.addArgument(title);
|
||||
email.addArgument(coll.getName());
|
||||
email.addArgument(submitter);
|
||||
email.addArgument(taskName);
|
||||
email.addArgument(message);
|
||||
email.addArgument(action);
|
||||
email.addRecipient(epa.getEmail());
|
||||
email.send();
|
||||
}
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
log.warn(LogManager.getHeader(c, "notifyOfCuration",
|
||||
"cannot email users of workflow_item_id " + wi.getID()
|
||||
+ ": " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
protected String getItemTitle(XmlWorkflowItem wi) throws SQLException
|
||||
{
|
||||
Item myitem = wi.getItem();
|
||||
String title = myitem.getName();
|
||||
|
||||
// only return the first element, or "Untitled"
|
||||
if (StringUtils.isNotBlank(title))
|
||||
{
|
||||
return title;
|
||||
}
|
||||
else
|
||||
{
|
||||
return I18nUtil.getMessage("org.dspace.workflow.WorkflowManager.untitled ");
|
||||
}
|
||||
}
|
||||
|
||||
protected String getSubmitterName(XmlWorkflowItem wi) throws SQLException
|
||||
{
|
||||
EPerson e = wi.getSubmitter();
|
||||
|
||||
return getEPersonName(e);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* WORKFLOW TASK MANAGEMENT
|
||||
**********************************/
|
||||
|
@@ -32,7 +32,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
* When an item is submitted and is somewhere in a workflow, it has a row in the
|
||||
* WorkflowItem table pointing to it.
|
||||
*
|
||||
* Once the item has completed the workflow it will be archived
|
||||
* Once the item has completed the workflow it will be archived.
|
||||
*
|
||||
* @author Bram De Schouwer (bram.deschouwer at dot com)
|
||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||
@@ -47,7 +47,23 @@ public interface XmlWorkflowService extends WorkflowService<XmlWorkflowItem> {
|
||||
public WorkflowActionConfig doState(Context c, EPerson user, HttpServletRequest request, int workflowItemId,
|
||||
Workflow workflow, WorkflowActionConfig currentActionConfig)
|
||||
throws SQLException, AuthorizeException, IOException, MessagingException, WorkflowException;
|
||||
|
||||
/**
|
||||
* Execute the actions associated with a state, and return the next state.
|
||||
*
|
||||
* @param c session context.
|
||||
* @param user current user.
|
||||
* @param workflow item is in this workflow.
|
||||
* @param currentStep workflow step being executed.
|
||||
* @param currentActionConfig describes the current step's action.
|
||||
* @param currentOutcome the result of executing the current step (accept/reject/etc).
|
||||
* @param wfi the Item being processed through workflow.
|
||||
* @param enteredNewStep is the Item advancing to a new workflow step?
|
||||
* @return the next step's action.
|
||||
* @throws SQLException passed through.
|
||||
* @throws AuthorizeException passed through.
|
||||
* @throws IOException passed through.
|
||||
* @throws WorkflowException if the current step's outcome is unrecognized.
|
||||
*/
|
||||
public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep,
|
||||
WorkflowActionConfig currentActionConfig, ActionResult currentOutcome,
|
||||
XmlWorkflowItem wfi, boolean enteredNewStep)
|
||||
@@ -75,5 +91,21 @@ public interface XmlWorkflowService extends WorkflowService<XmlWorkflowItem> {
|
||||
|
||||
public void removeUserItemPolicies(Context context, Item item, EPerson e) throws SQLException, AuthorizeException;
|
||||
|
||||
/**
|
||||
* Send email to interested parties when curation tasks run.
|
||||
*
|
||||
* @param c session context.
|
||||
* @param wi the item being curated.
|
||||
* @param ePeople the interested parties.
|
||||
* @param taskName the task that has been run.
|
||||
* @param action the action indicated by the task (reject, approve, etc.)
|
||||
* @param message anything the code wants to say about the task.
|
||||
* @throws SQLException passed through.
|
||||
* @throws IOException passed through.
|
||||
*/
|
||||
public void notifyOfCuration(Context c, XmlWorkflowItem wi,
|
||||
List<EPerson> ePeople, String taskName, String action, String message)
|
||||
throws SQLException, IOException;
|
||||
|
||||
public String getEPersonName(EPerson ePerson);
|
||||
}
|
||||
|
Reference in New Issue
Block a user