mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-14 13:33:08 +00:00
Merge pull request #2420 from KevinVdV/DS-4239-migrate-workflow-xml-to-spring
[DS-4239] Migrate the workflow.xml to spring Merging since there are 2 approvals and it's a dependency for https://github.com/DSpace/DSpace/pull/2646
This commit is contained in:
@@ -48,6 +48,7 @@ import org.dspace.harvest.HarvestedCollection;
|
||||
import org.dspace.harvest.service.HarvestedCollectionService;
|
||||
import org.dspace.workflow.factory.WorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.XmlWorkflowFactoryImpl;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.storedcomponents.CollectionRole;
|
||||
@@ -370,11 +371,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
||||
Workflow workflow = null;
|
||||
try {
|
||||
workflow = workflowFactory.getWorkflow(collection);
|
||||
} catch (IOException | WorkflowConfigurationException e) {
|
||||
} catch (WorkflowConfigurationException e) {
|
||||
log.error(LogManager.getHeader(context, "setWorkflowGroup",
|
||||
"collection_id=" + collection.getID() + " " + e.getMessage()), e);
|
||||
}
|
||||
if (!StringUtils.equals(XmlWorkflowFactory.LEGACY_WORKFLOW_NAME, workflow.getID())) {
|
||||
if (!StringUtils.equals(XmlWorkflowFactoryImpl.LEGACY_WORKFLOW_NAME, workflow.getID())) {
|
||||
throw new IllegalArgumentException(
|
||||
"setWorkflowGroup can be used only on collection with the default basic dspace workflow. "
|
||||
+ "Instead, the collection: "
|
||||
|
@@ -13,14 +13,15 @@ import java.util.List;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.GroupService;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.storedcomponents.CollectionRole;
|
||||
import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* The role that is responsible for a certain step
|
||||
@@ -32,38 +33,36 @@ import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService;
|
||||
* @author Ben Bosman (ben at atmire dot com)
|
||||
* @author Mark Diggory (markd at atmire dot com)
|
||||
*/
|
||||
public class Role {
|
||||
public class Role implements BeanNameAware {
|
||||
|
||||
@Autowired
|
||||
private GroupService groupService;
|
||||
@Autowired
|
||||
private CollectionRoleService collectionRoleService;
|
||||
@Autowired
|
||||
private WorkflowItemRoleService workflowItemRoleService;
|
||||
|
||||
private GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
|
||||
private CollectionRoleService collectionRoleService = XmlWorkflowServiceFactory.getInstance()
|
||||
.getCollectionRoleService();
|
||||
private WorkflowItemRoleService workflowItemRoleService = XmlWorkflowServiceFactory.getInstance()
|
||||
.getWorkflowItemRoleService();
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private boolean isInternal;
|
||||
private Scope scope;
|
||||
private boolean isInternal = false;
|
||||
private Scope scope = Scope.COLLECTION;
|
||||
|
||||
public static enum Scope {
|
||||
@Override
|
||||
public void setBeanName(String s) {
|
||||
this.id = s;
|
||||
}
|
||||
|
||||
public enum Scope {
|
||||
REPOSITORY,
|
||||
COLLECTION,
|
||||
ITEM
|
||||
}
|
||||
|
||||
public Role(String id, String name, String description, boolean isInternal, Scope scope) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.isInternal = isInternal;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -118,4 +117,41 @@ public class Role {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The name specified in the name attribute of a role will be used to lookup the in DSpace.
|
||||
* The lookup will depend on the scope specified in the "scope" attribute:
|
||||
* @param name
|
||||
*/
|
||||
@Required
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the description of the role
|
||||
* @param description the description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scope attribute, depending on the scope the users will be retrieved in the following manner:
|
||||
* * collection: The collection value specifies that the group will be configured at the level of the collection.
|
||||
* * repository: The repository scope uses groups that are defined at repository level in DSpace.
|
||||
* item: The item scope assumes that a different action in the workflow will assign a number of EPersons or
|
||||
* Groups to a specific workflow-item in order to perform a step.
|
||||
* @param scope the scope parameter
|
||||
*/
|
||||
public void setScope(Scope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional attribute which isn't really used at the moment, false by default
|
||||
* @param internal if the role is internal
|
||||
*/
|
||||
public void setInternal(boolean internal) {
|
||||
isInternal = internal;
|
||||
}
|
||||
}
|
||||
|
@@ -13,8 +13,8 @@ import java.io.StringWriter;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -236,13 +236,13 @@ public class WorkflowUtils extends Util {
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, Role> getCollectionRoles(Collection thisCollection)
|
||||
public static Map<String, Role> getCollectionRoles(Collection thisCollection)
|
||||
throws IOException, WorkflowConfigurationException, SQLException {
|
||||
Workflow workflow = xmlWorkflowFactory.getWorkflow(thisCollection);
|
||||
LinkedHashMap<String, Role> result = new LinkedHashMap<String, Role>();
|
||||
if (workflow != null) {
|
||||
//Make sure we find one
|
||||
HashMap<String, Role> allRoles = workflow.getRoles();
|
||||
Map<String, Role> allRoles = workflow.getRoles();
|
||||
//We have retrieved all our roles, not get the ones which can be configured by the collection
|
||||
for (String roleId : allRoles.keySet()) {
|
||||
Role role = allRoles.get(roleId);
|
||||
@@ -257,13 +257,13 @@ public class WorkflowUtils extends Util {
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, Role> getCollectionAndRepositoryRoles(Collection thisCollection)
|
||||
public static Map<String, Role> getCollectionAndRepositoryRoles(Collection thisCollection)
|
||||
throws IOException, WorkflowConfigurationException, SQLException {
|
||||
Workflow workflow = xmlWorkflowFactory.getWorkflow(thisCollection);
|
||||
LinkedHashMap<String, Role> result = new LinkedHashMap<String, Role>();
|
||||
if (workflow != null) {
|
||||
//Make sure we find one
|
||||
HashMap<String, Role> allRoles = workflow.getRoles();
|
||||
Map<String, Role> allRoles = workflow.getRoles();
|
||||
//We have retrieved all our roles, not get the ones which can be configured by the collection
|
||||
for (String roleId : allRoles.keySet()) {
|
||||
Role role = allRoles.get(roleId);
|
||||
@@ -279,13 +279,13 @@ public class WorkflowUtils extends Util {
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, Role> getAllExternalRoles(Collection thisCollection)
|
||||
public static Map<String, Role> getAllExternalRoles(Collection thisCollection)
|
||||
throws IOException, WorkflowConfigurationException, SQLException {
|
||||
Workflow workflow = xmlWorkflowFactory.getWorkflow(thisCollection);
|
||||
LinkedHashMap<String, Role> result = new LinkedHashMap<String, Role>();
|
||||
if (workflow != null) {
|
||||
//Make sure we find one
|
||||
HashMap<String, Role> allRoles = workflow.getRoles();
|
||||
Map<String, Role> allRoles = workflow.getRoles();
|
||||
//We have retrieved all our roles, not get the ones which can be configured by the collection
|
||||
for (String roleId : allRoles.keySet()) {
|
||||
Role role = allRoles.get(roleId);
|
||||
|
@@ -7,31 +7,12 @@
|
||||
*/
|
||||
package org.dspace.xmlworkflow;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.xpath.XPathAPI;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.state.Step;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig;
|
||||
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* The workflowfactory is responsible for parsing the
|
||||
@@ -45,239 +26,28 @@ import org.w3c.dom.NodeList;
|
||||
*/
|
||||
public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
|
||||
|
||||
private Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowFactoryImpl.class);
|
||||
public static final String LEGACY_WORKFLOW_NAME = "defaultWorkflow";
|
||||
|
||||
@Autowired(required = true)
|
||||
protected ConfigurationService configurationService;
|
||||
protected HashMap<String, Workflow> workflowCache;
|
||||
protected String path;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
path = configurationService
|
||||
.getProperty("dspace.dir") + File.separator + "config" + File.separator + "workflow.xml";
|
||||
}
|
||||
// private static String pathActions = ConfigurationManager.getProperty("dspace.dir")+"/config/workflow-actions.xml";
|
||||
|
||||
protected XmlWorkflowFactoryImpl() {
|
||||
|
||||
}
|
||||
private Map<String, Workflow> workflowMapping;
|
||||
|
||||
@Override
|
||||
public Workflow getWorkflow(Collection collection) throws IOException, WorkflowConfigurationException {
|
||||
//Initialize our cache if we have none
|
||||
if (workflowCache == null) {
|
||||
workflowCache = new HashMap<>();
|
||||
}
|
||||
|
||||
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException {
|
||||
// Attempt to retrieve our workflow object
|
||||
if (workflowCache.get(collection.getHandle()) == null) {
|
||||
try {
|
||||
// No workflow cache found for the collection, check if we have a workflowId for this collection
|
||||
File xmlFile = new File(path);
|
||||
Document input = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);
|
||||
Node mainNode = input.getFirstChild();
|
||||
Node workflowMap = XPathAPI.selectSingleNode(mainNode,
|
||||
"//workflow-map/name-map[@collection='" + collection
|
||||
.getHandle() + "']");
|
||||
if (workflowMap == null) {
|
||||
//No workflowId found for this collection, so retrieve & use the default workflow
|
||||
if (workflowCache.get("default") == null) {
|
||||
String workflowID = XPathAPI
|
||||
.selectSingleNode(mainNode, "//workflow-map/name-map[@collection='default']")
|
||||
.getAttributes().getNamedItem("workflow").getTextContent();
|
||||
if (workflowID == null) {
|
||||
throw new WorkflowConfigurationException(
|
||||
"No mapping is present for collection with handle:" + collection.getHandle());
|
||||
if (workflowMapping.get(collection.getHandle()) == null) {
|
||||
final Workflow defaultWorkflow = workflowMapping.get(LEGACY_WORKFLOW_NAME);
|
||||
if (defaultWorkflow != null) {
|
||||
return defaultWorkflow;
|
||||
}
|
||||
Node workflowNode = XPathAPI.selectSingleNode(mainNode, "//workflow[@id='" + workflowID + "']");
|
||||
Workflow wf = new Workflow(workflowID, getRoles(workflowNode));
|
||||
Step step = createFirstStep(wf, workflowNode);
|
||||
wf.setFirstStep(step);
|
||||
workflowCache.put("default", wf);
|
||||
workflowCache.put(collection.getHandle(), wf);
|
||||
return wf;
|
||||
} else {
|
||||
return workflowCache.get("default");
|
||||
return workflowMapping.get(collection.getHandle());
|
||||
}
|
||||
|
||||
} else {
|
||||
//We have a workflowID so retrieve it & resolve it to a workflow, also store it in our cache
|
||||
String workflowID = workflowMap.getAttributes().getNamedItem("workflow").getTextContent();
|
||||
|
||||
Node workflowNode = XPathAPI.selectSingleNode(mainNode, "//workflow[@id='" + workflowID + "']");
|
||||
Workflow wf = new Workflow(workflowID, getRoles(workflowNode));
|
||||
Step step = createFirstStep(wf, workflowNode);
|
||||
wf.setFirstStep(step);
|
||||
workflowCache.put(collection.getHandle(), wf);
|
||||
return wf;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error while retrieving workflow for collection: " + collection.getHandle(), e);
|
||||
throw new WorkflowConfigurationException(
|
||||
"Error while retrieving workflow for the following collection: " + collection.getHandle());
|
||||
}
|
||||
} else {
|
||||
return workflowCache.get(collection.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
protected Step createFirstStep(Workflow workflow, Node workflowNode)
|
||||
throws TransformerException, WorkflowConfigurationException {
|
||||
String firstStepID = workflowNode.getAttributes().getNamedItem("start").getTextContent();
|
||||
Node stepNode = XPathAPI.selectSingleNode(workflowNode, "step[@id='" + firstStepID + "']");
|
||||
if (stepNode == null) {
|
||||
throw new WorkflowConfigurationException(
|
||||
"First step does not exist for workflow: " + workflowNode.getAttributes().getNamedItem("id")
|
||||
.getTextContent());
|
||||
}
|
||||
Node roleNode = stepNode.getAttributes().getNamedItem("role");
|
||||
Role role = null;
|
||||
if (roleNode != null) {
|
||||
role = workflow.getRoles().get(roleNode.getTextContent());
|
||||
}
|
||||
String userSelectionActionID = stepNode.getAttributes().getNamedItem("userSelectionMethod").getTextContent();
|
||||
UserSelectionActionConfig userSelection = createUserAssignmentActionConfig(userSelectionActionID);
|
||||
return new Step(firstStepID, workflow, role, userSelection, getStepActionConfigs(stepNode),
|
||||
getStepOutcomes(stepNode), getNbRequiredUser(stepNode));
|
||||
}
|
||||
|
||||
|
||||
protected Map<Integer, String> getStepOutcomes(Node stepNode)
|
||||
throws TransformerException, WorkflowConfigurationException {
|
||||
try {
|
||||
NodeList outcomesNodeList = XPathAPI.selectNodeList(stepNode, "outcomes/step");
|
||||
Map<Integer, String> outcomes = new HashMap<Integer, String>();
|
||||
//Add our outcome, should it be null it will be interpreted as the end of the line (last step)
|
||||
for (int i = 0; i < outcomesNodeList.getLength(); i++) {
|
||||
Node outcomeNode = outcomesNodeList.item(i);
|
||||
int index = Integer.parseInt(outcomeNode.getAttributes().getNamedItem("status").getTextContent());
|
||||
if (index < 0) {
|
||||
throw new WorkflowConfigurationException(
|
||||
"Outcome configuration error for step: " + stepNode.getAttributes().getNamedItem("id")
|
||||
.getTextContent());
|
||||
}
|
||||
outcomes.put(index, outcomeNode.getTextContent());
|
||||
}
|
||||
return outcomes;
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"Outcome configuration error for step: " + stepNode.getAttributes().getNamedItem("id").getTextContent(),
|
||||
e);
|
||||
throw new WorkflowConfigurationException(
|
||||
"Outcome configuration error for step: " + stepNode.getAttributes().getNamedItem("id")
|
||||
.getTextContent());
|
||||
@Required
|
||||
public void setWorkflowMapping(Map<String, Workflow> workflowMapping) {
|
||||
this.workflowMapping = workflowMapping;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getNbRequiredUser(Node stepnode) {
|
||||
if (stepnode.getAttributes().getNamedItem("requiredUsers") != null) {
|
||||
return Integer.parseInt(stepnode.getAttributes().getNamedItem("requiredUsers").getTextContent());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static List<String> getStepActionConfigs(Node stepNode) throws TransformerException {
|
||||
NodeList actionConfigNodes = XPathAPI.selectNodeList(stepNode, "actions/action");
|
||||
List<String> actionConfigIDs = new ArrayList<String>();
|
||||
for (int i = 0; i < actionConfigNodes.getLength(); i++) {
|
||||
actionConfigIDs.add(actionConfigNodes.item(i).getAttributes().getNamedItem("id").getTextContent());
|
||||
}
|
||||
return actionConfigIDs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step createStep(Workflow workflow, String stepID) throws WorkflowConfigurationException, IOException {
|
||||
try {
|
||||
File xmlFile = new File(path);
|
||||
Document input = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);
|
||||
Node mainNode = input.getFirstChild();
|
||||
Node stepNode = XPathAPI
|
||||
.selectSingleNode(mainNode, "//workflow[@id='" + workflow.getID() + "']/step[@id='" + stepID + "']");
|
||||
|
||||
if (stepNode == null) {
|
||||
throw new WorkflowConfigurationException("Step does not exist for workflow: " + workflow.getID());
|
||||
}
|
||||
Node roleNode = stepNode.getAttributes().getNamedItem("role");
|
||||
Role role = null;
|
||||
if (roleNode != null) {
|
||||
role = workflow.getRoles().get(roleNode.getTextContent());
|
||||
}
|
||||
String userSelectionActionID = stepNode.getAttributes().getNamedItem("userSelectionMethod")
|
||||
.getTextContent();
|
||||
UserSelectionActionConfig userSelection = createUserAssignmentActionConfig(userSelectionActionID);
|
||||
return new Step(stepID, workflow, role, userSelection, getStepActionConfigs(stepNode),
|
||||
getStepOutcomes(stepNode), getNbRequiredUser(stepNode));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error while creating step with :" + stepID, e);
|
||||
throw new WorkflowConfigurationException(
|
||||
"Step: " + stepID + " does not exist for workflow: " + workflow.getID());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected UserSelectionActionConfig createUserAssignmentActionConfig(String userSelectionActionID) {
|
||||
return DSpaceServicesFactory.getInstance().getServiceManager()
|
||||
.getServiceByName(userSelectionActionID, UserSelectionActionConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkflowActionConfig createWorkflowActionConfig(String actionID) {
|
||||
return DSpaceServicesFactory.getInstance().getServiceManager()
|
||||
.getServiceByName(actionID, WorkflowActionConfig.class);
|
||||
}
|
||||
|
||||
protected LinkedHashMap<String, Role> getRoles(Node workflowNode) throws WorkflowConfigurationException {
|
||||
NodeList roleNodes = null;
|
||||
try {
|
||||
roleNodes = XPathAPI.selectNodeList(workflowNode, "roles/role");
|
||||
} catch (Exception e) {
|
||||
log.error("Error while resolving nodes", e);
|
||||
throw new WorkflowConfigurationException("Error while retrieving roles");
|
||||
}
|
||||
LinkedHashMap<String, Role> roles = new LinkedHashMap<String, Role>();
|
||||
for (int i = 0; i < roleNodes.getLength(); i++) {
|
||||
String roleID = roleNodes.item(i).getAttributes().getNamedItem("id").getTextContent();
|
||||
String roleName = roleNodes.item(i).getAttributes().getNamedItem("name").getTextContent();
|
||||
Node descriptionNode = roleNodes.item(i).getAttributes().getNamedItem("description");
|
||||
String roleDescription = null;
|
||||
if (descriptionNode != null) {
|
||||
roleDescription = descriptionNode.getTextContent();
|
||||
}
|
||||
|
||||
Node scopeNode = roleNodes.item(i).getAttributes().getNamedItem("scope");
|
||||
String roleScope = null;
|
||||
if (scopeNode != null) {
|
||||
roleScope = scopeNode.getTextContent();
|
||||
}
|
||||
|
||||
Node internalNode = roleNodes.item(i).getAttributes().getNamedItem("internal");
|
||||
String roleInternal;
|
||||
boolean internal = false;
|
||||
if (internalNode != null) {
|
||||
roleInternal = internalNode.getTextContent();
|
||||
internal = Boolean.parseBoolean(roleInternal);
|
||||
|
||||
}
|
||||
|
||||
Role.Scope scope;
|
||||
if (roleScope == null || roleScope.equalsIgnoreCase("collection")) {
|
||||
scope = Role.Scope.COLLECTION;
|
||||
} else if (roleScope.equalsIgnoreCase("item")) {
|
||||
scope = Role.Scope.ITEM;
|
||||
} else if (roleScope.equalsIgnoreCase("repository")) {
|
||||
scope = Role.Scope.REPOSITORY;
|
||||
} else {
|
||||
throw new WorkflowConfigurationException(
|
||||
"An invalid role scope has been specified it must either be item or collection.");
|
||||
}
|
||||
|
||||
Role role = new Role(roleID, roleName, roleDescription, internal, scope);
|
||||
roles.put(roleID, role);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -7,14 +7,9 @@
|
||||
*/
|
||||
package org.dspace.xmlworkflow.factory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.state.Step;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
||||
|
||||
/**
|
||||
* The xmlworkflowfactory is responsible for parsing the
|
||||
@@ -28,11 +23,13 @@ import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
||||
*/
|
||||
public interface XmlWorkflowFactory {
|
||||
|
||||
public final String LEGACY_WORKFLOW_NAME = "default";
|
||||
|
||||
public Workflow getWorkflow(Collection collection) throws IOException, WorkflowConfigurationException, SQLException;
|
||||
|
||||
public Step createStep(Workflow workflow, String stepID) throws WorkflowConfigurationException, IOException;
|
||||
|
||||
public WorkflowActionConfig createWorkflowActionConfig(String actionID);
|
||||
/**
|
||||
* Retrieve the workflow configuration for a single collection
|
||||
*
|
||||
* @param collection the collection for which we want our workflow
|
||||
* @return the workflow configuration
|
||||
* @throws WorkflowConfigurationException occurs if there is a configuration error in the workflow
|
||||
*/
|
||||
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException;
|
||||
}
|
||||
|
@@ -7,22 +7,22 @@
|
||||
*/
|
||||
package org.dspace.xmlworkflow.state;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.workflow.WorkflowException;
|
||||
import org.dspace.xmlworkflow.Role;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig;
|
||||
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* A class that contains all the data of an xlworkflow step
|
||||
@@ -32,47 +32,37 @@ import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService;
|
||||
* @author Ben Bosman (ben at atmire dot com)
|
||||
* @author Mark Diggory (markd at atmire dot com)
|
||||
*/
|
||||
public class Step {
|
||||
|
||||
|
||||
protected InProgressUserService inProgressUserService = XmlWorkflowServiceFactory.getInstance()
|
||||
.getInProgressUserService();
|
||||
protected XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
|
||||
public class Step implements BeanNameAware {
|
||||
|
||||
@Autowired
|
||||
protected InProgressUserService inProgressUserService;
|
||||
|
||||
private UserSelectionActionConfig userSelectionMethod;
|
||||
private HashMap<String, WorkflowActionConfig> actionConfigsMap;
|
||||
private List<String> actionConfigsList;
|
||||
private Map<Integer, String> outcomes;
|
||||
private List<WorkflowActionConfig> actions;
|
||||
private Map<Integer, Step> outcomes = new HashMap<>();
|
||||
private String id;
|
||||
private Role role;
|
||||
private Workflow workflow;
|
||||
private int requiredUsers;
|
||||
|
||||
public Step(String id, Workflow workflow, Role role, UserSelectionActionConfig userSelectionMethod,
|
||||
List<String> actionConfigsList, Map<Integer, String> outcomes, int requiredUsers) {
|
||||
this.actionConfigsMap = new HashMap<>();
|
||||
this.outcomes = outcomes;
|
||||
this.userSelectionMethod = userSelectionMethod;
|
||||
this.role = role;
|
||||
this.actionConfigsList = actionConfigsList;
|
||||
this.id = id;
|
||||
userSelectionMethod.setStep(this);
|
||||
this.requiredUsers = requiredUsers;
|
||||
this.workflow = workflow;
|
||||
private int requiredUsers = 1;
|
||||
|
||||
/**
|
||||
* Get an WorkflowActionConfiguration object for the provided action identifier
|
||||
* @param actionID the action id for which we want our action config
|
||||
* @return The corresponding WorkflowActionConfiguration
|
||||
* @throws WorkflowConfigurationException occurs if the provided action isn't part of the step
|
||||
*/
|
||||
public WorkflowActionConfig getActionConfig(String actionID) throws WorkflowConfigurationException {
|
||||
// First check the userSelectionMethod as this is not a regular "action"
|
||||
if (userSelectionMethod != null && StringUtils.equals(userSelectionMethod.getId(), actionID)) {
|
||||
return userSelectionMethod;
|
||||
}
|
||||
|
||||
public WorkflowActionConfig getActionConfig(String actionID) {
|
||||
if (actionConfigsMap.get(actionID) != null) {
|
||||
return actionConfigsMap.get(actionID);
|
||||
} else {
|
||||
WorkflowActionConfig action = xmlWorkflowFactory.createWorkflowActionConfig(actionID);
|
||||
action.setStep(this);
|
||||
actionConfigsMap.put(actionID, action);
|
||||
return action;
|
||||
for (WorkflowActionConfig actionConfig : actions) {
|
||||
if (StringUtils.equals(actionConfig.getId(), actionID)) {
|
||||
return actionConfig;
|
||||
}
|
||||
}
|
||||
throw new WorkflowConfigurationException("Action configuration not found for: " + actionID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boolean that returns whether or not the actions in this step have a ui
|
||||
@@ -80,8 +70,7 @@ public class Step {
|
||||
* @return a boolean
|
||||
*/
|
||||
public boolean hasUI() {
|
||||
for (String actionConfigId : actionConfigsList) {
|
||||
WorkflowActionConfig actionConfig = getActionConfig(actionConfigId);
|
||||
for (WorkflowActionConfig actionConfig : actions) {
|
||||
if (actionConfig.requiresUI()) {
|
||||
return true;
|
||||
}
|
||||
@@ -89,8 +78,12 @@ public class Step {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getNextStepID(int outcome)
|
||||
throws WorkflowException, IOException, WorkflowConfigurationException, SQLException {
|
||||
/**
|
||||
* Get the next step based on out the outcome
|
||||
* @param outcome the outcome of the previous step
|
||||
* @return the next stepp or NULL if there is no step configured for this outcome
|
||||
*/
|
||||
public Step getNextStep(int outcome) {
|
||||
return outcomes.get(outcome);
|
||||
}
|
||||
|
||||
@@ -109,9 +102,9 @@ public class Step {
|
||||
}
|
||||
|
||||
public WorkflowActionConfig getNextAction(WorkflowActionConfig currentAction) {
|
||||
int index = actionConfigsList.indexOf(currentAction.getId());
|
||||
if (index < actionConfigsList.size() - 1) {
|
||||
return getActionConfig(actionConfigsList.get(index + 1));
|
||||
int index = actions.indexOf(currentAction);
|
||||
if (index < actions.size() - 1) {
|
||||
return actions.get(index + 1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -125,7 +118,6 @@ public class Step {
|
||||
return workflow;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if enough users have finished this step for it to continue
|
||||
*
|
||||
@@ -146,6 +138,78 @@ public class Step {
|
||||
return role;
|
||||
}
|
||||
|
||||
// public boolean skipStep() {
|
||||
// }
|
||||
/**
|
||||
* Set the user selection configuration, this is required as every step requires one
|
||||
* @param userSelectionMethod the user selection method configuration
|
||||
*/
|
||||
@Required
|
||||
public void setUserSelectionMethod(UserSelectionActionConfig userSelectionMethod) {
|
||||
this.userSelectionMethod = userSelectionMethod;
|
||||
userSelectionMethod.setStep(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the outcomes as a map, if no outcomes are configured this step will be last step in the workflow
|
||||
* @param outcomes the map containing the outcomes.
|
||||
*/
|
||||
public void setOutcomes(Map<Integer, Step> outcomes) {
|
||||
this.outcomes = outcomes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the processing actions for the step. Processing actions contain the logic required to execute the required
|
||||
* operations in each step.
|
||||
* @return the actions configured for this step
|
||||
*/
|
||||
public List<WorkflowActionConfig> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the processing actions for the step. Processing actions contain the logic required to execute the required
|
||||
* operations in each step.
|
||||
* @param actions the list of actions
|
||||
*/
|
||||
@Required
|
||||
public void setActions(List<WorkflowActionConfig> actions) {
|
||||
for (WorkflowActionConfig workflowActionConfig : actions) {
|
||||
workflowActionConfig.setStep(this);
|
||||
}
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the workflow this step belongs to
|
||||
* @param workflow the workflow configuration
|
||||
*/
|
||||
protected void setWorkflow(Workflow workflow) {
|
||||
this.workflow = workflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the name of the bean in the identifier
|
||||
* @param s the bean name
|
||||
*/
|
||||
@Override
|
||||
public void setBeanName(String s) {
|
||||
id = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of required users that need to execute this step before it is completed,
|
||||
* the default is a single user
|
||||
* @param requiredUsers the number of required users
|
||||
*/
|
||||
public void setRequiredUsers(int requiredUsers) {
|
||||
this.requiredUsers = requiredUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role of which users role should execute this step
|
||||
* @param role the role to be configured for this step
|
||||
*/
|
||||
public void setRole(Role role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
||||
|
@@ -7,18 +7,18 @@
|
||||
*/
|
||||
package org.dspace.xmlworkflow.state;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.workflow.WorkflowException;
|
||||
import org.dspace.xmlworkflow.Role;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
|
||||
import org.dspace.xmlworkflow.state.actions.ActionResult;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* Class that contains all the steps and roles involved in a certain
|
||||
@@ -29,21 +29,11 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
* @author Ben Bosman (ben at atmire dot com)
|
||||
* @author Mark Diggory (markd at atmire dot com)
|
||||
*/
|
||||
public class Workflow {
|
||||
|
||||
protected XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
|
||||
public class Workflow implements BeanNameAware {
|
||||
|
||||
private String id;
|
||||
private Step firstStep;
|
||||
private HashMap<String, Step> steps;
|
||||
private LinkedHashMap<String, Role> roles;
|
||||
|
||||
|
||||
public Workflow(String workflowID, LinkedHashMap<String, Role> roles) {
|
||||
this.id = workflowID;
|
||||
this.roles = roles;
|
||||
this.steps = new HashMap<String, Step>();
|
||||
}
|
||||
private List<Step> steps;
|
||||
|
||||
public Step getFirstStep() {
|
||||
return firstStep;
|
||||
@@ -56,46 +46,72 @@ public class Workflow {
|
||||
/*
|
||||
* Return a step with a given id
|
||||
*/
|
||||
public Step getStep(String stepID) throws WorkflowConfigurationException, IOException {
|
||||
if (steps.get(id) != null) {
|
||||
return steps.get(id);
|
||||
} else {
|
||||
Step step = xmlWorkflowFactory.createStep(this, stepID);
|
||||
if (step == null) {
|
||||
throw new WorkflowConfigurationException("Step definition not found for: " + stepID);
|
||||
}
|
||||
steps.put(stepID, step);
|
||||
public Step getStep(String stepID) throws WorkflowConfigurationException {
|
||||
for (Step step : steps) {
|
||||
if (step.getId().equals(stepID)) {
|
||||
return step;
|
||||
}
|
||||
}
|
||||
throw new WorkflowConfigurationException("Step definition not found for: " + stepID);
|
||||
}
|
||||
|
||||
public Step getNextStep(Context context, XmlWorkflowItem wfi, Step currentStep, int outcome)
|
||||
throws IOException, WorkflowConfigurationException, WorkflowException, SQLException {
|
||||
String nextStepID = currentStep.getNextStepID(outcome);
|
||||
if (nextStepID != null) {
|
||||
Step nextStep = getStep(nextStepID);
|
||||
if (nextStep == null) {
|
||||
throw new WorkflowException(
|
||||
"Error while processing outcome, the following action was undefined: " + nextStepID);
|
||||
}
|
||||
throws WorkflowConfigurationException, SQLException {
|
||||
Step nextStep = currentStep.getNextStep(outcome);
|
||||
if (nextStep != null) {
|
||||
if (nextStep.isValidStep(context, wfi)) {
|
||||
return nextStep;
|
||||
} else {
|
||||
return getNextStep(context, wfi, nextStep, 0);
|
||||
return getNextStep(context, wfi, nextStep, ActionResult.OUTCOME_COMPLETE);
|
||||
}
|
||||
|
||||
} else {
|
||||
//No next step, archive it
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setFirstStep(Step firstStep) {
|
||||
firstStep.setWorkflow(this);
|
||||
this.firstStep = firstStep;
|
||||
}
|
||||
|
||||
public HashMap<String, Role> getRoles() {
|
||||
/**
|
||||
* Get the steps that need to be executed in this workflow before the item is archived
|
||||
* @return the workflow steps
|
||||
*/
|
||||
public List<Step> getSteps() {
|
||||
return steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the steps that need to be executed in this workflow before the item is archived
|
||||
* @param steps the workflow steps
|
||||
*/
|
||||
@Required
|
||||
public void setSteps(List<Step> steps) {
|
||||
for (Step step : steps) {
|
||||
step.setWorkflow(this);
|
||||
}
|
||||
this.steps = steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the roles that are used in this workflow
|
||||
* @return a map containing the roles, the role name will the key, the role itself the value
|
||||
*/
|
||||
public Map<String, Role> getRoles() {
|
||||
Map<String, Role> roles = new HashMap<>();
|
||||
for (Step step : steps) {
|
||||
if (step.getRole() != null) {
|
||||
roles.put(step.getRole().getName(), step.getRole());
|
||||
}
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String s) {
|
||||
id = s;
|
||||
}
|
||||
}
|
||||
|
@@ -19,12 +19,14 @@ import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.workflow.WorkflowException;
|
||||
import org.dspace.xmlworkflow.Role;
|
||||
import org.dspace.xmlworkflow.state.Step;
|
||||
import org.dspace.xmlworkflow.state.actions.ActionResult;
|
||||
import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
* Processing class for an action where an assigned user can
|
||||
@@ -42,7 +44,7 @@ public class SelectReviewerAction extends ProcessingAction {
|
||||
|
||||
public static final int RESULTS_PER_PAGE = 5;
|
||||
|
||||
private String roleId;
|
||||
private Role role;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected EPersonService ePersonService;
|
||||
@@ -90,7 +92,7 @@ public class SelectReviewerAction extends ProcessingAction {
|
||||
//We have a reviewer, assign him, the workflowitemrole will be translated into a task in the autoassign
|
||||
WorkflowItemRole workflowItemRole = workflowItemRoleService.create(c);
|
||||
workflowItemRole.setEPerson(reviewer);
|
||||
workflowItemRole.setRoleId(getRoleId());
|
||||
workflowItemRole.setRoleId(getRole().getId());
|
||||
workflowItemRole.setWorkflowItem(wfi);
|
||||
workflowItemRoleService.update(c, workflowItemRole);
|
||||
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
|
||||
@@ -100,11 +102,12 @@ public class SelectReviewerAction extends ProcessingAction {
|
||||
return new ActionResult(ActionResult.TYPE.TYPE_ERROR);
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
public Role getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
@Required
|
||||
public void setRole(Role role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,17 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- DS-4239 Migrate the workflow.xml to spring
|
||||
---------------------------------------------------------------
|
||||
-- This script will rename the default workflow "default" name
|
||||
-- to the new "defaultWorkflow" identifier
|
||||
---------------------------------------------------------------
|
||||
|
||||
UPDATE cwf_pooltask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
||||
UPDATE cwf_claimtask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
@@ -0,0 +1,17 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- DS-4239 Migrate the workflow.xml to spring
|
||||
---------------------------------------------------------------
|
||||
-- This script will rename the default workflow "default" name
|
||||
-- to the new "defaultWorkflow" identifier
|
||||
---------------------------------------------------------------
|
||||
|
||||
UPDATE cwf_pooltask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
||||
UPDATE cwf_claimtask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
@@ -0,0 +1,17 @@
|
||||
--
|
||||
-- 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/
|
||||
--
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- DS-4239 Migrate the workflow.xml to spring
|
||||
---------------------------------------------------------------
|
||||
-- This script will rename the default workflow "default" name
|
||||
-- to the new "defaultWorkflow" identifier
|
||||
---------------------------------------------------------------
|
||||
|
||||
UPDATE cwf_pooltask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
||||
UPDATE cwf_claimtask SET workflow_id='defaultWorkflow' WHERE workflow_id='default';
|
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<bean name="xmlWorkflowFactory" class="org.dspace.xmlworkflow.XmlWorkflowFactoryImpl">
|
||||
<property name="workflowMapping">
|
||||
<util:map>
|
||||
<entry key="defaultWorkflow"
|
||||
value-ref="defaultWorkflow"/>
|
||||
<entry key="123456789/4" value-ref="selectSingleReviewer"/>
|
||||
<!-- <entry key="123456789/5" value-ref="scoreReview"/>-->
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!--Standard DSpace workflow-->
|
||||
<bean name="defaultWorkflow" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="reviewstep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="reviewstep"/>
|
||||
<ref bean="editstep"/>
|
||||
<ref bean="finaleditstep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="reviewer"/>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="editstep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<util:list>
|
||||
<ref bean="reviewaction"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewer" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Reviewer"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
|
||||
</bean>
|
||||
|
||||
<bean name="editstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="editor" />
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="finaleditstep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="editaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="editor" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Editor"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
|
||||
</bean>
|
||||
|
||||
<bean name="finaleditstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="finaleditor" />
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="finaleditaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="finaleditor" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Final Editor"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, but will not be able to reject them."/>
|
||||
</bean>
|
||||
|
||||
<!--Workflow where a reviewManager can select a single review who will then either accept/reject the item-->
|
||||
<bean name="selectSingleReviewer" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="selectReviewerStep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="selectReviewerStep"/>
|
||||
<ref bean="singleUserReviewStep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="selectReviewerStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="reviewmanagers">
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="selectrevieweraction"/>
|
||||
</list>
|
||||
</property>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="singleUserReviewStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewmanagers" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).REPOSITORY}"/>
|
||||
<property name="name" value="ReviewManagers"/>
|
||||
</bean>
|
||||
|
||||
<bean name="singleUserReviewStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="autoassignAction"/>
|
||||
<property name="role" ref="scoreAssignedReviewer">
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="singleuserreviewaction"/>
|
||||
</list>
|
||||
</property>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.processingaction.SingleUserReviewAction).OUTCOME_REJECT}"
|
||||
value-ref="selectReviewerStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreAssignedReviewer" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).ITEM}"/>
|
||||
<property name="name" value="Reviewer"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!--Workflow where a number of users will perform reviews on an item and depending on the scores the item will be archived/rejected-->
|
||||
<bean name="scoreReview" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="scoreReviewStep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="scoreReviewStep"/>
|
||||
<ref bean="evaluationStep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreReviewStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="scoreReviewers"/>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="evaluationStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="scorereviewaction"/>
|
||||
</list>
|
||||
</property>
|
||||
<property name="requiredUsers" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean name="evaluationStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="noUserSelectionAction"/>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="evaluationaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreReviewers" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="ScoreReviewers"/>
|
||||
</bean>
|
||||
</beans>
|
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import org.dspace.AbstractUnitTest;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests that check that the spring beans (of type {@link Role}) in workflow.xml get created correctly
|
||||
*
|
||||
* @author Maria Verdonck (Atmire) on 19/12/2019
|
||||
*/
|
||||
public class RoleTest extends AbstractUnitTest {
|
||||
|
||||
private Workflow defaultWorkflow
|
||||
= new DSpace().getServiceManager().getServiceByName("defaultWorkflow", Workflow.class);
|
||||
private Workflow selectSingleReviewer
|
||||
= new DSpace().getServiceManager().getServiceByName("selectSingleReviewer", Workflow.class);
|
||||
private Workflow scoreReview
|
||||
= new DSpace().getServiceManager().getServiceByName("scoreReview", Workflow.class);
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_RoleReviewer() {
|
||||
Role role = defaultWorkflow.getRoles().get("Reviewer");
|
||||
assertEquals(role.getDescription(),
|
||||
"The people responsible for this step are able to edit the metadata of incoming submissions, " +
|
||||
"and then accept or reject them.");
|
||||
assertEquals(role.getName(), "Reviewer");
|
||||
assertEquals(role.getScope(), Role.Scope.COLLECTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_RoleEditor() {
|
||||
Role role = defaultWorkflow.getRoles().get("Editor");
|
||||
assertEquals(role.getDescription(), "The people responsible for this step are able to edit the " +
|
||||
"metadata of incoming submissions, and then accept or reject them.");
|
||||
assertEquals(role.getName(), "Editor");
|
||||
assertEquals(role.getScope(), Role.Scope.COLLECTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_RoleFinalEditor() {
|
||||
Role role = defaultWorkflow.getRoles().get("Final Editor");
|
||||
assertEquals(role.getDescription(), "The people responsible for this step are able to edit the " +
|
||||
"metadata of incoming submissions, but will not be able to reject them.");
|
||||
assertEquals(role.getName(), "Final Editor");
|
||||
assertEquals(role.getScope(), Role.Scope.COLLECTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectSingleReviewer_RoleReviewManagers() {
|
||||
Role role = selectSingleReviewer.getRoles().get("ReviewManagers");
|
||||
assertEquals(role.getName(), "ReviewManagers");
|
||||
assertEquals(role.getScope(), Role.Scope.REPOSITORY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectSingleReviewer_RoleReviewer() {
|
||||
Role role = selectSingleReviewer.getRoles().get("Reviewer");
|
||||
assertEquals(role.getName(), "Reviewer");
|
||||
assertEquals(role.getScope(), Role.Scope.ITEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scoreReview_RoleScoreReviewers() {
|
||||
Role role = scoreReview.getRoles().get("ScoreReviewers");
|
||||
assertEquals(role.getName(), "ScoreReviewers");
|
||||
assertEquals(role.getScope(), Role.Scope.COLLECTION);
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import org.dspace.AbstractUnitTest;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests that check that the spring bean {@link org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactoryImpl}
|
||||
* in workflow.xml gets created correctly
|
||||
*
|
||||
* @author Maria Verdonck (Atmire) on 19/12/2019
|
||||
*/
|
||||
public class XmlWorkflowFactoryTest extends AbstractUnitTest {
|
||||
|
||||
private CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
|
||||
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
|
||||
private XmlWorkflowFactory xmlWorkflowFactory
|
||||
= new DSpace().getServiceManager().getServiceByName("xmlWorkflowFactory",
|
||||
XmlWorkflowFactoryImpl.class);
|
||||
private Community owningCommunity;
|
||||
|
||||
/**
|
||||
* log4j category
|
||||
*/
|
||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowFactoryTest.class);
|
||||
|
||||
/**
|
||||
* This method will be run before every test as per @Before. It will
|
||||
* initialize resources required for the tests.
|
||||
*
|
||||
* Other methods can be annotated with @Before here or in subclasses
|
||||
* but no execution order is guaranteed
|
||||
*/
|
||||
@Before
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
try {
|
||||
//we have to create a new community in the database
|
||||
context.turnOffAuthorisationSystem();
|
||||
this.owningCommunity = communityService.create(null, context);
|
||||
//we need to commit the changes so we don't block the table for testing
|
||||
context.restoreAuthSystemState();
|
||||
} catch (SQLException e) {
|
||||
log.error("SQL Error in init", e);
|
||||
fail("SQL Error in init: " + e.getMessage());
|
||||
} catch (AuthorizeException e) {
|
||||
log.error("Authorization Error in init", e);
|
||||
fail("Authorization Error in init: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflowMapping_NonMappedCollection() throws WorkflowConfigurationException {
|
||||
Collection collection = this.findOrCreateCollectionWithHandle("123456789/6");
|
||||
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection);
|
||||
assertEquals(workflow.getID(), "defaultWorkflow");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workflowMapping_MappedCollection() throws WorkflowConfigurationException {
|
||||
Collection collection = this.findOrCreateCollectionWithHandle("123456789/4");
|
||||
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection);
|
||||
assertEquals(workflow.getID(), "selectSingleReviewer");
|
||||
}
|
||||
|
||||
private Collection findOrCreateCollectionWithHandle(String handle) {
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
for (Collection collection : this.collectionService.findAll(context)) {
|
||||
if (collection.getHandle().equalsIgnoreCase(handle)) {
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
Collection collection = this.collectionService.create(context, owningCommunity, handle);
|
||||
context.restoreAuthSystemState();
|
||||
return collection;
|
||||
} catch (SQLException e) {
|
||||
log.error("SQL Error in findOrCreateCollectionWithHandle", e);
|
||||
fail("SQL Error in findOrCreateCollectionWithHandle: " + e.getMessage());
|
||||
} catch (AuthorizeException e) {
|
||||
log.error("Authorization Error in findOrCreateCollectionWithHandle", e);
|
||||
fail("Authorization Error in findOrCreateCollectionWithHandle: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 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.state;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.AbstractUnitTest;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.dspace.xmlworkflow.WorkflowConfigurationException;
|
||||
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests that check that the spring beans (of type {@link Step}) in workflow.xml get created correctly
|
||||
*
|
||||
* @author Maria Verdonck (Atmire) on 19/12/2019
|
||||
*/
|
||||
public class StepTest extends AbstractUnitTest {
|
||||
|
||||
private Workflow defaultWorkflow
|
||||
= new DSpace().getServiceManager().getServiceByName("defaultWorkflow", Workflow.class);
|
||||
private Workflow selectSingleReviewer
|
||||
= new DSpace().getServiceManager().getServiceByName("selectSingleReviewer", Workflow.class);
|
||||
private Workflow scoreReview
|
||||
= new DSpace().getServiceManager().getServiceByName("scoreReview", Workflow.class);
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_ReviewStep() throws WorkflowConfigurationException {
|
||||
Step step = defaultWorkflow.getStep("reviewstep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "claimaction");
|
||||
assertEquals(step.getRole().getName(), "Reviewer");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "reviewaction"));
|
||||
assertEquals(step.getNextStep(0).getId(), "editstep");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_EditStep() throws WorkflowConfigurationException {
|
||||
Step step = defaultWorkflow.getStep("editstep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "claimaction");
|
||||
assertEquals(step.getRole().getName(), "Editor");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "editaction"));
|
||||
assertEquals(step.getNextStep(0).getId(), "finaleditstep");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow_FinalEditStep() throws WorkflowConfigurationException {
|
||||
Step step = defaultWorkflow.getStep("finaleditstep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "claimaction");
|
||||
assertEquals(step.getRole().getName(), "Final Editor");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "finaleditaction"));
|
||||
assertNull(step.getNextStep(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectSingleReviewer_SelectReviewerStep() throws WorkflowConfigurationException {
|
||||
Step step = selectSingleReviewer.getStep("selectReviewerStep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "claimaction");
|
||||
assertEquals(step.getRole().getName(), "ReviewManagers");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "selectrevieweraction"));
|
||||
assertEquals(step.getNextStep(0).getId(), "singleUserReviewStep");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectSingleReviewer_SingleUserReviewStep() throws WorkflowConfigurationException {
|
||||
Step step = selectSingleReviewer.getStep("singleUserReviewStep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "autoassignAction");
|
||||
assert (step.getRole().getName().equals("Reviewer"));
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "singleuserreviewaction"));
|
||||
assertEquals(step.getNextStep(1).getId(), "selectReviewerStep");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scoreReview_ScoreReviewStep() throws WorkflowConfigurationException {
|
||||
Step step = scoreReview.getStep("scoreReviewStep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "claimaction");
|
||||
assertEquals(step.getRole().getName(), "ScoreReviewers");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "scorereviewaction"));
|
||||
assertEquals(step.getNextStep(0).getId(), "evaluationStep");
|
||||
assertEquals(step.getRequiredUsers(), 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scoreReview_EvaluationStep() throws WorkflowConfigurationException {
|
||||
Step step = scoreReview.getStep("evaluationStep");
|
||||
assertEquals(step.getUserSelectionMethod().getId(), "noUserSelectionAction");
|
||||
List<WorkflowActionConfig> actions = step.getActions();
|
||||
assert (this.containsActionNamed(actions, "evaluationaction"));
|
||||
assertNull(step.getNextStep(0));
|
||||
}
|
||||
|
||||
private boolean containsActionNamed(List<WorkflowActionConfig> actions, String actionName) {
|
||||
for (WorkflowActionConfig workflowActionConfig : actions) {
|
||||
if (workflowActionConfig.getId().equalsIgnoreCase(actionName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.state;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.AbstractUnitTest;
|
||||
import org.dspace.utils.DSpace;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests that check that the spring beans (of type {@link Workflow}) in workflow.xml get created correctly
|
||||
*
|
||||
* @author Maria Verdonck (Atmire) on 19/12/2019
|
||||
*/
|
||||
public class WorkflowTest extends AbstractUnitTest {
|
||||
|
||||
private Workflow defaultWorkflow
|
||||
= new DSpace().getServiceManager().getServiceByName("defaultWorkflow", Workflow.class);
|
||||
private Workflow selectSingleReviewer
|
||||
= new DSpace().getServiceManager().getServiceByName("selectSingleReviewer", Workflow.class);
|
||||
private Workflow scoreReview
|
||||
= new DSpace().getServiceManager().getServiceByName("scoreReview", Workflow.class);
|
||||
|
||||
@Test
|
||||
public void defaultWorkflow() {
|
||||
assertEquals(defaultWorkflow.getFirstStep().getId(), "reviewstep");
|
||||
List<Step> steps = defaultWorkflow.getSteps();
|
||||
assertEquals(steps.size(), 3);
|
||||
assert (this.containsStepNamed(steps, "reviewstep"));
|
||||
assert (this.containsStepNamed(steps, "editstep"));
|
||||
assert (this.containsStepNamed(steps, "finaleditstep"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectSingleReviewer() {
|
||||
assertEquals(selectSingleReviewer.getFirstStep().getId(), "selectReviewerStep");
|
||||
List<Step> steps = selectSingleReviewer.getSteps();
|
||||
assertEquals(steps.size(), 2);
|
||||
assert (this.containsStepNamed(steps, "selectReviewerStep"));
|
||||
assert (this.containsStepNamed(steps, "singleUserReviewStep"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scoreReview() {
|
||||
assertEquals(scoreReview.getFirstStep().getId(), "scoreReviewStep");
|
||||
List<Step> steps = scoreReview.getSteps();
|
||||
assertEquals(steps.size(), 2);
|
||||
assert (this.containsStepNamed(steps, "scoreReviewStep"));
|
||||
assert (this.containsStepNamed(steps, "evaluationStep"));
|
||||
}
|
||||
|
||||
private boolean containsStepNamed(List<Step> steps, String stepName) {
|
||||
for (Step step : steps) {
|
||||
if (step.getId().equalsIgnoreCase(stepName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -115,7 +115,6 @@
|
||||
<bean class="org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItemServiceImpl"/>
|
||||
<bean class="org.dspace.xmlworkflow.XmlWorkflowServiceImpl"/>
|
||||
<bean class="org.dspace.xmlworkflow.WorkflowRequirementsServiceImpl"/>
|
||||
<bean class="org.dspace.xmlworkflow.XmlWorkflowFactoryImpl"/>
|
||||
|
||||
<!-- Discovery indexable object services -->
|
||||
<bean class="org.dspace.discovery.indexobject.ClaimedTaskIndexFactoryImpl" autowire-candidate="true"/>
|
||||
|
@@ -13,7 +13,7 @@
|
||||
<bean id="singleuserreviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SingleUserReviewAction" scope="prototype"/>
|
||||
|
||||
<bean id="selectrevieweractionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SelectReviewerAction" scope="prototype">
|
||||
<property name="roleId" value="reviewer"/>
|
||||
<property name="role" ref="scoreAssignedReviewer"/>
|
||||
</bean>
|
||||
<bean id="scorereviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreReviewAction" scope="prototype"/>
|
||||
<bean id="evaluationactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreEvaluationAction" scope="prototype">
|
||||
|
190
dspace/config/spring/api/workflow.xml
Normal file
190
dspace/config/spring/api/workflow.xml
Normal file
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<bean class="org.dspace.xmlworkflow.XmlWorkflowFactoryImpl">
|
||||
<property name="workflowMapping">
|
||||
<util:map>
|
||||
<entry key="defaultWorkflow"
|
||||
value-ref="defaultWorkflow"/>
|
||||
<!-- <entry key="123456789/4" value-ref="selectSingleReviewer"/>-->
|
||||
<!-- <entry key="123456789/5" value-ref="scoreReview"/>-->
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!--Standard DSpace workflow-->
|
||||
<bean name="defaultWorkflow" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="reviewstep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="reviewstep"/>
|
||||
<ref bean="editstep"/>
|
||||
<ref bean="finaleditstep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="reviewer"/>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="editstep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<util:list>
|
||||
<ref bean="reviewaction"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewer" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Reviewer"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean name="editstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="editor" />
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="finaleditstep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="editaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="editor" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Editor"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
|
||||
</bean>
|
||||
|
||||
<bean name="finaleditstep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="finaleditor" />
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="finaleditaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="finaleditor" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="Final Editor"/>
|
||||
<property name="description"
|
||||
value="The people responsible for this step are able to edit the metadata of incoming submissions, but will not be able to reject them."/>
|
||||
</bean>
|
||||
|
||||
<!--Workflow where a reviewManager can select a single review who will then either accept/reject the item-->
|
||||
<bean name="selectSingleReviewer" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="selectReviewerStep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="selectReviewerStep"/>
|
||||
<ref bean="singleUserReviewStep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="selectReviewerStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="reviewmanagers">
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="selectrevieweraction" />
|
||||
</list>
|
||||
</property>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="singleUserReviewStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="reviewmanagers" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).REPOSITORY}"/>
|
||||
<property name="name" value="ReviewManagers"/>
|
||||
</bean>
|
||||
|
||||
<bean name="singleUserReviewStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="autoassignAction"/>
|
||||
<property name="role" ref="scoreAssignedReviewer">
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="singleuserreviewaction" />
|
||||
</list>
|
||||
</property>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.processingaction.SingleUserReviewAction).OUTCOME_REJECT}" value-ref="selectReviewerStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreAssignedReviewer" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).ITEM}"/>
|
||||
<property name="name" value="Reviewer"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!--Workflow where a number of users will perform reviews on an item and depending on the scores the item will be archived/rejected-->
|
||||
<bean name="scoreReview" class="org.dspace.xmlworkflow.state.Workflow">
|
||||
<property name="firstStep" ref="scoreReviewStep"/>
|
||||
<property name="steps">
|
||||
<util:list>
|
||||
<ref bean="scoreReviewStep"/>
|
||||
<ref bean="evaluationStep"/>
|
||||
</util:list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreReviewStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="claimaction"/>
|
||||
<property name="role" ref="scoreReviewers"/>
|
||||
<property name="outcomes">
|
||||
<util:map>
|
||||
<entry key="#{ T(org.dspace.xmlworkflow.state.actions.ActionResult).OUTCOME_COMPLETE}"
|
||||
value-ref="evaluationStep"/>
|
||||
</util:map>
|
||||
</property>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="scorereviewaction"/>
|
||||
</list>
|
||||
</property>
|
||||
<property name="requiredUsers" value="2"/>
|
||||
</bean>
|
||||
|
||||
<bean name="evaluationStep" class="org.dspace.xmlworkflow.state.Step">
|
||||
<property name="userSelectionMethod" ref="noUserSelectionAction"/>
|
||||
<property name="actions">
|
||||
<list>
|
||||
<ref bean="evaluationaction"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean name="scoreReviewers" class="org.dspace.xmlworkflow.Role">
|
||||
<property name="scope" value="#{ T(org.dspace.xmlworkflow.Role.Scope).COLLECTION}"/>
|
||||
<property name="name" value="ScoreReviewers"/>
|
||||
</bean>
|
||||
</beans>
|
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wf-config>
|
||||
<workflow-map>
|
||||
<name-map collection="default" workflow="default"/>
|
||||
<!--<name-map collection="123456789/4" workflow="selectSingleReviewer"/>-->
|
||||
<!--<name-map collection="123456789/5" workflow="scoreReview"/>-->
|
||||
</workflow-map>
|
||||
|
||||
<!--Standard workflow step-->
|
||||
<workflow start="reviewstep" id="default">
|
||||
|
||||
<roles>
|
||||
<role id="reviewer" name="Reviewer" description="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them." />
|
||||
<role id="editor" name="Editor" description="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
|
||||
<role id="finaleditor" name="Final Editor" description="The people responsible for this step are able to edit the metadata of incoming submissions, but will not be able to reject them."/>
|
||||
</roles>
|
||||
|
||||
<step id="reviewstep" role="reviewer" userSelectionMethod="claimaction">
|
||||
<outcomes>
|
||||
<step status="0">editstep</step>
|
||||
</outcomes>
|
||||
<actions>
|
||||
<action id="reviewaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
<step id="editstep" role="editor" userSelectionMethod="claimaction">
|
||||
<outcomes>
|
||||
<step status="0">finaleditstep</step>
|
||||
</outcomes>
|
||||
<actions>
|
||||
<action id="editaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
<step id="finaleditstep" role="finaleditor" userSelectionMethod="claimaction">
|
||||
<actions>
|
||||
<action id="finaleditaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
</workflow>
|
||||
|
||||
<!--Workflow where a reviewManager can select a single review who will then either accept/reject the item-->
|
||||
<workflow id="selectSingleReviewer" start="selectReviewerStep">
|
||||
<roles>
|
||||
<role id="reviewer" name="Reviewer" scope="item" />
|
||||
<role id="reviewmanagers" name="ReviewManagers" scope="repository"/>
|
||||
</roles>
|
||||
|
||||
|
||||
<step id="selectReviewerStep" role="reviewmanagers" userSelectionMethod="claimaction">
|
||||
<outcomes>
|
||||
<step status="0">singleUserReviewStep</step>
|
||||
</outcomes>
|
||||
<actions>
|
||||
<action id="selectrevieweraction"/>
|
||||
</actions>
|
||||
</step>
|
||||
|
||||
<step id="singleUserReviewStep" role="reviewer" userSelectionMethod="autoassignAction">
|
||||
<outcomes>
|
||||
<step status="1">selectReviewerStep</step>
|
||||
</outcomes>
|
||||
<actions>
|
||||
<action id="singleuserreviewaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
||||
<!--Workflow where a number of users will perform reviews on an item and depending on the scores the item will be archived/rejected-->
|
||||
<workflow id="scoreReview" start="scoreReviewStep">
|
||||
<roles>
|
||||
<role id="scoreReviewers" name="ScoreReviewers" scope="collection" description="The people responsible to select a single reviewer for the submission"/>
|
||||
</roles>
|
||||
|
||||
<step id="scoreReviewStep" role="scoreReviewers" userSelectionMethod="claimaction" requiredUsers="2">
|
||||
<outcomes>
|
||||
<step status="0">evaluationStep</step>
|
||||
</outcomes>
|
||||
<actions>
|
||||
<action id="scorereviewaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
<step id="evaluationStep" userSelectionMethod="noUserSelectionAction">
|
||||
<actions>
|
||||
<action id="evaluationaction"/>
|
||||
</actions>
|
||||
</step>
|
||||
</workflow>
|
||||
</wf-config>
|
Reference in New Issue
Block a user