mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-14 13:33:08 +00:00
Merge pull request #75 from atmire/dspace3-workflow
[DS-1249] Configurable Workflow Improvements
This commit is contained in:
@@ -310,7 +310,8 @@ public class DescribeStep extends AbstractProcessingStep
|
||||
DCValue[] values = item.getMetadata(inputs[i].getSchema(),
|
||||
inputs[i].getElement(), inputs[i].getQualifier(), Item.ANY);
|
||||
|
||||
if (inputs[i].isRequired() && values.length == 0)
|
||||
if ((inputs[i].isRequired() && values.length == 0) &&
|
||||
inputs[i].isVisible(subInfo.isInWorkflow() ? DCInput.WORKFLOW_SCOPE : DCInput.SUBMISSION_SCOPE))
|
||||
{
|
||||
// since this field is missing add to list of error fields
|
||||
addErrorField(request, getFieldName(inputs[i]));
|
||||
|
@@ -86,7 +86,7 @@ public class UsageEvent extends Event {
|
||||
return objText + ":" + action.text();
|
||||
}catch(Exception e)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
return "";
|
||||
|
||||
|
@@ -15,12 +15,10 @@ import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Email;
|
||||
import org.dspace.core.I18nUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.dspace.xmlworkflow.state.Workflow;
|
||||
import org.dspace.xmlworkflow.storedcomponents.CollectionRole;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
@@ -211,9 +209,13 @@ public class WorkflowUtils extends Util{
|
||||
/*
|
||||
* Deletes a role group linked to a given role and a collection
|
||||
*/
|
||||
public static void deleteRoleGroup(Context context, int collectionID, String roleID) throws SQLException {
|
||||
CollectionRole ass = CollectionRole.find(context,collectionID,roleID);
|
||||
ass.delete();
|
||||
public static void deleteRoleGroup(Context context, Collection collection, String roleID) throws SQLException, IOException, WorkflowConfigurationException {
|
||||
Workflow workflow = WorkflowFactory.getWorkflow(collection);
|
||||
Role role = workflow.getRoles().get(roleID);
|
||||
if(role.getScope() == Role.Scope.COLLECTION){
|
||||
CollectionRole ass = CollectionRole.find(context, collection.getID(), roleID);
|
||||
ass.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -236,6 +238,46 @@ public class WorkflowUtils extends Util{
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, Role> getCollectionAndRepositoryRoles(Collection thisCollection) throws IOException, WorkflowConfigurationException {
|
||||
Workflow workflow = WorkflowFactory.getWorkflow(thisCollection);
|
||||
LinkedHashMap<String, Role> result = new LinkedHashMap<String, Role>();
|
||||
if(workflow != null){
|
||||
//Make sure we find one
|
||||
HashMap<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);
|
||||
// We just require the roles which have a scope of collection
|
||||
if((role.getScope() == Role.Scope.COLLECTION || role.getScope() == Role.Scope.REPOSITORY) && !role.isInternal()){
|
||||
result.put(roleId, role);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, Role> getAllExternalRoles(Collection thisCollection) throws IOException, WorkflowConfigurationException {
|
||||
Workflow workflow = WorkflowFactory.getWorkflow(thisCollection);
|
||||
LinkedHashMap<String, Role> result = new LinkedHashMap<String, Role>();
|
||||
if(workflow != null){
|
||||
//Make sure we find one
|
||||
HashMap<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);
|
||||
// We just require the roles which have a scope of collection
|
||||
if(!role.isInternal()){
|
||||
result.put(roleId, role);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Group getRoleGroup(Context context, int collectionId, Role role) throws SQLException {
|
||||
if(role.getScope() == Role.Scope.REPOSITORY){
|
||||
return Group.findByName(context, role.getName());
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<%@ page import="org.dspace.content.Bitstream" %>
|
||||
<%@ page import="org.dspace.content.BitstreamFormat" %>
|
||||
<%@ page import="org.dspace.content.Bundle" %>
|
||||
<%@ page import="org.dspace.core.ConfigurationManager" %>
|
||||
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
|
||||
@@ -46,6 +47,7 @@
|
||||
boolean showChecksums = ((Boolean) request.getAttribute("show.checksums")).booleanValue();
|
||||
|
||||
request.setAttribute("LanguageSwitch", "hide");
|
||||
boolean allowFileEditing = !subInfo.isInWorkflow() || ConfigurationManager.getBooleanProperty("workflow", "reviewer.file-edit");
|
||||
%>
|
||||
|
||||
<dspace:layout locbar="off" navbar="off" titlekey="jsp.submit.upload-file-list.title">
|
||||
@@ -90,7 +92,7 @@
|
||||
}
|
||||
|
||||
// Don't display last column ("Remove") in workflow mode
|
||||
if (!subInfo.isInWorkflow())
|
||||
if (allowFileEditing)
|
||||
{
|
||||
// Whether it's an odd or even column depends on whether we're showing checksums
|
||||
String column = (showChecksums ? "Even" : "Odd");
|
||||
@@ -163,7 +165,7 @@
|
||||
}
|
||||
|
||||
// Don't display "remove" button in workflow mode
|
||||
if (!subInfo.isInWorkflow())
|
||||
if (allowFileEditing)
|
||||
{
|
||||
// Whether it's an odd or even column depends on whether we're showing checksums
|
||||
String column = (showChecksums ? "Even" : "Odd");
|
||||
@@ -188,7 +190,7 @@
|
||||
<%-- Show information about how to verify correct upload, but not in workflow
|
||||
mode! --%>
|
||||
<%
|
||||
if (!subInfo.isInWorkflow())
|
||||
if (allowFileEditing)
|
||||
{
|
||||
%>
|
||||
<p class="uploadHelp"><fmt:message key="jsp.submit.upload-file-list.info3"/></p>
|
||||
@@ -223,7 +225,7 @@
|
||||
<center>
|
||||
<%
|
||||
// Don't allow files to be added in workflow mode
|
||||
if (!subInfo.isInWorkflow())
|
||||
if (allowFileEditing)
|
||||
{
|
||||
%>
|
||||
<p><input type="submit" name="submit_more" value="<fmt:message key="jsp.submit.upload-file-list.button4"/>" /></p>
|
||||
|
@@ -488,17 +488,23 @@ public class FlowContainerUtils
|
||||
}
|
||||
|
||||
private static Group getXMLWorkflowRole(Context context, int collectionID, String roleName, Collection collection, Group roleGroup) throws IOException, WorkflowConfigurationException, SQLException, AuthorizeException {
|
||||
Role role = WorkflowUtils.getCollectionRoles(collection).get(roleName);
|
||||
if(role.getScope() == Role.Scope.COLLECTION){
|
||||
Role role = WorkflowUtils.getCollectionAndRepositoryRoles(collection).get(roleName);
|
||||
if(role.getScope() == Role.Scope.COLLECTION || role.getScope() == Role.Scope.REPOSITORY){
|
||||
roleGroup = WorkflowUtils.getRoleGroup(context, collectionID, role);
|
||||
if(roleGroup == null){
|
||||
AuthorizeManager.authorizeAction(context, collection, Constants.WRITE);
|
||||
roleGroup = Group.create(context);
|
||||
roleGroup.setName("COLLECTION_" + collection.getID() + "_WORKFLOW_ROLE_" + roleName);
|
||||
if(role.getScope() == Role.Scope.COLLECTION){
|
||||
roleGroup.setName("COLLECTION_" + collection.getID() + "_WORKFLOW_ROLE_" + roleName);
|
||||
}else{
|
||||
roleGroup.setName(role.getName());
|
||||
}
|
||||
roleGroup.update();
|
||||
AuthorizeManager.addPolicy(context, collection, Constants.ADD, roleGroup);
|
||||
WorkflowUtils.createCollectionWorkflowRole(context, collectionID, roleName, roleGroup);
|
||||
}
|
||||
if(role.getScope() == Role.Scope.COLLECTION){
|
||||
WorkflowUtils.createCollectionWorkflowRole(context, collectionID, roleName, roleGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
return roleGroup;
|
||||
}
|
||||
@@ -513,8 +519,8 @@ public class FlowContainerUtils
|
||||
* @param groupID The id of the group associated with this role.
|
||||
* @return A process result's object.
|
||||
*/
|
||||
public static FlowResult processDeleteCollectionRole(Context context, int collectionID, String roleName, int groupID) throws SQLException, UIException, IOException, AuthorizeException
|
||||
{
|
||||
public static FlowResult processDeleteCollectionRole(Context context, int collectionID, String roleName, int groupID) throws SQLException, UIException, IOException, AuthorizeException, WorkflowConfigurationException
|
||||
{
|
||||
FlowResult result = new FlowResult();
|
||||
|
||||
Collection collection = Collection.find(context,collectionID);
|
||||
@@ -530,7 +536,7 @@ public class FlowContainerUtils
|
||||
collection.removeSubmitters();
|
||||
}
|
||||
else{
|
||||
WorkflowUtils.deleteRoleGroup(context, collectionID, roleName);
|
||||
WorkflowUtils.deleteRoleGroup(context, collection, roleName);
|
||||
}
|
||||
// else if (ROLE_WF_STEP1.equals(roleName))
|
||||
// {
|
||||
|
@@ -90,6 +90,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
||||
private static final Message T_label_default_read = message("xmlui.administrative.collection.AssignCollectionRoles.label_default_read");
|
||||
|
||||
private static final Message T_sysadmins_only = message("xmlui.administrative.collection.AssignCollectionRoles.sysadmins_only");
|
||||
private static final Message T_sysadmins_only_repository_role = message("xmlui.administrative.collection.AssignCollectionRoles.repository_role");
|
||||
private static final Message T_not_allowed = message("xmlui.administrative.collection.AssignCollectionRoles.not_allowed");
|
||||
|
||||
|
||||
@@ -116,7 +117,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
||||
HashMap<String, Role> roles = null;
|
||||
|
||||
try {
|
||||
roles = WorkflowUtils.getCollectionRoles(thisCollection);
|
||||
roles = WorkflowUtils.getAllExternalRoles(thisCollection);
|
||||
} catch (WorkflowConfigurationException e) {
|
||||
log.error(LogManager.getHeader(context, "error while getting collection roles", "Collection id: " + thisCollection.getID()));
|
||||
} catch (IOException e) {
|
||||
@@ -361,16 +362,35 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
||||
for(String roleId: roles.keySet()){
|
||||
Role role = roles.get(roleId);
|
||||
|
||||
if (role.getScope() == Role.Scope.COLLECTION) {
|
||||
if (role.getScope() == Role.Scope.COLLECTION || role.getScope() == Role.Scope.REPOSITORY) {
|
||||
tableRow = rolesTable.addRow(Row.ROLE_DATA);
|
||||
tableRow.addCell(Cell.ROLE_HEADER).addContent(role.getName());
|
||||
Group roleGroup = WorkflowUtils.getRoleGroup(context, thisCollection.getID(), role);
|
||||
if (roleGroup != null) {
|
||||
tableRow.addCell().addXref(baseURL + "&submit_edit_wf_role_" + roleId, roleGroup.getName());
|
||||
addAdministratorOnlyButton(tableRow.addCell(), "submit_delete_wf_role_" + roleId, T_delete);
|
||||
if(role.getScope() == Role.Scope.REPOSITORY){
|
||||
if(AuthorizeManager.isAdmin(context)){
|
||||
tableRow.addCell().addXref(baseURL + "&submit_edit_wf_role_" + roleId, roleGroup.getName());
|
||||
}else{
|
||||
Cell cell = tableRow.addCell();
|
||||
cell.addContent(roleGroup.getName());
|
||||
cell.addHighlight("fade").addContent(T_sysadmins_only_repository_role);
|
||||
}
|
||||
}else{
|
||||
tableRow.addCell().addXref(baseURL + "&submit_edit_wf_role_" + roleId, roleGroup.getName());
|
||||
}
|
||||
|
||||
if (role.getScope() == Role.Scope.COLLECTION) {
|
||||
addAdministratorOnlyButton(tableRow.addCell(), "submit_delete_wf_role_" + roleId, T_delete);
|
||||
} else {
|
||||
tableRow.addCell();
|
||||
}
|
||||
} else {
|
||||
tableRow.addCell().addContent(T_no_role);
|
||||
addAdministratorOnlyButton(tableRow.addCell(), "submit_create_wf_role_" + roleId, T_create);
|
||||
if (role.getScope() == Role.Scope.COLLECTION || role.getScope() == Role.Scope.REPOSITORY) {
|
||||
addAdministratorOnlyButton(tableRow.addCell(), "submit_create_wf_role_" + roleId, T_create);
|
||||
} else {
|
||||
tableRow.addCell();
|
||||
}
|
||||
}
|
||||
// help and directions row
|
||||
tableRow = rolesTable.addRow(Row.ROLE_DATA);
|
||||
@@ -379,6 +399,19 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer
|
||||
tableRow.addCell(1,2).addHighlight("fade offset").addContent(role.getDescription());
|
||||
}
|
||||
|
||||
} else {
|
||||
tableRow = rolesTable.addRow(Row.ROLE_DATA);
|
||||
tableRow.addCell(Cell.ROLE_HEADER).addContent(role.getName());
|
||||
|
||||
tableRow.addCell().addContent(T_no_role);
|
||||
tableRow.addCell();
|
||||
|
||||
// help and directions row
|
||||
tableRow = rolesTable.addRow(Row.ROLE_DATA);
|
||||
tableRow.addCell();
|
||||
if (role.getDescription() != null){
|
||||
tableRow.addCell(1,2).addHighlight("fade offset").addContent(role.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -232,7 +232,7 @@ public abstract class AbstractStep extends AbstractDSpaceTransformer
|
||||
HandleUtil.buildHandleTrail(collection,pageMeta,contextPath, true);
|
||||
pageMeta.addTrail().addContent(T_submission_trail);
|
||||
}
|
||||
else if (submission instanceof WorkflowItem)
|
||||
else if (submissionInfo != null && submissionInfo.isInWorkflow())
|
||||
{
|
||||
pageMeta.addMetadata("title").addContent(T_workflow_title);
|
||||
|
||||
|
@@ -37,6 +37,7 @@ import org.dspace.content.BitstreamFormat;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.workflow.WorkflowItem;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@@ -166,7 +167,7 @@ public class UploadStep extends AbstractSubmissionStep
|
||||
Item item = submission.getItem();
|
||||
Collection collection = submission.getCollection();
|
||||
String actionURL = contextPath + "/handle/"+collection.getHandle() + "/submit/" + knot.getId() + ".continue";
|
||||
boolean workflow = submission instanceof WorkflowItem;
|
||||
boolean disableFileEditing = (submissionInfo.isInWorkflow()) && !ConfigurationManager.getBooleanProperty("workflow", "reviewer.file-edit");
|
||||
Bundle[] bundles = item.getBundles("ORIGINAL");
|
||||
Bitstream[] bitstreams = new Bitstream[0];
|
||||
if (bundles.length > 0)
|
||||
@@ -182,7 +183,7 @@ public class UploadStep extends AbstractSubmissionStep
|
||||
|
||||
|
||||
List upload = null;
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Only add the upload capabilities for new item submissions
|
||||
upload = div.addList("submit-upload-new", List.TYPE_FORM);
|
||||
@@ -227,7 +228,7 @@ public class UploadStep extends AbstractSubmissionStep
|
||||
|
||||
// Part B:
|
||||
// If the user has already uploaded files provide a list for the user.
|
||||
if (bitstreams.length > 0 || workflow)
|
||||
if (bitstreams.length > 0 || disableFileEditing)
|
||||
{
|
||||
Table summary = div.addTable("submit-upload-summary",(bitstreams.length * 2) + 2,7);
|
||||
summary.setHead(T_head2);
|
||||
@@ -264,7 +265,7 @@ public class UploadStep extends AbstractSubmissionStep
|
||||
primary.setOptionSelected(String.valueOf(id));
|
||||
}
|
||||
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Workflow users can not remove files.
|
||||
CheckBox remove = row.addCell().addCheckBox("remove");
|
||||
@@ -323,7 +324,7 @@ public class UploadStep extends AbstractSubmissionStep
|
||||
checksumCell.addContent(algorithm + ":" + checksum);
|
||||
}
|
||||
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Workflow users can not remove files.
|
||||
Row actionRow = summary.addRow();
|
||||
|
@@ -159,7 +159,8 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
isAdvancedFormEnabled=ConfigurationManager.getBooleanProperty("xmlui.submission.restrictstep.enableAdvancedForm", false);
|
||||
}
|
||||
|
||||
public void addPageMeta(PageMeta pageMeta) throws WingException{
|
||||
public void addPageMeta(PageMeta pageMeta) throws WingException, AuthorizeException, IOException, SAXException, SQLException {
|
||||
super.addPageMeta(pageMeta);
|
||||
pageMeta.addMetadata("javascript", "static").addContent("static/js/accessFormUtil.js");
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
Item item = submission.getItem();
|
||||
Collection collection = submission.getCollection();
|
||||
String actionURL = contextPath + "/handle/"+collection.getHandle() + "/submit/" + knot.getId() + ".continue";
|
||||
boolean workflow = submission instanceof WorkflowItem;
|
||||
boolean disableFileEditing = (submissionInfo.isInWorkflow()) && !ConfigurationManager.getBooleanProperty("workflow", "reviewer.file-edit");
|
||||
Bundle[] bundles = item.getBundles("ORIGINAL");
|
||||
Bitstream[] bitstreams = new Bitstream[0];
|
||||
if (bundles.length > 0)
|
||||
@@ -202,7 +203,7 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
|
||||
|
||||
List upload = null;
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Only add the upload capabilities for new item submissions
|
||||
upload = div.addList("submit-upload-new", List.TYPE_FORM);
|
||||
@@ -257,7 +258,7 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
|
||||
// Part B:
|
||||
// If the user has already uploaded files provide a list for the user.
|
||||
if (bitstreams.length > 0 || workflow)
|
||||
if (bitstreams.length > 0 || disableFileEditing)
|
||||
{
|
||||
Table summary = div.addTable("submit-upload-summary",(bitstreams.length * 2) + 2,7);
|
||||
summary.setHead(T_head2);
|
||||
@@ -294,7 +295,7 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
primary.setOptionSelected(String.valueOf(id));
|
||||
}
|
||||
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Workflow users can not remove files.
|
||||
CheckBox remove = row.addCell().addCheckBox("remove");
|
||||
@@ -358,7 +359,7 @@ public class UploadWithEmbargoStep extends AbstractSubmissionStep
|
||||
checksumCell.addContent(algorithm + ":" + checksum);
|
||||
}
|
||||
|
||||
if (!workflow)
|
||||
if (!disableFileEditing)
|
||||
{
|
||||
// Workflow users can not remove files.
|
||||
Row actionRow = summary.addRow();
|
||||
|
@@ -1599,6 +1599,7 @@
|
||||
<message key="xmlui.administrative.collection.AssignCollectionRoles.label_submitters">Submitters</message>
|
||||
<message key="xmlui.administrative.collection.AssignCollectionRoles.label_default_read">Default read access</message>
|
||||
<message key="xmlui.administrative.collection.AssignCollectionRoles.sysadmins_only"><nobr>(system administrators only)</nobr></message>
|
||||
<message key="xmlui.administrative.collection.AssignCollectionRoles.repository_role"><br/>(Repository level group, system administrators only)</message>
|
||||
<message key="xmlui.administrative.collection.AssignCollectionRoles.not_allowed"><nobr>(you are not allowed to configure this)</nobr></message>
|
||||
|
||||
<!-- org.dspace.app.xmlui.administrative.collection.CurateCollectionForm.java -->
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<!ATTLIST form name NMTOKEN #REQUIRED>
|
||||
<!ELEMENT page (field)+ >
|
||||
<!ATTLIST page number NMTOKEN #REQUIRED>
|
||||
<!ELEMENT field (dc-schema, dc-element, dc-qualifier?, repeatable?, label, input-type, hint, required?, vocabulary?) >
|
||||
<!ELEMENT field (dc-schema, dc-element, dc-qualifier?, repeatable?, label, input-type, hint, required?, vocabulary?, visibility?) >
|
||||
<!ELEMENT dc-schema (#PCDATA) >
|
||||
<!ELEMENT dc-element (#PCDATA) >
|
||||
<!ELEMENT dc-qualifier (#PCDATA) >
|
||||
@@ -51,3 +51,5 @@
|
||||
<!ELEMENT vocabulary (#PCDATA) >
|
||||
|
||||
<!ATTLIST vocabulary closed (true|false) "false">
|
||||
|
||||
<!ELEMENT visibility (#PCDATA) >
|
||||
|
@@ -10,3 +10,7 @@
|
||||
# xmlworkflow = New (as of 1.8.0) Configurable Reviewer Workflow
|
||||
workflow.framework=originalworkflow
|
||||
#workflow.framework=xmlworkflow
|
||||
|
||||
#Allow the reviewers to add/edit/remove files from the submission
|
||||
#When changing this property you might want to alert submitters in the license that reviewers can alter their files
|
||||
reviewer.file-edit=false
|
Reference in New Issue
Block a user