Merge branch 'master' of https://github.com/DSpace/DSpace into resourcepolicy-DS-4418

This commit is contained in:
Mykhaylo
2020-03-02 09:44:50 +01:00
95 changed files with 3119 additions and 363 deletions

View File

@@ -367,7 +367,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
@Override @Override
public void setWorkflowGroup(Context context, Collection collection, int step, Group group) public void setWorkflowGroup(Context context, Collection collection, int step, Group group)
throws SQLException, AuthorizeException { throws SQLException {
Workflow workflow = null; Workflow workflow = null;
try { try {
workflow = workflowFactory.getWorkflow(collection); workflow = workflowFactory.getWorkflow(collection);
@@ -889,4 +889,4 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
throws SQLException { throws SQLException {
return collectionDAO.getCollectionsWithBitstreamSizesTotal(context); return collectionDAO.getCollectionsWithBitstreamSizesTotal(context);
} }
} }

View File

@@ -7,29 +7,53 @@
*/ */
package org.dspace.xmlworkflow; package org.dspace.xmlworkflow;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.handle.service.HandleService;
import org.dspace.utils.DSpace;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.Workflow;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Required;
/** /**
* The workflowfactory is responsible for parsing the * The workflowfactory is responsible for parsing the workflow xml file and is used to retrieve info about the workflow:
* workflow xml file and is used to retrieve the workflow for * - the workflow for a certain collection
* a certain collection * - collections mapped to a certain workflow
* - collections not mapped to any workflow
* - configured workflows and the default workflow
* - workflow action by name
* *
* @author Bram De Schouwer (bram.deschouwer at dot com) * @author Bram De Schouwer (bram.deschouwer at dot com)
* @author Kevin Van de Velde (kevin at atmire dot com) * @author Kevin Van de Velde (kevin at atmire dot com)
* @author Ben Bosman (ben at atmire dot com) * @author Ben Bosman (ben at atmire dot com)
* @author Mark Diggory (markd at atmire dot com) * @author Mark Diggory (markd at atmire dot com)
* @author Maria Verdonck (Atmire) on 11/12/2019
*/ */
public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory { public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
public static final String LEGACY_WORKFLOW_NAME = "defaultWorkflow"; public static final String LEGACY_WORKFLOW_NAME = "defaultWorkflow";
private Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowFactoryImpl.class);
private Map<String, Workflow> workflowMapping; private Map<String, Workflow> workflowMapping;
@Autowired
protected CollectionService collectionService;
@Autowired
protected HandleService handleService;
@Override @Override
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException { public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException {
// Attempt to retrieve our workflow object // Attempt to retrieve our workflow object
@@ -50,4 +74,93 @@ public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
public void setWorkflowMapping(Map<String, Workflow> workflowMapping) { public void setWorkflowMapping(Map<String, Workflow> workflowMapping) {
this.workflowMapping = workflowMapping; this.workflowMapping = workflowMapping;
} }
}
@Override
public Workflow getWorkflowByName(String workflowName) throws WorkflowConfigurationException {
for (Workflow workflow : workflowMapping.values()) {
if (workflow.getID().equals(workflowName)) {
return workflow;
}
}
throw new WorkflowConfigurationException(
"Error while retrieving workflow by the following name: " + workflowName);
}
@Override
public Workflow getDefaultWorkflow() {
return this.workflowMapping.get(LEGACY_WORKFLOW_NAME);
}
@Override
public List<Workflow> getAllConfiguredWorkflows() {
return new ArrayList<>(this.workflowMapping.values());
}
@Override
public List<Collection> getCollectionHandlesMappedToWorklow(Context context, String workflowName) {
List<Collection> collectionsMapped = new ArrayList<>();
for (String handle : this.workflowMapping.keySet()) {
if (this.workflowMapping.get(handle).getID().equals(workflowName)) {
try {
Collection collection = (Collection) handleService.resolveToObject(context, handle);
if (collection != null) {
collectionsMapped.add(collection);
}
} catch (SQLException e) {
log.error("SQLException in XmlWorkflowFactoryImpl.getCollectionHandlesMappedToWorklow trying to " +
"retrieve collection with handle: " + handle, e);
}
}
}
return collectionsMapped;
}
@Override
public List<Collection> getAllNonMappedCollectionsHandles(Context context) {
List<Collection> nonMappedCollections = new ArrayList<>();
try {
for (Collection collection : this.collectionService.findAll(context)) {
if (workflowMapping.get(collection.getHandle()) == null) {
nonMappedCollections.add(collection);
}
}
} catch (SQLException e) {
log.error("SQLException in XmlWorkflowFactoryImpl.getAllNonMappedCollectionsHandles trying to " +
"retrieve all collections", e);
}
return nonMappedCollections;
}
@Override
public boolean workflowByThisNameExists(String workflowName) {
for (Workflow workflow : this.workflowMapping.values()) {
if (workflow.getID().equals(workflowName)) {
return true;
}
}
return false;
}
@Override
public boolean isDefaultWorkflow(String workflowName) {
if (StringUtils.isNotBlank(workflowName)) {
Workflow defaultWorkflow = this.getDefaultWorkflow();
if (defaultWorkflow != null && StringUtils.isNotBlank(defaultWorkflow.getID())) {
return (defaultWorkflow.getID().equals(workflowName));
}
}
return false;
}
@Override
public WorkflowActionConfig getActionByName(String workflowActionName) {
return new DSpace().getServiceManager().getServiceByName(workflowActionName, WorkflowActionConfig.class);
}
@Override
public Step getStepByName(String workflowStepName) {
return new DSpace().getServiceManager().getServiceByName(workflowStepName, Step.class);
}
}

View File

@@ -7,23 +7,31 @@
*/ */
package org.dspace.xmlworkflow.factory; package org.dspace.xmlworkflow.factory;
import java.util.List;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.Workflow;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
/** /**
* The xmlworkflowfactory is responsible for parsing the * The workflowfactory is responsible for parsing the workflow xml file and is used to retrieve info about the workflow:
* workflow xml file and is used to retrieve the workflow for * - the workflow for a certain collection
* a certain collection * - collections mapped to a certain workflow
* - collections not mapped to any workflow
* - configured workflows and the default workflow
* - workflow action by name
* *
* @author Bram De Schouwer (bram.deschouwer at dot com) * @author Bram De Schouwer (bram.deschouwer at dot com)
* @author Kevin Van de Velde (kevin at atmire dot com) * @author Kevin Van de Velde (kevin at atmire dot com)
* @author Ben Bosman (ben at atmire dot com) * @author Ben Bosman (ben at atmire dot com)
* @author Mark Diggory (markd at atmire dot com) * @author Mark Diggory (markd at atmire dot com)
* @author Maria Verdonck (Atmire) on 11/12/2019
*/ */
public interface XmlWorkflowFactory { public interface XmlWorkflowFactory {
/** /**
* Retrieve the workflow configuration for a single collection * Retrieve the workflow configuration for a single collection
* *
@@ -32,4 +40,74 @@ public interface XmlWorkflowFactory {
* @throws WorkflowConfigurationException occurs if there is a configuration error in the workflow * @throws WorkflowConfigurationException occurs if there is a configuration error in the workflow
*/ */
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException; public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException;
/**
* Retrieves the workflow configuration by name
*
* @param workflowName the name for which we want our workflow
* @return the workflow configuration
* @throws WorkflowConfigurationException occurs if there is no workflow configured by that name
*/
public Workflow getWorkflowByName(String workflowName) throws WorkflowConfigurationException;
/**
* Creates a list of all configured workflows, or returns the cache of this if it was already created
*
* @return List of all configured workflows
*/
public List<Workflow> getAllConfiguredWorkflows();
/**
* Check to see if there is a workflow configured by the given name
*
* @param workflowName Name of a possible configured workflow
* @return True if there is a workflow configured by this name, false otherwise
*/
public boolean workflowByThisNameExists(String workflowName);
/**
* Check to see if the given workflowName is the workflow configured to be default for collections
*
* @param workflowName Name of workflow to check if default
* @return True if given workflowName is the workflow mapped to default for collections, otherwise false
*/
public boolean isDefaultWorkflow(String workflowName);
/**
* Gets the default workflow, i.e. the workflow that is mapped to collection=default in workflow.xml
*/
public Workflow getDefaultWorkflow();
/**
* Return a list of collections that are mapped to the given workflow in the workflow configuration.
* * Makes use of a cache so it only retrieves the workflowName->List<collectionHandle> if it's not cached
*
* @param context Dspace context
* @param workflowName Name of workflow we want the collections of that are mapped to is
* @return List of collections mapped to the requested workflow
*/
public List<Collection> getCollectionHandlesMappedToWorklow(Context context, String workflowName);
/**
* Returns list of collections that are not mapped to any configured workflow, and thus use the default workflow
*
* @return List of collections not mapped to any workflow
*/
public List<Collection> getAllNonMappedCollectionsHandles(Context context);
/**
* Retrieves a {@link WorkflowActionConfig} object based on its name, should correspond with bean id in workflow-actions.xml
*
* @param workflowActionName Name of workflow action we want to retrieve
* @return Workflow action object corresponding to the given workflowActionName
*/
public WorkflowActionConfig getActionByName(String workflowActionName);
/**
* Retrieves a {@link Step} object based on its name, should correspond with bean id in workflow.xml
*
* @param workflowStepName Name of workflow step we want to retrieve
* @return Workflow step object corresponding to the given workflowStepName
*/
public Step getStepByName(String workflowStepName);
} }

View File

@@ -36,8 +36,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
public abstract class Action { public abstract class Action {
private WorkflowActionConfig parent; private WorkflowActionConfig parent;
private static String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields"; private static final String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields";
public abstract void activate(Context c, XmlWorkflowItem wf) public abstract void activate(Context c, XmlWorkflowItem wf)
throws SQLException, IOException, AuthorizeException, WorkflowException; throws SQLException, IOException, AuthorizeException, WorkflowException;
@@ -45,6 +44,12 @@ public abstract class Action {
public abstract ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public abstract ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException; throws SQLException, AuthorizeException, IOException, WorkflowException;
/**
* Returns a list of options that the user can select at this action which results in the next step in the workflow
* @return A list of options of this action, resulting in the next step of the workflow
*/
public abstract List<String> getOptions();
public WorkflowActionConfig getParent() { public WorkflowActionConfig getParent() {
return parent; return parent;
} }

View File

@@ -7,6 +7,8 @@
*/ */
package org.dspace.xmlworkflow.state.actions; package org.dspace.xmlworkflow.state.actions;
import java.util.List;
import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Step;
/** /**
@@ -59,4 +61,12 @@ public class WorkflowActionConfig {
return step; return step;
} }
/**
* Returns a list of options the user has on this action, resulting in the next step of the workflow
* @return A list of options of this action, resulting in the next step of the workflow
*/
public List<String> getOptions() {
return this.processingAction.getOptions();
}
} }

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -31,40 +33,49 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/ */
public class AcceptEditRejectAction extends ProcessingAction { public class AcceptEditRejectAction extends ProcessingAction {
public static final int MAIN_PAGE = 0; private static final String SUBMIT_APPROVE = "submit_approve";
public static final int REJECT_PAGE = 1; private static final String SUBMIT_REJECT = "submit_reject";
//TODO: rename to AcceptAndEditMetadataAction //TODO: rename to AcceptAndEditMetadataAction
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException { public void activate(Context c, XmlWorkflowItem wf) {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
if (request.getParameter("submit_approve") != null) { if (request.getParameter(SUBMIT_APPROVE) != null) {
return processAccept(c, wfi, step, request); return processAccept(c, wfi);
} else { } else {
if (request.getParameter("submit_reject") != null) { if (request.getParameter(SUBMIT_REJECT) != null) {
return processRejectPage(c, wfi, step, request); return processRejectPage(c, wfi, request);
} }
} }
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL); return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
} }
public ActionResult processAccept(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) @Override
throws SQLException, AuthorizeException { public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
options.add(ProcessingAction.SUBMIT_EDIT_METADATA);
return options;
}
public ActionResult processAccept(Context c, XmlWorkflowItem wfi)
throws SQLException, AuthorizeException {
//Delete the tasks //Delete the tasks
addApprovedProvenance(c, wfi); addApprovedProvenance(c, wfi);
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
String reason = request.getParameter("reason"); String reason = request.getParameter("reason");
if (reason == null || 0 == reason.trim().length()) { if (reason == null || 0 == reason.trim().length()) {
addErrorField(request, "reason"); addErrorField(request, "reason");
@@ -85,14 +96,14 @@ public class AcceptEditRejectAction extends ProcessingAction {
// Get user's name + email address // Get user's name + email address
String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService()
.getEPersonName(c.getCurrentUser()); .getEPersonName(c.getCurrentUser());
String provDescription = getProvenanceStartId() + " Approved for entry into archive by " String provDescription = getProvenanceStartId() + " Approved for entry into archive by "
+ usersName + " on " + now + " (GMT) "; + usersName + " on " + now + " (GMT) ";
// Add to item as a DC field // Add to item as a DC field
itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en", itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en",
provDescription); provDescription);
itemService.update(c, wfi.getItem()); itemService.update(c, wfi.getItem());
} }
} }

View File

@@ -7,8 +7,9 @@
*/ */
package org.dspace.xmlworkflow.state.actions.processingaction; package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -31,21 +32,22 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/ */
public class FinalEditAction extends ProcessingAction { public class FinalEditAction extends ProcessingAction {
private static final String SUBMIT_APPROVE = "submit_approve";
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException { public void activate(Context c, XmlWorkflowItem wf) {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException {
return processMainPage(c, wfi, step, request); return processMainPage(c, wfi, step, request);
} }
public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
if (request.getParameter("submit_approve") != null) { if (request.getParameter(SUBMIT_APPROVE) != null) {
//Delete the tasks //Delete the tasks
addApprovedProvenance(c, wfi); addApprovedProvenance(c, wfi);
@@ -56,20 +58,28 @@ public class FinalEditAction extends ProcessingAction {
} }
} }
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(ProcessingAction.SUBMIT_EDIT_METADATA);
return options;
}
private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException {
//Add the provenance for the accept //Add the provenance for the accept
String now = DCDate.getCurrent().toString(); String now = DCDate.getCurrent().toString();
// Get user's name + email address // Get user's name + email address
String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService()
.getEPersonName(c.getCurrentUser()); .getEPersonName(c.getCurrentUser());
String provDescription = getProvenanceStartId() + " Approved for entry into archive by " String provDescription = getProvenanceStartId() + " Approved for entry into archive by "
+ usersName + " on " + now + " (GMT) "; + usersName + " on " + now + " (GMT) ";
// Add to item as a DC field // Add to item as a DC field
itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en", itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en",
provDescription); provDescription);
itemService.update(c, wfi.getItem()); itemService.update(c, wfi.getItem());
} }

View File

@@ -34,6 +34,7 @@ public abstract class ProcessingAction extends Action {
@Autowired(required = true) @Autowired(required = true)
protected ItemService itemService; protected ItemService itemService;
protected static final String SUBMIT_EDIT_METADATA = "submit_edit_metadata";
@Override @Override
public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException { public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException {

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -34,6 +36,8 @@ public class ReviewAction extends ProcessingAction {
public static final int MAIN_PAGE = 0; public static final int MAIN_PAGE = 0;
public static final int REJECT_PAGE = 1; public static final int REJECT_PAGE = 1;
private static final String SUBMIT_APPROVE = "submit_approve";
private static final String SUBMIT_REJECT = "submit_reject";
@Override @Override
public void activate(Context c, XmlWorkflowItem wfItem) { public void activate(Context c, XmlWorkflowItem wfItem) {
@@ -43,10 +47,10 @@ public class ReviewAction extends ProcessingAction {
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException { throws SQLException, AuthorizeException, IOException {
if (request.getParameter("submit_approve") != null) { if (request.getParameter(SUBMIT_APPROVE) != null) {
return processAccept(c, wfi, step, request); return processAccept(c, wfi, step, request);
} else { } else {
if (request.getParameter("submit_reject") != null) { if (request.getParameter(SUBMIT_REJECT) != null) {
return processRejectPage(c, wfi, step, request); return processRejectPage(c, wfi, step, request);
} }
} }
@@ -54,6 +58,14 @@ public class ReviewAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL); return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
} }
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
return options;
}
public ActionResult processAccept(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult processAccept(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
//Delete the tasks //Delete the tasks

View File

@@ -9,6 +9,7 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -17,7 +18,6 @@ import org.dspace.content.Item;
import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.MetadataSchemaEnum;
import org.dspace.content.MetadataValue; import org.dspace.content.MetadataValue;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.service.WorkflowRequirementsService;
import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Step;
@@ -40,14 +40,13 @@ public class ScoreEvaluationAction extends ProcessingAction {
private int minimumAcceptanceScore; private int minimumAcceptanceScore;
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) public void activate(Context c, XmlWorkflowItem wf) {
throws SQLException, IOException, AuthorizeException, WorkflowException {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException { throws SQLException, AuthorizeException, IOException {
boolean hasPassed = false; boolean hasPassed = false;
//Retrieve all our scores from the metadata & add em up //Retrieve all our scores from the metadata & add em up
List<MetadataValue> scores = itemService List<MetadataValue> scores = itemService
@@ -82,6 +81,11 @@ public class ScoreEvaluationAction extends ProcessingAction {
} }
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
public int getMinimumAcceptanceScore() { public int getMinimumAcceptanceScore() {
return minimumAcceptanceScore; return minimumAcceptanceScore;
} }

View File

@@ -7,14 +7,14 @@
*/ */
package org.dspace.xmlworkflow.state.actions.processingaction; package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.app.util.Util; import org.dspace.app.util.Util;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.service.WorkflowRequirementsService;
import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.ActionResult;
@@ -32,20 +32,21 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/ */
public class ScoreReviewAction extends ProcessingAction { public class ScoreReviewAction extends ProcessingAction {
private static final String SUBMIT_SCORE = "submit_score";
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) public void activate(Context c, XmlWorkflowItem wf) {
throws SQLException, IOException, AuthorizeException, WorkflowException {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException { throws SQLException, AuthorizeException {
if (request.getParameter("submit_score") != null) { if (request.getParameter(SUBMIT_SCORE) != null) {
int score = Util.getIntParameter(request, "score"); int score = Util.getIntParameter(request, "score");
//Add our score to the metadata //Add our score to the metadata
itemService.addMetadata(c, wfi.getItem(), WorkflowRequirementsService.WORKFLOW_SCHEMA, "score", null, null, itemService.addMetadata(c, wfi.getItem(), WorkflowRequirementsService.WORKFLOW_SCHEMA, "score", null, null,
String.valueOf(score)); String.valueOf(score));
itemService.update(c, wfi.getItem()); itemService.update(c, wfi.getItem());
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
@@ -54,4 +55,9 @@ public class ScoreReviewAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE);
} }
} }
@Override
public List<String> getOptions() {
return Arrays.asList(SUBMIT_SCORE);
}
} }

View File

@@ -7,8 +7,8 @@
*/ */
package org.dspace.xmlworkflow.state.actions.processingaction; package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -18,7 +18,6 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.EPersonService;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.Role;
import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.ActionResult;
@@ -39,36 +38,38 @@ import org.springframework.beans.factory.annotation.Required;
*/ */
public class SelectReviewerAction extends ProcessingAction { public class SelectReviewerAction extends ProcessingAction {
public static final int MAIN_PAGE = 0;
public static final int SEARCH_RESULTS_PAGE = 1; public static final int SEARCH_RESULTS_PAGE = 1;
public static final int RESULTS_PER_PAGE = 5; public static final int RESULTS_PER_PAGE = 5;
private static final String SUBMIT_CANCEL = "submit_cancel";
private static final String SUBMIT_SEARCH = "submit_search";
private static final String SUBMIT_SELECT_REVIEWER = "submit_select_reviewer_";
private Role role; private Role role;
@Autowired(required = true) @Autowired(required = true)
protected EPersonService ePersonService; private EPersonService ePersonService;
@Autowired(required = true) @Autowired(required = true)
protected WorkflowItemRoleService workflowItemRoleService; private WorkflowItemRoleService workflowItemRoleService;
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) public void activate(Context c, XmlWorkflowItem wf) {
throws SQLException, IOException, AuthorizeException, WorkflowException {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException { throws SQLException, AuthorizeException {
String submitButton = Util.getSubmitButton(request, "submit_cancel"); String submitButton = Util.getSubmitButton(request, SUBMIT_CANCEL);
//Check if our user has pressed cancel //Check if our user has pressed cancel
if (submitButton.equals("submit_cancel")) { if (submitButton.equals(SUBMIT_CANCEL)) {
//Send us back to the submissions page //Send us back to the submissions page
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL); return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
} else if (submitButton.equals("submit_search")) { } else if (submitButton.equals(SUBMIT_SEARCH)) {
//Perform the search //Perform the search
String query = request.getParameter("query"); String query = request.getParameter("query");
int page = Util.getIntParameter(request, "result-page"); int page = Util.getIntParameter(request, "result-page");
@@ -85,7 +86,7 @@ public class SelectReviewerAction extends ProcessingAction {
request.setAttribute("result-page", page); request.setAttribute("result-page", page);
request.setAttribute("page", SEARCH_RESULTS_PAGE); request.setAttribute("page", SEARCH_RESULTS_PAGE);
return new ActionResult(ActionResult.TYPE.TYPE_PAGE, SEARCH_RESULTS_PAGE); return new ActionResult(ActionResult.TYPE.TYPE_PAGE, SEARCH_RESULTS_PAGE);
} else if (submitButton.startsWith("submit_select_reviewer_")) { } else if (submitButton.startsWith(SUBMIT_SELECT_REVIEWER)) {
//Retrieve the identifier of the eperson which will do the reviewing //Retrieve the identifier of the eperson which will do the reviewing
UUID reviewerId = UUID.fromString(submitButton.substring(submitButton.lastIndexOf("_") + 1)); UUID reviewerId = UUID.fromString(submitButton.substring(submitButton.lastIndexOf("_") + 1));
EPerson reviewer = ePersonService.find(c, reviewerId); EPerson reviewer = ePersonService.find(c, reviewerId);
@@ -102,6 +103,14 @@ public class SelectReviewerAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_ERROR); return new ActionResult(ActionResult.TYPE.TYPE_ERROR);
} }
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_SEARCH);
options.add(SUBMIT_SELECT_REVIEWER);
return options;
}
public Role getRole() { public Role getRole() {
return role; return role;
} }

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.app.util.Util; import org.dspace.app.util.Util;
@@ -38,6 +40,10 @@ public class SingleUserReviewAction extends ProcessingAction {
public static final int OUTCOME_REJECT = 1; public static final int OUTCOME_REJECT = 1;
protected static final String SUBMIT_APPROVE = "submit_approve";
protected static final String SUBMIT_REJECT = "submit_reject";
protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task";
@Override @Override
public void activate(Context c, XmlWorkflowItem wfItem) { public void activate(Context c, XmlWorkflowItem wfItem) {
@@ -58,19 +64,28 @@ public class SingleUserReviewAction extends ProcessingAction {
} }
} }
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
options.add(SUBMIT_DECLINE_TASK);
return options;
}
public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException { throws SQLException, AuthorizeException {
if (request.getParameter("submit_approve") != null) { if (request.getParameter(SUBMIT_APPROVE) != null) {
//Delete the tasks //Delete the tasks
addApprovedProvenance(c, wfi); addApprovedProvenance(c, wfi);
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} else if (request.getParameter("submit_reject") != null) { } else if (request.getParameter(SUBMIT_REJECT) != null) {
// Make sure we indicate which page we want to process // Make sure we indicate which page we want to process
request.setAttribute("page", REJECT_PAGE); request.setAttribute("page", REJECT_PAGE);
// We have pressed reject item, so take the user to a page where he can reject // We have pressed reject item, so take the user to a page where he can reject
return new ActionResult(ActionResult.TYPE.TYPE_PAGE); return new ActionResult(ActionResult.TYPE.TYPE_PAGE);
} else if (request.getParameter("submit_decline_task") != null) { } else if (request.getParameter(SUBMIT_DECLINE_TASK) != null) {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, OUTCOME_REJECT); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, OUTCOME_REJECT);
} else { } else {

View File

@@ -8,6 +8,8 @@
package org.dspace.xmlworkflow.state.actions.userassignment; package org.dspace.xmlworkflow.state.actions.userassignment;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -34,6 +36,11 @@ public class AssignAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
public void generateTasks() { public void generateTasks() {
} }

View File

@@ -9,7 +9,9 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -112,6 +114,11 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
/** /**
* Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item * Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item
* *

View File

@@ -9,6 +9,7 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -106,6 +107,11 @@ public class AutoAssignAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
/** /**
* Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item * Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item
* *

View File

@@ -10,6 +10,7 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -67,6 +68,11 @@ public class ClaimAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
@Override @Override
public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers)
throws IOException, SQLException { throws IOException, SQLException {

View File

@@ -8,6 +8,8 @@
package org.dspace.xmlworkflow.state.actions.userassignment; package org.dspace.xmlworkflow.state.actions.userassignment;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -37,6 +39,11 @@ public class InheritUsersAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
@Override @Override
public boolean isFinished(XmlWorkflowItem wfi) { public boolean isFinished(XmlWorkflowItem wfi) {
return false; return false;

View File

@@ -7,14 +7,12 @@
*/ */
package org.dspace.xmlworkflow.state.actions.userassignment; package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException; import java.util.ArrayList;
import java.sql.SQLException; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.RoleMembers;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.ActionResult;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
@@ -34,12 +32,11 @@ public class NoUserSelectionAction extends UserSelectionAction {
} }
@Override @Override
public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) {
} }
@Override @Override
public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) {
throws WorkflowConfigurationException, SQLException {
return true; return true;
} }
@@ -49,12 +46,16 @@ public class NoUserSelectionAction extends UserSelectionAction {
} }
@Override @Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException, IOException { public void activate(Context c, XmlWorkflowItem wf) {
} }
@Override @Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) {
throws SQLException, AuthorizeException, IOException {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} }
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
} }

View File

@@ -0,0 +1,99 @@
<?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-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="claimactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.ClaimAction" scope="prototype"/>
<bean id="reviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ReviewAction" scope="prototype"/>
<bean id="editactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.AcceptEditRejectAction" scope="prototype"/>
<bean id="finaleditactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.FinalEditAction" scope="prototype"/>
<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="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">
<property name="minimumAcceptanceScore" value="50" />
</bean>
<bean id="autoassignactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AutoAssignAction" scope="prototype"/>
<bean id="noUserSelectionActionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.NoUserSelectionAction" scope="prototype"/>
<bean id="assignoriginalsubmitteractionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AssignOriginalSubmitterAction" scope="prototype"/>
<bean id="reviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="reviewaction"/>
<property name="processingAction" ref="reviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="editaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="editaction"/>
<property name="processingAction" ref="editactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="finaleditaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="finaleditaction"/>
<property name="processingAction" ref="finaleditactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<!--Action for the select single reviewer workflow -->
<bean id="selectrevieweraction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="selectrevieweraction"/>
<property name="processingAction" ref="selectrevieweractionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="singleuserreviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="singleuserreviewaction"/>
<property name="processingAction" ref="singleuserreviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="scorereviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="scorereviewaction"/>
<property name="processingAction" ref="scorereviewactionAPI" />
<property name="requiresUI" value="true"/>
</bean>
<!--Autmatic step that evaluates scores (workflow.score) and checks if they match the configured minimum for archiving -->
<bean id="evaluationaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="evaluationaction"/>
<property name="processingAction" ref="evaluationactionAPI" />
<property name="requiresUI" value="false"/>
</bean>
<!--User selection actions-->
<bean id="claimaction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="claimaction"/>
<property name="processingAction" ref="claimactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="autoassignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="autoassignAction"/>
<property name="processingAction" ref="autoassignactionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="noUserSelectionAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="noUserSelectionAction"/>
<property name="processingAction" ref="noUserSelectionActionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="originalSubmitterAssignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value=""/>
<property name="processingAction" ref="assignoriginalsubmitteractionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
</beans>

View File

@@ -9,8 +9,8 @@
<util:map> <util:map>
<entry key="defaultWorkflow" <entry key="defaultWorkflow"
value-ref="defaultWorkflow"/> value-ref="defaultWorkflow"/>
<entry key="123456789/4" value-ref="selectSingleReviewer"/> <entry key="123456789/workflow-test-1" value-ref="selectSingleReviewer"/>
<!-- <entry key="123456789/5" value-ref="scoreReview"/>--> <!-- <entry key="123456789/5" value-ref="scoreReview"/>-->
</util:map> </util:map>
</property> </property>
</bean> </bean>

View File

@@ -25,6 +25,7 @@ import org.dspace.utils.DSpace;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.Workflow;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -42,6 +43,8 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
= new DSpace().getServiceManager().getServiceByName("xmlWorkflowFactory", = new DSpace().getServiceManager().getServiceByName("xmlWorkflowFactory",
XmlWorkflowFactoryImpl.class); XmlWorkflowFactoryImpl.class);
private Community owningCommunity; private Community owningCommunity;
private Collection mappedCollection;
private Collection nonMappedCollection;
/** /**
* log4j category * log4j category
@@ -63,6 +66,9 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
//we have to create a new community in the database //we have to create a new community in the database
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
this.owningCommunity = communityService.create(null, context); this.owningCommunity = communityService.create(null, context);
this.mappedCollection =
this.collectionService.create(context, owningCommunity, "123456789/workflow-test-1");
this.nonMappedCollection = this.collectionService.create(context, owningCommunity, "123456789/999");
//we need to commit the changes so we don't block the table for testing //we need to commit the changes so we don't block the table for testing
context.restoreAuthSystemState(); context.restoreAuthSystemState();
} catch (SQLException e) { } catch (SQLException e) {
@@ -74,38 +80,46 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
} }
} }
/**
* This method will be run after every test as per @After. It will
* clean resources initialized by the @Before methods.
*
* Other methods can be annotated with @After here or in subclasses
* but no execution order is guaranteed
*/
@After
@Override
public void destroy() {
context.turnOffAuthorisationSystem();
try {
this.collectionService.delete(context, this.nonMappedCollection);
this.collectionService.delete(context, this.mappedCollection);
this.communityService.delete(context, this.owningCommunity);
} catch (Exception e) {
log.error("Error in destroy", e);
}
context.restoreAuthSystemState();
this.owningCommunity = null;
this.nonMappedCollection = null;
this.mappedCollection = null;
try {
super.destroy();
} catch (Exception e) {
log.error("Error in destroy", e);
}
}
@Test @Test
public void workflowMapping_NonMappedCollection() throws WorkflowConfigurationException { public void workflowMapping_NonMappedCollection() throws WorkflowConfigurationException {
Collection collection = this.findOrCreateCollectionWithHandle("123456789/6"); Workflow workflow = xmlWorkflowFactory.getWorkflow(this.nonMappedCollection);
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection); assertEquals(workflow.getID(), "defaultWorkflow");
assertEquals("defaultWorkflow", workflow.getID());
} }
@Test @Test
public void workflowMapping_MappedCollection() throws WorkflowConfigurationException { public void workflowMapping_MappedCollection() throws WorkflowConfigurationException {
Collection collection = this.findOrCreateCollectionWithHandle("123456789/4"); Workflow workflow = xmlWorkflowFactory.getWorkflow(this.mappedCollection);
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection); assertEquals(workflow.getID(), "selectSingleReviewer");
assertEquals("selectSingleReviewer", workflow.getID());
}
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;
} }
} }

View File

@@ -15,7 +15,7 @@
<properties> <properties>
<!-- This is the path to the root [dspace-src] directory. --> <!-- This is the path to the root [dspace-src] directory. -->
<root.basedir>${basedir}/..</root.basedir> <root.basedir>${basedir}/..</root.basedir>
<xoai.version>3.2.11</xoai.version> <xoai.version>3.3.0</xoai.version>
<jtwig.version>5.87.0.RELEASE</jtwig.version> <jtwig.version>5.87.0.RELEASE</jtwig.version>
</properties> </properties>
@@ -89,7 +89,7 @@
<exclusion> <exclusion>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>log4j</groupId> <groupId>log4j</groupId>
<artifactId>log4j</artifactId> <artifactId>log4j</artifactId>
@@ -103,6 +103,11 @@
<groupId>org.codehaus.woodstox</groupId> <groupId>org.codehaus.woodstox</groupId>
<artifactId>wstx-asl</artifactId> <artifactId>wstx-asl</artifactId>
</exclusion> </exclusion>
<!-- Later version provided by Hibernate -->
<exclusion>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>

View File

@@ -26,11 +26,12 @@ public class DSpaceSolrServerResolver implements SolrServerResolver {
@Override @Override
public SolrClient getServer() throws SolrServerException { public SolrClient getServer() throws SolrServerException {
if (server == null) { if (server == null) {
String serverUrl = configurationService.getProperty("oai.solr.url");
try { try {
server = new HttpSolrClient.Builder(configurationService.getProperty("oai", "solr.url")).build(); server = new HttpSolrClient.Builder(serverUrl).build();
log.debug("Solr Server Initialized"); log.debug("OAI Solr Server Initialized");
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error("Could not initialize OAI Solr Server at " + serverUrl , e);
} }
} }
return server; return server;

View File

@@ -30,12 +30,12 @@ public class DSpaceSolrServer {
public static SolrClient getServer() throws SolrServerException { public static SolrClient getServer() throws SolrServerException {
if (_server == null) { if (_server == null) {
String serverUrl = ConfigurationManager.getProperty("oai.solr.url");
try { try {
_server = new HttpSolrClient.Builder( _server = new HttpSolrClient.Builder(serverUrl).build();
ConfigurationManager.getProperty("oai", "solr.url")).build(); log.debug("OAI Solr Server Initialized");
log.debug("Solr Server Initialized");
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error("Could not initialize OAI Solr Server at " + serverUrl , e);
} }
} }
return _server; return _server;

View File

@@ -27,7 +27,6 @@ import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.hateoas.BitstreamResource; import org.dspace.app.rest.model.hateoas.BitstreamResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.MultipartFileSender; import org.dspace.app.rest.utils.MultipartFileSender;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
@@ -243,7 +242,7 @@ public class BitstreamRestController {
context.commit(); context.commit();
BitstreamRest bitstreamRest = converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT); BitstreamRest bitstreamRest = converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
return converter.toResource(bitstreamRest); return converter.toResource(bitstreamRest);
} }
} }

View File

@@ -22,7 +22,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BundleRest; import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.hateoas.BundleResource; import org.dspace.app.rest.model.hateoas.BundleResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.ItemRestRepository; import org.dspace.app.rest.repository.ItemRestRepository;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
@@ -108,7 +107,7 @@ public class ItemAddBundleController {
} }
Bundle bundle = itemRestRepository.addBundleToItem(context, item, bundleRest); Bundle bundle = itemRestRepository.addBundleToItem(context, item, bundleRest);
BundleResource bundleResource = converter.toResource(converter.toRest(bundle, Projection.DEFAULT)); BundleResource bundleResource = converter.toResource(converter.toRest(bundle, utils.obtainProjection()));
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), bundleResource); return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), bundleResource);
} }

View File

@@ -21,7 +21,6 @@ import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.CollectionRest; import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -97,7 +96,7 @@ public class ItemOwningCollectionUpdateRestController {
if (targetCollection == null) { if (targetCollection == null) {
return null; return null;
} }
return converter.toRest(targetCollection, Projection.DEFAULT); return converter.toRest(targetCollection, utils.obtainProjection());
} }

View File

@@ -0,0 +1,82 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.app.rest.utils.Utils;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "collections" subresource of an individual workflow definition.
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME + "."
+ WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO)
public class WorkflowDefinitionCollectionsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
protected ConverterService converter;
@Autowired
protected Utils utils;
/**
* GET endpoint that returns the list of collections that make an explicit use of the workflow-definition.
* If a collection doesn't specify the workflow-definition to be used, the default mapping applies,
* but this collection is not included in the list returned by this method.
*
* @param request The request object
* @param workflowName Name of workflow we want the collections of that are mapped to is
* @return List of collections mapped to the requested workflow
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<CollectionRest> getCollections(@Nullable HttpServletRequest request,
String workflowName,
@Nullable Pageable optionalPageable,
Projection projection) {
if (xmlWorkflowFactory.workflowByThisNameExists(workflowName)) {
Context context = obtainContext();
List<Collection> collectionsMappedToWorkflow = new ArrayList<>();
if (xmlWorkflowFactory.isDefaultWorkflow(workflowName)) {
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context));
}
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context,
workflowName));
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(collectionsMappedToWorkflow, pageable),
projection);
} else {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
}

View File

@@ -0,0 +1,63 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "steps" subresource of an individual workflow definition.
*
* @author Maria Verdonck (Atmire) on 24/02/2020
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME + "."
+ WorkflowDefinitionRest.STEPS)
public class WorkflowDefinitionStepsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
/**
* GET endpoint that returns the list of steps of a workflow-definition.
*
* @param request The request object
* @param workflowName Name of workflow we want the steps from
* @return List of steps of the requested workflow
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowStepRest> getSteps(@Nullable HttpServletRequest request,
String workflowName,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(steps, pageable), projection);
} catch (WorkflowConfigurationException e) {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
}

View File

@@ -0,0 +1,57 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "actions" subresource of an individual workflow step.
*
* @author Maria Verdonck (Atmire) on 24/02/2020
*/
@Component(WorkflowStepRest.CATEGORY + "." + WorkflowStepRest.NAME + "."
+ WorkflowStepRest.ACTIONS)
public class WorkflowStepActionsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
/**
* GET endpoint that returns the list of actions of a workflow step.
*
* @param request The request object
* @param workflowStepName Name of workflow step we want the actions from
* @return List of actions of the requested workflow step
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowActionRest> getActions(@Nullable HttpServletRequest request,
String workflowStepName,
@Nullable Pageable optionalPageable,
Projection projection) {
List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(actions, pageable), projection);
}
}

View File

@@ -0,0 +1,36 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.stereotype.Component;
/**
* Converter to translate {@link WorkflowActionConfig} to a {@link WorkflowActionRest} object
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@Component
public class WorkflowActionConverter implements DSpaceConverter<WorkflowActionConfig, WorkflowActionRest> {
@Override
public WorkflowActionRest convert(WorkflowActionConfig modelObject, Projection projection) {
WorkflowActionRest restModel = new WorkflowActionRest();
restModel.setProjection(projection);
restModel.setId(modelObject.getId());
restModel.setOptions(modelObject.getOptions());
return restModel;
}
@Override
public Class<WorkflowActionConfig> getModelClass() {
return WorkflowActionConfig.class;
}
}

View File

@@ -0,0 +1,50 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Converter to translate Workflow to a Workflow Definition
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component
public class WorkflowDefinitionConverter implements DSpaceConverter<Workflow, WorkflowDefinitionRest> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
ConverterService converter;
@Override
public WorkflowDefinitionRest convert(Workflow modelObject, Projection projection) {
WorkflowDefinitionRest restModel = new WorkflowDefinitionRest();
restModel.setName(modelObject.getID());
restModel.setIsDefault(xmlWorkflowFactory.isDefaultWorkflow(modelObject.getID()));
restModel.setProjection(projection);
restModel.setSteps(modelObject.getSteps().stream()
.map(x -> (WorkflowStepRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
return restModel;
}
@Override
public Class<Workflow> getModelClass() {
return Workflow.class;
}
}

View File

@@ -0,0 +1,45 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Converter to translate {@link Step} to a {@link WorkflowStepRest} object
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@Component
public class WorkflowStepConverter implements DSpaceConverter<Step, WorkflowStepRest> {
@Autowired
ConverterService converter;
@Override
public WorkflowStepRest convert(Step modelObject, Projection projection) {
WorkflowStepRest restModel = new WorkflowStepRest();
restModel.setProjection(projection);
restModel.setId(modelObject.getId());
restModel.setWorkflowactions(modelObject.getActions().stream()
.map(x -> (WorkflowActionRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
return restModel;
}
@Override
public Class<Step> getModelClass() {
return Step.class;
}
}

View File

@@ -26,6 +26,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest( @LinkRest(
name = CollectionRest.MAPPED_ITEMS, name = CollectionRest.MAPPED_ITEMS,
method = "getMappedItems" method = "getMappedItems"
),
@LinkRest(
name = CollectionRest.PARENT_COMMUNITY,
method = "getParentCommunity"
) )
}) })
public class CollectionRest extends DSpaceObjectRest { public class CollectionRest extends DSpaceObjectRest {
@@ -37,6 +41,7 @@ public class CollectionRest extends DSpaceObjectRest {
public static final String LICENSE = "license"; public static final String LICENSE = "license";
public static final String LOGO = "logo"; public static final String LOGO = "logo";
public static final String MAPPED_ITEMS = "mappedItems"; public static final String MAPPED_ITEMS = "mappedItems";
public static final String PARENT_COMMUNITY = "parentCommunity";
@Override @Override
public String getCategory() { public String getCategory() {

View File

@@ -26,6 +26,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest( @LinkRest(
name = CommunityRest.SUBCOMMUNITIES, name = CommunityRest.SUBCOMMUNITIES,
method = "getSubcommunities" method = "getSubcommunities"
),
@LinkRest(
name = CommunityRest.PARENT_COMMUNITY,
method = "getParentCommunity"
) )
}) })
public class CommunityRest extends DSpaceObjectRest { public class CommunityRest extends DSpaceObjectRest {
@@ -36,6 +40,8 @@ public class CommunityRest extends DSpaceObjectRest {
public static final String COLLECTIONS = "collections"; public static final String COLLECTIONS = "collections";
public static final String LOGO = "logo"; public static final String LOGO = "logo";
public static final String SUBCOMMUNITIES = "subcommunities"; public static final String SUBCOMMUNITIES = "subcommunities";
public static final String PARENT_COMMUNITY = "parentCommunity";
@Override @Override
public String getCategory() { public String getCategory() {

View File

@@ -0,0 +1,59 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow actions
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionRest extends BaseObjectRest<String> {
public static final String CATEGORY = "config";
public static final String NAME = "workflowaction";
public static final String NAME_PLURAL = "workflowactions";
private List<String> options;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
/**
* Generic getter for the options
*
* @return the options value of this WorkflowActionRest
*/
public List<String> getOptions() {
return options;
}
/**
* Generic setter for the options
*
* @param options The options to be set on this WorkflowActionRest
*/
public void setOptions(List<String> options) {
this.options = options;
}
}

View File

@@ -0,0 +1,88 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow definitions
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@LinksRest(links = {
@LinkRest(
name = WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO,
method = "getCollections"
),
@LinkRest(
name = WorkflowDefinitionRest.STEPS,
method = "getSteps"
)
})
public class WorkflowDefinitionRest extends BaseObjectRest<String> {
public static final String CATEGORY = "config";
public static final String NAME = "workflowdefinition";
public static final String NAME_PLURAL = "workflowdefinitions";
public static final String COLLECTIONS_MAPPED_TO = "collections";
public static final String STEPS = "steps";
private String name;
private boolean isDefault;
private List<WorkflowStepRest> steps;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
@Override
@JsonIgnore
public String getId() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(boolean isDefault) {
this.isDefault = isDefault;
}
@JsonIgnore
public List<WorkflowStepRest> getSteps() {
return steps;
}
public void setSteps(List<WorkflowStepRest> steps) {
this.steps = steps;
}
}

View File

@@ -0,0 +1,59 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow steps
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@LinksRest(links = {
@LinkRest(
name = WorkflowStepRest.ACTIONS,
method = "getActions"
),
})
public class WorkflowStepRest extends BaseObjectRest {
public static final String CATEGORY = "config";
public static final String NAME = "workflowstep";
public static final String NAME_PLURAL = "workflowsteps";
public static final String ACTIONS = "workflowactions";
private List<WorkflowActionRest> workflowactions;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
@JsonIgnore
public List<WorkflowActionRest> getWorkflowactions() {
return workflowactions;
}
public void setWorkflowactions(List<WorkflowActionRest> actions) {
this.workflowactions = actions;
}
}

View File

@@ -0,0 +1,25 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* {@link WorkflowActionRest} HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@RelNameDSpaceResource(WorkflowActionRest.NAME)
public class WorkflowActionResource extends DSpaceResource<WorkflowActionRest> {
public WorkflowActionResource(WorkflowActionRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,24 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* WorkflowDefinition Rest HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@RelNameDSpaceResource(WorkflowDefinitionRest.NAME)
public class WorkflowDefinitionResource extends DSpaceResource<WorkflowDefinitionRest> {
public WorkflowDefinitionResource(WorkflowDefinitionRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,25 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* {@link WorkflowStepRest} HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@RelNameDSpaceResource(WorkflowStepRest.NAME)
public class WorkflowStepResource extends DSpaceResource<WorkflowStepRest> {
public WorkflowStepResource(WorkflowStepRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -18,7 +18,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.BitstreamFormatRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.BitstreamFormat; import org.dspace.content.BitstreamFormat;
import org.dspace.content.service.BitstreamFormatService; import org.dspace.content.service.BitstreamFormatService;
@@ -89,7 +88,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
+ bitstreamFormatRest.getShortDescription(), e); + bitstreamFormatRest.getShortDescription(), e);
} }
return converter.toRest(bitstreamFormat, Projection.DEFAULT); return converter.toRest(bitstreamFormat, utils.obtainProjection());
} }
@Override @Override
@@ -116,7 +115,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
if (id.equals(bitstreamFormatRest.getId())) { if (id.equals(bitstreamFormatRest.getId())) {
this.setAllValuesOfRest(context, bitstreamFormat, bitstreamFormatRest); this.setAllValuesOfRest(context, bitstreamFormat, bitstreamFormatRest);
bitstreamFormatService.update(context, bitstreamFormat); bitstreamFormatService.update(context, bitstreamFormat);
return converter.toRest(bitstreamFormat, Projection.DEFAULT); return converter.toRest(bitstreamFormat, utils.obtainProjection());
} else { } else {
throw new IllegalArgumentException("The id in the Json and the id in the url do not match: " throw new IllegalArgumentException("The id in the Json and the id in the url do not match: "
+ id + ", " + id + ", "

View File

@@ -23,7 +23,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest; import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
@@ -150,7 +149,7 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
throw new RuntimeException(message, e); throw new RuntimeException(message, e);
} }
return converter.toRest(bitstream, Projection.DEFAULT); return converter.toRest(bitstream, utils.obtainProjection());
} }
/** /**

View File

@@ -0,0 +1,64 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* LinkRepository for the ParentCommunity object for a Collection
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.PARENT_COMMUNITY)
public class CollectionParentCommunityLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private CollectionService collectionService;
/**
* This method retrieves the ParentCommunity object for the Collection which is defined by the given collectionId
* It'll transform this Parent Community to a REST object and return this
* @param httpServletRequest The current request
* @param collectionId The given Collection UUID that will be used to find the Collection
* @param optionalPageable The pageable
* @param projection The current Projection
* @return The Parent Community REST object
*/
@PreAuthorize("hasPermission(#collectionId, 'COLLECTION', 'READ')")
public CommunityRest getParentCommunity(@Nullable HttpServletRequest httpServletRequest,
UUID collectionId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Collection collection = collectionService.find(context, collectionId);
if (collection == null) {
throw new ResourceNotFoundException("No such collection: " + collectionId);
}
Community parentCommunity = (Community) collectionService.getParentObject(context, collection);
return converter.toRest(parentCommunity, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -27,7 +27,6 @@ import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.model.TemplateItemRest; import org.dspace.app.rest.model.TemplateItemRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.model.wrapper.TemplateItem; import org.dspace.app.rest.model.wrapper.TemplateItem;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.CollectionRestEqualityUtils; import org.dspace.app.rest.utils.CollectionRestEqualityUtils;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
@@ -181,7 +180,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException("Unable to create new Collection under parent Community " + id, e); throw new RuntimeException("Unable to create new Collection under parent Community " + id, e);
} }
return converter.toRest(collection, Projection.DEFAULT); return converter.toRest(collection, utils.obtainProjection());
} }
@@ -200,7 +199,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
if (collection == null) { if (collection == null) {
throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found"); throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found");
} }
CollectionRest originalCollectionRest = converter.toRest(collection, Projection.DEFAULT); CollectionRest originalCollectionRest = converter.toRest(collection, utils.obtainProjection());
if (collectionRestEqualityUtils.isCollectionRestEqualWithoutMetadata(originalCollectionRest, collectionRest)) { if (collectionRestEqualityUtils.isCollectionRestEqualWithoutMetadata(originalCollectionRest, collectionRest)) {
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata()); metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
} else { } else {
@@ -208,7 +207,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
+ id + ", " + id + ", "
+ collectionRest.getId()); + collectionRest.getId());
} }
return converter.toRest(collection, Projection.DEFAULT); return converter.toRest(collection, utils.obtainProjection());
} }
@Override @Override
@@ -250,7 +249,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
Bitstream bitstream = cs.setLogo(context, collection, uploadfile.getInputStream()); Bitstream bitstream = cs.setLogo(context, collection, uploadfile.getInputStream());
cs.update(context, collection); cs.update(context, collection);
bitstreamService.update(context, bitstream); bitstreamService.update(context, bitstream);
return converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT); return converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
} }
/** /**
@@ -277,7 +276,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
cs.update(context, collection); cs.update(context, collection);
itemService.update(context, item); itemService.update(context, item);
return converter.toRest(new TemplateItem(item), Projection.DEFAULT); return converter.toRest(new TemplateItem(item), utils.obtainProjection());
} }
/** /**
@@ -296,7 +295,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
} }
try { try {
return converter.toRest(new TemplateItem(item), Projection.DEFAULT); return converter.toRest(new TemplateItem(item), utils.obtainProjection());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new UnprocessableEntityException("The item with id " + item.getID() + " is not a template item"); throw new UnprocessableEntityException("The item with id " + item.getID() + " is not a template item");
} }

View File

@@ -0,0 +1,65 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Community;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* LinkRepository for the ParentCommunity object for a Community
*/
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME + "." + CommunityRest.PARENT_COMMUNITY)
public class CommunityParentCommunityLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private CommunityService communityService;
/**
* This method retrieves the ParentCommunity object for the Community which is defined by the given communityId
* It'll transform this Parent Community to a REST object and return this
* @param httpServletRequest The current request
* @param communityId The given Community UUID that will be used to find the communityId
* @param optionalPageable The pageable
* @param projection The current Projection
* @return The Parent Community REST object
*/
@PreAuthorize("hasPermission(#communityId, 'COMMUNITY', 'READ')")
public CommunityRest getParentCommunity(@Nullable HttpServletRequest httpServletRequest,
UUID communityId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Community community = communityService.find(context, communityId);
if (community == null) {
throw new ResourceNotFoundException("No such community: " + community);
}
Community parentCommunity = (Community) communityService.getParentObject(context, community);
if (parentCommunity == null) {
return null;
}
return converter.toRest(parentCommunity, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -25,7 +25,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamRest; import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CommunityRest; import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.CommunityRestEqualityUtils; import org.dspace.app.rest.utils.CommunityRestEqualityUtils;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
@@ -90,7 +89,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
} }
return converter.toRest(community, Projection.DEFAULT); return converter.toRest(community, utils.obtainProjection());
} }
@Override @Override
@@ -127,7 +126,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
} }
return converter.toRest(community, Projection.DEFAULT); return converter.toRest(community, utils.obtainProjection());
} }
@Override @Override
@@ -215,14 +214,14 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
if (community == null) { if (community == null) {
throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found"); throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found");
} }
CommunityRest originalCommunityRest = converter.toRest(community, Projection.DEFAULT); CommunityRest originalCommunityRest = converter.toRest(community, utils.obtainProjection());
if (communityRestEqualityUtils.isCommunityRestEqualWithoutMetadata(originalCommunityRest, communityRest)) { if (communityRestEqualityUtils.isCommunityRestEqualWithoutMetadata(originalCommunityRest, communityRest)) {
metadataConverter.setMetadata(context, community, communityRest.getMetadata()); metadataConverter.setMetadata(context, community, communityRest.getMetadata());
} else { } else {
throw new UnprocessableEntityException("The given JSON and the original Community differ more " + throw new UnprocessableEntityException("The given JSON and the original Community differ more " +
"than just the metadata"); "than just the metadata");
} }
return converter.toRest(community, Projection.DEFAULT); return converter.toRest(community, utils.obtainProjection());
} }
@Override @Override
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'DELETE')") @PreAuthorize("hasPermission(#id, 'COMMUNITY', 'DELETE')")
@@ -267,6 +266,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
Bitstream bitstream = cs.setLogo(context, community, uploadfile.getInputStream()); Bitstream bitstream = cs.setLogo(context, community, uploadfile.getInputStream());
cs.update(context, community); cs.update(context, community);
bitstreamService.update(context, bitstream); bitstreamService.update(context, bitstream);
return converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT); return converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
} }
} }

View File

@@ -20,7 +20,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.EPersonRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -84,7 +83,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository<EPerson, E
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
} }
return converter.toRest(eperson, Projection.DEFAULT); return converter.toRest(eperson, utils.obtainProjection());
} }
@Override @Override

View File

@@ -13,7 +13,6 @@ import java.util.Optional;
import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.model.ExternalSourceEntryRest; import org.dspace.app.rest.model.ExternalSourceEntryRest;
import org.dspace.app.rest.model.ExternalSourceRest; import org.dspace.app.rest.model.ExternalSourceRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.external.model.ExternalDataObject; import org.dspace.external.model.ExternalDataObject;
import org.dspace.external.provider.ExternalDataProvider; import org.dspace.external.provider.ExternalDataProvider;
@@ -52,7 +51,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
entryId); entryId);
ExternalDataObject dataObject = externalDataObject.orElseThrow(() -> new ResourceNotFoundException( ExternalDataObject dataObject = externalDataObject.orElseThrow(() -> new ResourceNotFoundException(
"Couldn't find an ExternalSource for source: " + externalSourceName + " and ID: " + entryId)); "Couldn't find an ExternalSource for source: " + externalSourceName + " and ID: " + entryId));
return converter.toRest(dataObject, Projection.DEFAULT); return converter.toRest(dataObject, utils.obtainProjection());
} }
/** /**
@@ -84,7 +83,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
throw new ResourceNotFoundException("ExternalDataProvider for: " + throw new ResourceNotFoundException("ExternalDataProvider for: " +
externalSourceName + " couldn't be found"); externalSourceName + " couldn't be found");
} }
return converter.toRest(externalDataProvider, Projection.DEFAULT); return converter.toRest(externalDataProvider, utils.obtainProjection());
} }
@Override @Override

View File

@@ -19,7 +19,6 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.GroupRest; import org.dspace.app.rest.model.GroupRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
@@ -74,7 +73,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository<Group, Group
throw new RuntimeException(excSQL.getMessage(), excSQL); throw new RuntimeException(excSQL.getMessage(), excSQL);
} }
return converter.toRest(group, Projection.DEFAULT); return converter.toRest(group, utils.obtainProjection());
} }
@Override @Override

View File

@@ -21,7 +21,6 @@ import org.dspace.app.rest.converter.HarvestedCollectionConverter;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.HarvestTypeEnum; import org.dspace.app.rest.model.HarvestTypeEnum;
import org.dspace.app.rest.model.HarvestedCollectionRest; import org.dspace.app.rest.model.HarvestedCollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.harvest.HarvestedCollection; import org.dspace.harvest.HarvestedCollection;
@@ -91,7 +90,7 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats(); List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs, return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs,
Projection.DEFAULT); utils.obtainProjection());
} else { } else {
throw new UnprocessableEntityException( throw new UnprocessableEntityException(
"Incorrect harvest settings in request. The following errors were found: " + errors.toString() "Incorrect harvest settings in request. The following errors were found: " + errors.toString()

View File

@@ -28,7 +28,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BundleRest; import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.handler.service.UriListHandlerService; import org.dspace.app.rest.repository.handler.service.UriListHandlerService;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bundle; import org.dspace.content.Bundle;
@@ -293,7 +292,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
Item itemToReturn = installItemService.installItem(context, workspaceItem); Item itemToReturn = installItemService.installItem(context, workspaceItem);
return converter.toRest(itemToReturn, Projection.DEFAULT); return converter.toRest(itemToReturn, utils.obtainProjection());
} }
@Override @Override
@@ -322,7 +321,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
+ uuid + ", " + uuid + ", "
+ itemRest.getId()); + itemRest.getId());
} }
return converter.toRest(item, Projection.DEFAULT); return converter.toRest(item, utils.obtainProjection());
} }
/** /**
@@ -355,6 +354,6 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest(); HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
Item item = uriListHandlerService.handle(context, req, stringList, Item.class); Item item = uriListHandlerService.handle(context, req, stringList, Item.class);
return converter.toRest(item, Projection.DEFAULT); return converter.toRest(item, utils.obtainProjection());
} }
} }

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataFieldRest; import org.dspace.app.rest.model.MetadataFieldRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.MetadataField; import org.dspace.content.MetadataField;
import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataSchema;
@@ -147,7 +146,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
} }
// return // return
return converter.toRest(metadataField, Projection.DEFAULT); return converter.toRest(metadataField, utils.obtainProjection());
} }
@Override @Override
@@ -203,6 +202,6 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return converter.toRest(metadataField, Projection.DEFAULT); return converter.toRest(metadataField, utils.obtainProjection());
} }
} }

View File

@@ -21,7 +21,6 @@ import com.google.gson.Gson;
import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataSchemaRest; import org.dspace.app.rest.model.MetadataSchemaRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataSchema;
import org.dspace.content.NonUniqueMetadataException; import org.dspace.content.NonUniqueMetadataException;
@@ -111,7 +110,7 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
} }
// return // return
return converter.toRest(metadataSchema, Projection.DEFAULT); return converter.toRest(metadataSchema, utils.obtainProjection());
} }
@Override @Override
@@ -167,6 +166,6 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
+ metadataSchemaRest.getPrefix() + "." + metadataSchemaRest.getNamespace() + " already exists"); + metadataSchemaRest.getPrefix() + "." + metadataSchemaRest.getNamespace() + " already exists");
} }
return converter.toRest(metadataSchema, Projection.DEFAULT); return converter.toRest(metadataSchema, utils.obtainProjection());
} }
} }

View File

@@ -22,7 +22,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.RelationshipRest; import org.dspace.app.rest.model.RelationshipRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
@@ -127,7 +126,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
relationshipService.updateItem(context, relationship.getLeftItem()); relationshipService.updateItem(context, relationship.getLeftItem());
relationshipService.updateItem(context, relationship.getRightItem()); relationshipService.updateItem(context, relationship.getRightItem());
context.restoreAuthSystemState(); context.restoreAuthSystemState();
return converter.toRest(relationship, Projection.DEFAULT); return converter.toRest(relationship, utils.obtainProjection());
} else { } else {
throw new AccessDeniedException("You do not have write rights on this relationship's items"); throw new AccessDeniedException("You do not have write rights on this relationship's items");
} }
@@ -192,7 +191,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
throw new AccessDeniedException("You do not have write rights on this relationship's items"); throw new AccessDeniedException("You do not have write rights on this relationship's items");
} }
return converter.toRest(relationship, Projection.DEFAULT); return converter.toRest(relationship, utils.obtainProjection());
} else { } else {
throw new AccessDeniedException("You do not have write rights on this relationship's items"); throw new AccessDeniedException("You do not have write rights on this relationship's items");
} }
@@ -256,7 +255,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
context.commit(); context.commit();
context.reloadEntity(relationship); context.reloadEntity(relationship);
return converter.toRest(relationship, Projection.DEFAULT); return converter.toRest(relationship, utils.obtainProjection());
} catch (AuthorizeException e) { } catch (AuthorizeException e) {
throw new AccessDeniedException("You do not have write rights on this relationship's metadata"); throw new AccessDeniedException("You do not have write rights on this relationship's metadata");
} }

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ResourcePolicyRest; import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.ResourcePatch; import org.dspace.app.rest.repository.patch.ResourcePatch;
import org.dspace.app.rest.utils.DSpaceObjectUtils; import org.dspace.app.rest.utils.DSpaceObjectUtils;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
@@ -270,7 +269,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException excSQL) { } catch (SQLException excSQL) {
throw new RuntimeException(excSQL.getMessage(), excSQL); throw new RuntimeException(excSQL.getMessage(), excSQL);
} }
return converter.toRest(resourcePolicy, Projection.DEFAULT); return converter.toRest(resourcePolicy, utils.obtainProjection());
} else { } else {
try { try {
UUID groupUuid = UUID.fromString(groupUuidStr); UUID groupUuid = UUID.fromString(groupUuidStr);
@@ -283,7 +282,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException excSQL) { } catch (SQLException excSQL) {
throw new RuntimeException(excSQL.getMessage(), excSQL); throw new RuntimeException(excSQL.getMessage(), excSQL);
} }
return converter.toRest(resourcePolicy, Projection.DEFAULT); return converter.toRest(resourcePolicy, utils.obtainProjection());
} }
} }

View File

@@ -25,7 +25,6 @@ import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ParameterValueRest; import org.dspace.app.rest.model.ParameterValueRest;
import org.dspace.app.rest.model.ProcessRest; import org.dspace.app.rest.model.ProcessRest;
import org.dspace.app.rest.model.ScriptRest; import org.dspace.app.rest.model.ScriptRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.scripts.handler.impl.RestDSpaceRunnableHandler; import org.dspace.app.rest.scripts.handler.impl.RestDSpaceRunnableHandler;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -103,7 +102,7 @@ public class ScriptRestRepository extends DSpaceRestRepository<ScriptRest, Strin
try { try {
runDSpaceScript(scriptToExecute, restDSpaceRunnableHandler, args); runDSpaceScript(scriptToExecute, restDSpaceRunnableHandler, args);
context.complete(); context.complete();
return converter.toRest(restDSpaceRunnableHandler.getProcess(), Projection.DEFAULT); return converter.toRest(restDSpaceRunnableHandler.getProcess(), utils.obtainProjection());
} catch (SQLException e) { } catch (SQLException e) {
log.error("Failed to create a process with user: " + context.getCurrentUser() + log.error("Failed to create a process with user: " + context.getCurrentUser() +
" scriptname: " + scriptName + " and parameters " + DSpaceCommandLineParameter " scriptname: " + scriptName + " and parameters " + DSpaceCommandLineParameter

View File

@@ -17,7 +17,6 @@ import org.dspace.app.rest.converter.JsonPatchConverter;
import org.dspace.app.rest.model.TemplateItemRest; import org.dspace.app.rest.model.TemplateItemRest;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.model.wrapper.TemplateItem; import org.dspace.app.rest.model.wrapper.TemplateItem;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.ResourcePatch; import org.dspace.app.rest.repository.patch.ResourcePatch;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
@@ -62,7 +61,7 @@ public class TemplateItemRestRepository extends DSpaceRestRepository<TemplateIte
} }
try { try {
return converter.toRest(new TemplateItem(item), Projection.DEFAULT); return converter.toRest(new TemplateItem(item), utils.obtainProjection());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ResourceNotFoundException("The item with id " + item.getID() + " is not a template item"); throw new ResourceNotFoundException("The item with id " + item.getID() + " is not a template item");
} }

View File

@@ -0,0 +1,55 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing {@link WorkflowActionRest} objects
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@Component(WorkflowActionRest.CATEGORY + "." + WorkflowActionRest.NAME)
public class WorkflowActionRestRepository extends DSpaceRestRepository<WorkflowActionRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowActionRest findOne(Context context, String workflowActionName) {
WorkflowActionConfig actionConfig = this.xmlWorkflowFactory.getActionByName(workflowActionName);
if (actionConfig != null) {
return converter.toRest(actionConfig, utils.obtainProjection());
} else {
throw new ResourceNotFoundException("No workflow action with name " + workflowActionName
+ " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowActionRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException(WorkflowActionRest.NAME, "findAll");
}
@Override
public Class<WorkflowActionRest> getDomainClass() {
return WorkflowActionRest.class;
}
}

View File

@@ -0,0 +1,95 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import org.dspace.app.rest.Parameter;
import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing WorkflowDefinition Rest objects
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME)
public class WorkflowDefinitionRestRepository extends DSpaceRestRepository<WorkflowDefinitionRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
private CollectionService collectionService;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowDefinitionRest findOne(Context context, String workflowName) {
if (xmlWorkflowFactory.workflowByThisNameExists(workflowName)) {
try {
return converter.toRest(xmlWorkflowFactory.getWorkflowByName(workflowName), utils.obtainProjection());
} catch (WorkflowConfigurationException e) {
// Should never occur, since xmlWorkflowFactory.getWorkflowByName only throws a
// WorkflowConfigurationException if no workflow by that name is configured (tested earlier)
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
} else {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowDefinitionRest> findAll(Context context, Pageable pageable) {
List<Workflow> workflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
return converter.toRestPage(utils.getPage(workflows, pageable), utils.obtainProjection());
}
/**
* GET endpoint that returns the workflow definition that applies to a specific collection eventually fallback
* to the default configuration.
*
* @param collectionId Uuid of the collection
* @return the workflow definition for this collection
*/
@SearchRestMethod(name = "findByCollection")
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowDefinitionRest findByCollection(@Parameter(value = "uuid") UUID collectionId) throws SQLException {
Context context = obtainContext();
Collection collectionFromUuid = collectionService.find(context, collectionId);
if (collectionFromUuid != null) {
try {
return converter.toRest(xmlWorkflowFactory.getWorkflow(collectionFromUuid), utils.obtainProjection());
} catch (WorkflowConfigurationException e) {
throw new ResourceNotFoundException("No workflow for this collection fault and " +
"no defaultWorkflow found");
}
} else {
throw new ResourceNotFoundException("Collection with id " + collectionId + " not found");
}
}
@Override
public Class<WorkflowDefinitionRest> getDomainClass() {
return WorkflowDefinitionRest.class;
}
}

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.model.ErrorRest;
import org.dspace.app.rest.model.WorkflowItemRest; import org.dspace.app.rest.model.WorkflowItemRest;
import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.submit.AbstractRestProcessingStep; import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.SubmissionService; import org.dspace.app.rest.submit.SubmissionService;
import org.dspace.app.rest.submit.UploadableStep; import org.dspace.app.rest.submit.UploadableStep;
@@ -157,7 +156,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
if (source.getItem().isArchived()) { if (source.getItem().isArchived()) {
return null; return null;
} }
return converter.toRest(source, Projection.DEFAULT); return converter.toRest(source, utils.obtainProjection());
} }
@Override @Override
@@ -204,7 +203,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
} }
} }
wsi = converter.toRest(source, Projection.DEFAULT); wsi = converter.toRest(source, utils.obtainProjection());
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors); wsi.getErrors().addAll(errors);

View File

@@ -0,0 +1,55 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing {@link WorkflowStepRest} objects
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@Component(WorkflowStepRest.CATEGORY + "." + WorkflowStepRest.NAME)
public class WorkflowStepRestRepository extends DSpaceRestRepository<WorkflowStepRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowStepRest findOne(Context context, String workflowStepName) {
Step step = this.xmlWorkflowFactory.getStepByName(workflowStepName);
if (step != null) {
return converter.toRest(step, utils.obtainProjection());
} else {
throw new ResourceNotFoundException("No workflow step with name " + workflowStepName
+ " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowStepRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException(WorkflowStepRest.NAME, "findAll");
}
@Override
public Class<WorkflowStepRest> getDomainClass() {
return WorkflowStepRest.class;
}
}

View File

@@ -31,7 +31,6 @@ import org.dspace.app.rest.model.ErrorRest;
import org.dspace.app.rest.model.WorkspaceItemRest; import org.dspace.app.rest.model.WorkspaceItemRest;
import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.handler.service.UriListHandlerService; import org.dspace.app.rest.repository.handler.service.UriListHandlerService;
import org.dspace.app.rest.submit.AbstractRestProcessingStep; import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.SubmissionService; import org.dspace.app.rest.submit.SubmissionService;
@@ -167,7 +166,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
@Override @Override
protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException { protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException {
WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest()); WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest());
return converter.toRest(source, converter.getProjection("full")); return converter.toRest(source, utils.obtainProjection());
} }
@Override @Override
@@ -254,7 +253,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
} }
} }
wsi = converter.toRest(source, Projection.DEFAULT); wsi = converter.toRest(source, utils.obtainProjection());
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors); wsi.getErrors().addAll(errors);
@@ -473,7 +472,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
} }
} }
} }
WorkspaceItemRest wsi = converter.toRest(wi, Projection.DEFAULT); WorkspaceItemRest wsi = converter.toRest(wi, utils.obtainProjection());
if (result.size() == 1) { if (result.size() == 1) {
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors); wsi.getErrors().addAll(errors);
@@ -494,7 +493,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest(); HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
WorkspaceItem workspaceItem = uriListHandlerService.handle(context, req, stringList, WorkspaceItem.class); WorkspaceItem workspaceItem = uriListHandlerService.handle(context, req, stringList, WorkspaceItem.class);
return converter.toRest(workspaceItem, Projection.DEFAULT); return converter.toRest(workspaceItem, utils.obtainProjection());
} }

View File

@@ -79,6 +79,8 @@ public class SubmissionService {
private RequestService requestService; private RequestService requestService;
@Autowired @Autowired
private ConverterService converter; private ConverterService converter;
@Autowired
private org.dspace.app.rest.utils.Utils utils;
/** /**
* Create a workspaceitem using the information in the request * Create a workspaceitem using the information in the request
@@ -174,9 +176,9 @@ public class SubmissionService {
} }
} }
Projection projection = utils.obtainProjection();
HttpServletRequest request = requestService.getCurrentRequest().getHttpServletRequest(); HttpServletRequest request = requestService.getCurrentRequest().getHttpServletRequest();
data.setFormat(converter.toRest(source.getFormat(ContextUtil.obtainContext(request)), Projection.DEFAULT)); data.setFormat(converter.toRest(source.getFormat(ContextUtil.obtainContext(request)), projection));
for (ResourcePolicy rp : source.getResourcePolicies()) { for (ResourcePolicy rp : source.getResourcePolicies()) {
if (ResourcePolicy.TYPE_CUSTOM.equals(rp.getRpType())) { if (ResourcePolicy.TYPE_CUSTOM.equals(rp.getRpType())) {
@@ -231,7 +233,7 @@ public class SubmissionService {
if (wsi == null) { if (wsi == null) {
throw new UnprocessableEntityException("Workspace item is not found"); throw new UnprocessableEntityException("Workspace item is not found");
} }
WorkspaceItemRest wsiRest = converter.toRest(wsi, Projection.DEFAULT); WorkspaceItemRest wsiRest = converter.toRest(wsi, utils.obtainProjection());
if (!wsiRest.getErrors().isEmpty()) { if (!wsiRest.getErrors().isEmpty()) {
throw new UnprocessableEntityException( throw new UnprocessableEntityException(
"Start workflow failed due to validation error on workspaceitem"); "Start workflow failed due to validation error on workspaceitem");

View File

@@ -29,6 +29,7 @@ import org.dspace.app.rest.builder.BitstreamFormatBuilder;
import org.dspace.app.rest.builder.EPersonBuilder; import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.matcher.BitstreamFormatMatcher; import org.dspace.app.rest.matcher.BitstreamFormatMatcher;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.BitstreamFormatRest;
import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
@@ -134,6 +135,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati
public void createAdminAccess() throws Exception { public void createAdminAccess() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false); BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false);
//Create bitstream format //Create bitstream format
String token = getAuthToken(admin.getEmail(), password); String token = getAuthToken(admin.getEmail(), password);
@@ -142,10 +144,10 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati
try { try {
MvcResult mvcResult = getClient(token).perform(post("/api/core/bitstreamformats/") MvcResult mvcResult = getClient(token).perform(post("/api/core/bitstreamformats/")
.content(mapper.writeValueAsBytes( .content(mapper.writeValueAsBytes(bitstreamFormatRest))
bitstreamFormatRest))
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andReturn(); .andReturn();
String content = mvcResult.getResponse().getContentAsString(); String content = mvcResult.getResponse().getContentAsString();

View File

@@ -78,8 +78,10 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()), CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) col1.getHandle()),
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
))); )));
} }
@@ -110,11 +112,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.contains( .andExpect(jsonPath("$._embedded.collections", Matchers.contains(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._embedded.collections", Matchers.not( .andExpect(jsonPath("$._embedded.collections", Matchers.not(
Matchers.contains( Matchers.contains(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
) )
))); )));
@@ -125,11 +129,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.contains( .andExpect(jsonPath("$._embedded.collections", Matchers.contains(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
))) )))
.andExpect(jsonPath("$._embedded.collections", Matchers.not( .andExpect(jsonPath("$._embedded.collections", Matchers.not(
Matchers.contains( Matchers.contains(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
) )
))); )));
} }
@@ -202,11 +208,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is( .andExpect(jsonPath("$", is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$", Matchers.not( .andExpect(jsonPath("$", Matchers.not(
is( is(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
))) )))
) )
; ;
@@ -348,11 +356,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is( .andExpect(jsonPath("$", is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$", Matchers.not( .andExpect(jsonPath("$", Matchers.not(
is( is(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)))); ))));
} }
@@ -376,7 +386,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
; ;
@@ -403,7 +414,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry("Electronic theses and dissertations", CollectionMatcher.matchCollectionEntryFullProjection("Electronic theses and dissertations",
col1.getID(), col1.getHandle()) col1.getID(), col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
@@ -445,10 +456,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ; Matchers.containsString("/api/core/collections")));
getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString())) getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isNoContent()) .andExpect(status().isNoContent())
; ;
@@ -489,10 +501,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ; Matchers.containsString("/api/core/collections")));
getClient().perform(delete("/api/core/collections/" + col1.getID().toString())) getClient().perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isUnauthorized()) .andExpect(status().isUnauthorized())
; ;
@@ -532,9 +545,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
getClient(authToken).perform(post("/api/core/collections") getClient(authToken).perform(post("/api/core/collections")
.content(mapper.writeValueAsBytes(collectionRest)) .content(mapper.writeValueAsBytes(collectionRest))
.param("parent", parentCommunity.getID().toString()) .param("parent", parentCommunity.getID().toString())
.contentType(contentType)) .contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", CollectionMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf( .andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.id", not(empty())), hasJsonPath("$.id", not(empty())),
hasJsonPath("$.uuid", not(empty())), hasJsonPath("$.uuid", not(empty())),
@@ -554,6 +569,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
"Title Text") "Title Text")
))))); )))));
getClient(authToken).perform(post("/api/core/collections")
.content(mapper.writeValueAsBytes(collectionRest))
.param("parent", parentCommunity.getID().toString())
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()));
} }
@Test @Test
@@ -701,10 +723,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ; Matchers.containsString("/api/core/collections")));
getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString())) getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isNoContent()) .andExpect(status().isNoContent())
; ;
@@ -737,7 +760,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
; ;
@@ -767,7 +791,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry("Electronic theses and dissertations", CollectionMatcher.matchCollectionEntryFullProjection("Electronic theses and dissertations",
col1.getID(), col1.getHandle()) col1.getID(), col1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
@@ -908,9 +932,12 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()), CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) col1.getHandle()),
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
))) )))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 2))); .andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 20,
1, 2)));
} }
} }

View File

@@ -0,0 +1,374 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.sql.SQLException;
import java.util.UUID;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.matcher.CollectionMatcher;
import org.dspace.app.rest.matcher.CommunityMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class CommunityCollectionItemParentIT extends AbstractControllerIntegrationTest {
@Autowired
private CollectionService collectionService;
@Autowired
private CommunityService communityService;
@Autowired
private AuthorizeService authorizeService;
Community communityA;
Community communityB;
Community communityAA;
Community communityAB;
Collection colAA1;
Collection colAA2;
Collection colAB1;
Item itemAA1;
Item itemAA1MappedInAA2;
Item itemAA2;
@Before
public void setup() throws SQLException, AuthorizeException {
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
communityA = CommunityBuilder.createCommunity(context)
.withName("Parent CommunityA")
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("Parent CommunityB")
.build();
communityAA = CommunityBuilder.createSubCommunity(context, communityA)
.withName("Sub Community")
.build();
communityAB = CommunityBuilder.createSubCommunity(context, communityA)
.withName("Sub Community Two")
.build();
colAA1 = CollectionBuilder.createCollection(context, communityAA).withName("Collection 1").build();
colAA2 = CollectionBuilder.createCollection(context, communityAA).withName("Collection 2").build();
colAB1 = CollectionBuilder.createCollection(context, communityAB).withName("Collection 3").build();
communityService.addCollection(context, communityAB, colAA2);
itemAA1 = ItemBuilder.createItem(context, colAA1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
itemAA1MappedInAA2 = ItemBuilder.createItem(context, colAA1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
collectionService.addItem(context, colAA2, itemAA1MappedInAA2);
itemAA2 = ItemBuilder.createItem(context, colAA2)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
}
@Test
public void itemAA1OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA1.getName(),
colAA1.getID(),
colAA1.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA2.getName(), colAA2.getID(), colAA2.getHandle())))));
}
@Test
public void itemAA1MappedInAA2OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1MappedInAA2.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA1.getName(),
colAA1.getID(),
colAA1.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA2.getName(), colAA2.getID(), colAA2.getHandle())))));
}
@Test
public void itemAA2OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA2.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA2.getName(),
colAA2.getID(),
colAA2.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA1.getName(), colAA1.getID(), colAA1.getHandle())))));
}
@Test
public void colAA1ParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(jsonPath("$", is(CommunityMatcher
.matchCommunityEntry(communityAA.getName(), communityAA.getID(),
communityAA.getHandle()))))
.andExpect(jsonPath("$", not(is(CommunityMatcher.matchCommunityEntry(communityA.getName(),
communityA.getID(),
communityA.getHandle())))))
.andExpect(jsonPath("$", not(is(CommunityMatcher.matchCommunityEntry(communityAB.getName(),
communityAB.getID(),
communityAB
.getHandle())))));
}
@Test
public void comAAParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token)
.perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(jsonPath("$", Matchers
.is(CommunityMatcher.matchCommunityEntry(communityA.getID(), communityA.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(Matchers.is(CommunityMatcher.matchCommunityEntry(communityB.getID(), communityB.getHandle())))));
}
@Test
public void comAParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityA.getID() + "/parentCommunity"))
.andExpect(status().isNoContent());
}
@Test
public void parentCommunityWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + UUID.randomUUID() + "/parentCommunity"))
.andExpect(status().isNotFound());
}
@Test
public void parentCommunityPrivateCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityPrivateParentCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
@Test
public void parentCommunityPrivateCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityPrivateParentCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
@Test
public void parentCommunityForCollectionWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + UUID.randomUUID() + "/parentCommunity"))
.andExpect(status().isNotFound());
}
@Test
public void parentCommunityForCollectionPrivateCollectionUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityForCollectionPrivateParentCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
@Test
public void parentCommunityForCollectionPrivateCollectionForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityForCollectionPrivateParentCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
@Test
public void owningCollectionForItemWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + UUID.randomUUID() + "/owningCollection"))
.andExpect(status().isNotFound());
}
@Test
public void owningCollectionForItemPrivateItemUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, itemAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void owningCollectionForItemPrivateOwningCollectionUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void owningCollectionForItemPrivateOwningCollectionForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isForbidden());
}
@Test
public void owningCollectionForItemPrivateItemForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, itemAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isForbidden());
}
}

View File

@@ -75,8 +75,10 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
public void createTest() throws Exception { public void createTest() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
CommunityRest comm = new CommunityRest(); CommunityRest comm = new CommunityRest();
CommunityRest commNoembeds = new CommunityRest();
// We send a name but the created community should set this to the title // We send a name but the created community should set this to the title
comm.setName("Test Top-Level Community"); comm.setName("Test Top-Level Community");
commNoembeds.setName("Test Top-Level Community Full");
MetadataRest metadataRest = new MetadataRest(); MetadataRest metadataRest = new MetadataRest();
@@ -101,17 +103,22 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
metadataRest.put("dc.title", title); metadataRest.put("dc.title", title);
comm.setMetadata(metadataRest); comm.setMetadata(metadataRest);
commNoembeds.setMetadata(metadataRest);
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
// Capture the UUID of the created Community (see andDo() below) // Capture the UUID of the created Community (see andDo() below)
AtomicReference<UUID> idRef = new AtomicReference<UUID>(); AtomicReference<UUID> idRef = new AtomicReference<UUID>();
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<UUID>();
try { try {
getClient(authToken).perform(post("/api/core/communities") getClient(authToken).perform(post("/api/core/communities")
.content(mapper.writeValueAsBytes(comm)) .content(mapper.writeValueAsBytes(comm))
.contentType(contentType)) .contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", CommunityMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf( .andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.id", not(empty())), hasJsonPath("$.id", not(empty())),
hasJsonPath("$.uuid", not(empty())), hasJsonPath("$.uuid", not(empty())),
@@ -135,9 +142,19 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
// capture "id" returned in JSON response // capture "id" returned in JSON response
.andDo(result -> idRef .andDo(result -> idRef
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id")))); .set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
getClient(authToken).perform(post("/api/core/communities")
.content(mapper.writeValueAsBytes(commNoembeds))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRefNoEmbeds
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
} finally { } finally {
// Delete the created community (cleanup after ourselves!) // Delete the created community (cleanup after ourselves!)
CommunityBuilder.deleteCommunity(idRef.get()); CommunityBuilder.deleteCommunity(idRef.get());
CommunityBuilder.deleteCommunity(idRefNoEmbeds.get());
} }
} }
@@ -307,10 +324,11 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()), parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher CommunityMatcher
.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) .matchCommunityEntryFullProjection(child1.getName(), child1.getID(), child1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
@@ -334,13 +352,15 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.build(); .build();
getClient().perform(get("/api/core/communities").param("size", "2").param("projection", "full")) getClient().perform(get("/api/core/communities").param("size", "2").param("projection",
"full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(), CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
parentCommunity.getHandle()), parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.totalElements", is(2))) .andExpect(jsonPath("$.page.totalElements", is(2)))
@@ -357,50 +377,60 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.withTitle(titles.get(2)) .withTitle(titles.get(2))
.withTitle(titles.get(3)) .withTitle(titles.get(3))
.build(); .build();
Community childCommunity = CommunityBuilder.createSubCommunity(context, parentCommunity).build(); Community childCommunity = CommunityBuilder.createSubCommunity(context, parentCommunity).withName("test")
.build();
Community secondParentCommunity = CommunityBuilder.createCommunity(context).withName("testing").build(); Community secondParentCommunity = CommunityBuilder.createCommunity(context).withName("testing").build();
Community thirdParentCommunity = CommunityBuilder.createCommunity(context).withName("testingTitleTwo").build(); Community thirdParentCommunity = CommunityBuilder.createCommunity(context).withName("testingTitleTwo").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities").param("size", "2").param("projection", "full")) getClient().perform(get("/api/core/communities").param("size", "2").param("projection",
"full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(), CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
parentCommunity.getHandle()), parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(childCommunity.getID(), childCommunity.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(childCommunity.getName(),
childCommunity.getID(),
childCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href",
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 2, 2, 4))); Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 2,
2, 4)));
getClient().perform(get("/api/core/communities").param("size", "2").param("page", "1") getClient().perform(get("/api/core/communities").param("size", "2").param("page", "1")
.param("projection", "full")) .param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(secondParentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(secondParentCommunity.getName(),
secondParentCommunity.getHandle()), secondParentCommunity.getID(),
CommunityMatcher.matchCommunityEntry(thirdParentCommunity.getID(), secondParentCommunity.getHandle()),
thirdParentCommunity.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(thirdParentCommunity.getName(),
thirdParentCommunity.getID(),
thirdParentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(1, 2, 2, 4))); .andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(1, 2,
2, 4)));
} }
@Test @Test
public void findAllNoNameCommunityIsReturned() throws Exception { public void findAllNoNameCommunityIsReturned() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context).build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("test").build();
getClient().perform(get("/api/core/communities") getClient().perform(get("/api/core/communities")
.param("projection", "full")) .param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains( .andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -462,12 +492,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains( .andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._embedded.communities", Matchers.not( .andExpect(jsonPath("$._embedded.communities", Matchers.not(
Matchers.contains( Matchers.contains(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
) )
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -480,12 +512,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains( .andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
))) )))
.andExpect(jsonPath("$._embedded.communities", Matchers.not( .andExpect(jsonPath("$._embedded.communities", Matchers.not(
Matchers.contains( Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
) )
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -553,12 +587,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$", Matchers.not( .andExpect(jsonPath("$", Matchers.not(
Matchers.is( Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
) )
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers .andExpect(jsonPath("$._links.self.href", Matchers
@@ -633,14 +669,18 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()), parentCommunity.getID(),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(), parentCommunity2.getID(), parentCommunity.getHandle()),
parentCommunity2.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(),
parentCommunity2.getHandle())
))) )))
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()), CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
CommunityMatcher.matchCommunityEntry(child12.getName(), child12.getID(), child12.getHandle()) child1.getHandle()),
CommunityMatcher.matchCommunityEntryFullProjection(child12.getName(), child12.getID(),
child12.getHandle())
)))) ))))
.andExpect( .andExpect(
jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities/search/top"))) jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities/search/top")))
@@ -697,25 +737,25 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
//Checking that these communities are present //Checking that these communities are present
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunityChild1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild1.getName(),
parentCommunityChild1.getID(), parentCommunityChild1.getID(),
parentCommunityChild1.getHandle()), parentCommunityChild1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2.getName(),
parentCommunityChild2.getID(), parentCommunityChild2.getID(),
parentCommunityChild2.getHandle()) parentCommunityChild2.getHandle())
))) )))
//Checking that these communities are not present //Checking that these communities are not present
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf( .andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(), parentCommunity.getID(),
parentCommunity.getHandle()), parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(), parentCommunity2.getID(),
parentCommunity2.getHandle()), parentCommunity2.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2Child1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2Child1.getName(),
parentCommunity2Child1.getID(), parentCommunity2Child1.getID(),
parentCommunity2Child1.getHandle()), parentCommunity2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(), parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle()) parentCommunityChild2Child1.getHandle())
)))) ))))
@@ -732,25 +772,25 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
//Checking that these communities are present //Checking that these communities are present
.andExpect(jsonPath("$._embedded.communities", Matchers.contains( .andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(), parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle()) parentCommunityChild2Child1.getHandle())
))) )))
//Checking that these communities are not present //Checking that these communities are not present
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf( .andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(), parentCommunity.getID(),
parentCommunity.getHandle()), parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(), parentCommunity2.getID(),
parentCommunity2.getHandle()), parentCommunity2.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2Child1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2Child1.getName(),
parentCommunity2Child1.getID(), parentCommunity2Child1.getID(),
parentCommunity2Child1.getHandle()), parentCommunity2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(), parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle()), parentCommunityChild2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild1.getName(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild1.getName(),
parentCommunityChild1.getID(), parentCommunityChild1.getID(),
parentCommunityChild1.getHandle()) parentCommunityChild1.getHandle())
)))) ))))
@@ -824,12 +864,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$", Matchers.not( .andExpect(jsonPath("$", Matchers.not(
Matchers.is( Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
) )
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -857,7 +899,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry("Electronic theses and dissertations", CommunityMatcher.matchCommunityEntryFullProjection("Electronic theses and dissertations",
parentCommunity.getID(), parentCommunity.getID(),
parentCommunity.getHandle()) parentCommunity.getHandle())
))) )))
@@ -912,11 +954,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ; Matchers.containsString("/api/core/communities")));
getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString())) getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isNoContent()) .andExpect(status().isNoContent())
; ;
@@ -974,11 +1017,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ; Matchers.containsString("/api/core/communities")));
getClient().perform(delete("/api/core/communities/" + parentCommunity.getID().toString())) getClient().perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isUnauthorized()) .andExpect(status().isUnauthorized())
; ;
@@ -1007,11 +1051,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ; Matchers.containsString("/api/core/communities")));
getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString())) getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isNoContent()) .andExpect(status().isNoContent())
; ;
@@ -1041,12 +1086,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(), CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getHandle()) parentCommunity.getID(),
parentCommunity.getHandle())
))) )))
.andExpect(jsonPath("$", Matchers.not( .andExpect(jsonPath("$", Matchers.not(
Matchers.is( Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()) CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
) )
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -1077,7 +1124,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is( .andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry("Electronic theses and dissertations", CommunityMatcher.matchCommunityEntryFullProjection("Electronic theses and dissertations",
parentCommunity.getID(), parentCommunity.getID(),
parentCommunity.getHandle()) parentCommunity.getHandle())
))) )))

View File

@@ -56,6 +56,7 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
// we should check how to get it from Spring // we should check how to get it from Spring
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
EPersonRest data = new EPersonRest(); EPersonRest data = new EPersonRest();
EPersonRest dataFull = new EPersonRest();
MetadataRest metadataRest = new MetadataRest(); MetadataRest metadataRest = new MetadataRest();
data.setEmail("createtest@fake-email.com"); data.setEmail("createtest@fake-email.com");
data.setCanLogIn(true); data.setCanLogIn(true);
@@ -66,13 +67,18 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
firstname.setValue("John"); firstname.setValue("John");
metadataRest.put("eperson.firstname", firstname); metadataRest.put("eperson.firstname", firstname);
data.setMetadata(metadataRest); data.setMetadata(metadataRest);
dataFull.setEmail("createtestFull@fake-email.com");
dataFull.setCanLogIn(true);
dataFull.setMetadata(metadataRest);
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(post("/api/eperson/epersons") getClient(authToken).perform(post("/api/eperson/epersons")
.content(mapper.writeValueAsBytes(data)) .content(mapper.writeValueAsBytes(data))
.contentType(contentType)) .contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", EPersonMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf( .andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.uuid", not(empty())), hasJsonPath("$.uuid", not(empty())),
// is it what you expect? EPerson.getName() returns the email... // is it what you expect? EPerson.getName() returns the email...
@@ -86,6 +92,13 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
matchMetadata("eperson.firstname", "John"), matchMetadata("eperson.firstname", "John"),
matchMetadata("eperson.lastname", "Doe") matchMetadata("eperson.lastname", "Doe")
))))); )))));
getClient(authToken).perform(post("/api/eperson/epersons")
.content(mapper.writeValueAsBytes(dataFull))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()));
// TODO cleanup the context!!! // TODO cleanup the context!!!
} }

View File

@@ -44,17 +44,23 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
// hold the id of the created workflow item // hold the id of the created workflow item
AtomicReference<UUID> idRef = new AtomicReference<UUID>(); AtomicReference<UUID> idRef = new AtomicReference<UUID>();
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<UUID>();
try { try {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
GroupRest groupRest = new GroupRest(); GroupRest groupRest = new GroupRest();
GroupRest groupRestNoEmbeds = new GroupRest();
String groupName = "testGroup1"; String groupName = "testGroup1";
String groupNameNoEmbeds = "testGroup2";
groupRest.setName(groupName); groupRest.setName(groupName);
groupRestNoEmbeds.setName(groupNameNoEmbeds);
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(post("/api/eperson/groups") getClient(authToken).perform(post("/api/eperson/groups")
.content(mapper.writeValueAsBytes(groupRest)).contentType(contentType)) .content(mapper.writeValueAsBytes(groupRest)).contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$", GroupMatcher.matchFullEmbeds()))
.andDo(result -> idRef .andDo(result -> idRef
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id")))); .set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
@@ -66,9 +72,17 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
GroupMatcher.matchGroupWithName(groupName), GroupMatcher.matchGroupWithName(groupName),
GroupMatcher.matchGroupWithName("Administrator"), GroupMatcher.matchGroupWithName("Administrator"),
GroupMatcher.matchGroupWithName("Anonymous")))); GroupMatcher.matchGroupWithName("Anonymous"))));
getClient(authToken).perform(post("/api/eperson/groups")
.content(mapper.writeValueAsBytes(groupRestNoEmbeds)).contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRefNoEmbeds
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
} finally { } finally {
// remove the created group if any // remove the created group if any
GroupBuilder.deleteGroup(idRef.get()); GroupBuilder.deleteGroup(idRef.get());
GroupBuilder.deleteGroup(idRefNoEmbeds.get());
} }
} }

View File

@@ -98,8 +98,7 @@ public class ItemOwningCollectionUpdateRestControllerIT extends AbstractControll
//We expect a 401 Unauthorized status when performed by anonymous //We expect a 401 Unauthorized status when performed by anonymous
.andExpect(status().isOk()); .andExpect(status().isOk());
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection"))
.param("projection", "full"))
.andExpect(jsonPath("$", .andExpect(jsonPath("$",
is(CollectionMatcher is(CollectionMatcher
.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) .matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
@@ -152,8 +151,7 @@ public class ItemOwningCollectionUpdateRestControllerIT extends AbstractControll
//We expect a 401 Unauthorized status when performed by anonymous //We expect a 401 Unauthorized status when performed by anonymous
.andExpect(status().isOk()); .andExpect(status().isOk());
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection"))
.param("projection", "full"))
.andExpect(jsonPath("$", .andExpect(jsonPath("$",
is(CollectionMatcher is(CollectionMatcher
.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle()) .matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())

View File

@@ -1441,6 +1441,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
ItemRest itemRest = new ItemRest(); ItemRest itemRest = new ItemRest();
ItemRest itemRestFull = new ItemRest();
itemRest.setName("Practices of research data curation in institutional repositories:" + itemRest.setName("Practices of research data curation in institutional repositories:" +
" A qualitative view from repository staff"); " A qualitative view from repository staff");
itemRest.setInArchive(true); itemRest.setInArchive(true);
@@ -1454,11 +1455,25 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.put("dc.rights", new MetadataValueRest("Custom Copyright Text")) .put("dc.rights", new MetadataValueRest("Custom Copyright Text"))
.put("dc.title", new MetadataValueRest("Title Text"))); .put("dc.title", new MetadataValueRest("Title Text")));
itemRestFull.setName("Practices of research data curation in institutional repositories:" +
" A qualitative view from repository staff");
itemRestFull.setInArchive(true);
itemRestFull.setDiscoverable(true);
itemRestFull.setWithdrawn(false);
itemRestFull.setMetadata(new MetadataRest()
.put("dc.description", new MetadataValueRest("<p>Some cool HTML code here</p>"))
.put("dc.description.abstract", new MetadataValueRest("Sample item created via the REST API"))
.put("dc.description.tableofcontents", new MetadataValueRest("<p>HTML News</p>"))
.put("dc.rights", new MetadataValueRest("Custom Copyright Text"))
.put("dc.title", new MetadataValueRest("Title Text")));
String token = getAuthToken(admin.getEmail(), password); String token = getAuthToken(admin.getEmail(), password);
MvcResult mvcResult = getClient(token).perform(post("/api/core/items?owningCollection=" + MvcResult mvcResult = getClient(token).perform(post("/api/core/items?owningCollection=" +
col1.getID().toString()) col1.getID().toString())
.content(mapper.writeValueAsBytes(itemRest)).contentType(contentType)) .content(mapper.writeValueAsBytes(itemRest)).contentType(contentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andReturn(); .andReturn();
String content = mvcResult.getResponse().getContentAsString(); String content = mvcResult.getResponse().getContentAsString();
@@ -1487,6 +1502,13 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
MetadataMatcher.matchMetadata("dc.title", MetadataMatcher.matchMetadata("dc.title",
"Title Text") "Title Text")
))))); )))));
MvcResult mvcResultFull = getClient(token).perform(post("/api/core/items?owningCollection=" +
col1.getID().toString()).param("projection", "full")
.content(mapper.writeValueAsBytes(itemRestFull)).contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", ItemMatcher.matchFullEmbeds()))
.andReturn();
} }
@Test @Test

View File

@@ -62,12 +62,11 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build(); .build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1); // collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, col2); // collectionService.update(context, colAA2);
// itemService.update(context, publicItem1); // itemService.update(context, publicItem1);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()),
@@ -76,14 +75,12 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
; ;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))); )));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
@@ -124,8 +121,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
) )
); );
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()) CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle())
@@ -133,15 +129,13 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
; ;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))) )))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0))); .andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
@@ -184,8 +178,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
) )
); );
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -251,8 +244,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
) )
); );
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -307,8 +299,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
) )
); );
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle())
@@ -359,16 +350,14 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
) )
); );
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle())) CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()))
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
; ;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
@@ -378,30 +367,26 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken) getClient(adminToken)
.perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col2.getID())); .perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col2.getID()));
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()) CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle())
)))) ))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items"))); .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")));
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))) )))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0))); .andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))) )))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0))); .andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
@@ -411,8 +396,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken) getClient(adminToken)
.perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col1.getID())); .perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col1.getID()));
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -420,22 +404,19 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)))) ))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
; ;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))) )))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0))); .andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
))) )))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));; .andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));;
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems") getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains( .andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1)) ItemMatcher.matchItemProperties(publicItem1))
@@ -626,14 +607,13 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build(); .build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1); // collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, col2); // collectionService.update(context, colAA2);
// itemService.update(context, publicItem1); // itemService.update(context, publicItem1);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
context.setCurrentUser(null); context.setCurrentUser(null);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections") getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains( .andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()), CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()),
@@ -667,8 +647,8 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build(); .build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1); // collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, col2); // collectionService.update(context, colAA2);
// itemService.update(context, publicItem1); // itemService.update(context, publicItem1);
getClient().perform( getClient().perform(
@@ -704,8 +684,8 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build(); .build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1); // collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, col2); // collectionService.update(context, colAA2);
// itemService.update(context, publicItem1); // itemService.update(context, publicItem1);

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.builder.MetadataSchemaBuilder; import org.dspace.app.rest.builder.MetadataSchemaBuilder;
import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.matcher.MetadataschemaMatcher; import org.dspace.app.rest.matcher.MetadataschemaMatcher;
import org.dspace.app.rest.model.MetadataSchemaRest; import org.dspace.app.rest.model.MetadataSchemaRest;
import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.projection.Projection;
@@ -102,6 +103,7 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio
.content(new ObjectMapper().writeValueAsBytes(metadataSchemaRest)) .content(new ObjectMapper().writeValueAsBytes(metadataSchemaRest))
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
getClient().perform(get("/api/core/metadataschemas/" + idRef.get())) getClient().perform(get("/api/core/metadataschemas/" + idRef.get()))

View File

@@ -184,6 +184,7 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
getClient(authToken) getClient(authToken)
.perform(post("/api/core/metadatafields") .perform(post("/api/core/metadatafields")
.param("schemaId", metadataSchema.getID() + "") .param("schemaId", metadataSchema.getID() + "")
.param("projection", "full")
.content(new ObjectMapper().writeValueAsBytes(metadataFieldRest)) .content(new ObjectMapper().writeValueAsBytes(metadataFieldRest))
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())

View File

@@ -514,6 +514,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.param("relationshipType", .param("relationshipType",
isAuthorOfPublicationRelationshipType.getID() isAuthorOfPublicationRelationshipType.getID()
.toString()) .toString())
.param("projection", "full")
.contentType(MediaType.parseMediaType .contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes (org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE)) .TEXT_URI_LIST_VALUE))
@@ -523,6 +524,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
"https://localhost:8080/server/api/core/items/" + author1 "https://localhost:8080/server/api/core/items/" + author1
.getID())) .getID()))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$", RelationshipMatcher.matchFullEmbeds()))
.andReturn(); .andReturn();
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();

View File

@@ -38,7 +38,7 @@ import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.builder.GroupBuilder; import org.dspace.app.rest.builder.GroupBuilder;
import org.dspace.app.rest.builder.ItemBuilder; import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.builder.ResourcePolicyBuilder; import org.dspace.app.rest.builder.ResourcePolicyBuilder;
import org.dspace.app.rest.matcher.ResoucePolicyMatcher; import org.dspace.app.rest.matcher.ResourcePolicyMatcher;
import org.dspace.app.rest.model.ResourcePolicyRest; import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.AddOperation; import org.dspace.app.rest.model.patch.AddOperation;
import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.Operation;
@@ -122,7 +122,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID())) getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is( .andExpect(jsonPath("$", is(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy) ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy)
))) )))
.andExpect(jsonPath("$._links.self.href", Matchers .andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID()))); .containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID())));
@@ -236,8 +236,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID())) getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", is( .andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))));
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy))));
} }
@Test @Test
@@ -272,7 +271,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String authToken = getAuthToken(eperson1.getEmail(), "qwerty01"); String authToken = getAuthToken(eperson1.getEmail(), "qwerty01");
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID())) getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy)))); .andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))));
String authTokenEperson2 = getAuthToken(eperson2.getEmail(), "qwerty02"); String authTokenEperson2 = getAuthToken(eperson2.getEmail(), "qwerty02");
getClient(authTokenEperson2).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID())) getClient(authTokenEperson2).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
@@ -315,9 +314,9 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains( .andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson1)))) ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson1))))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson2))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString( .andExpect(jsonPath("$._links.self.href", Matchers.containsString(
"api/authz/resourcepolicies/search/eperson"))) "api/authz/resourcepolicies/search/eperson")))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -360,11 +359,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.param("resource", community.getID().toString())) .param("resource", community.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfCommunity), ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfCommunity),
ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfCommunity) ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfCommunity)
))) )))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfCollection))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfCollection)))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/eperson"))) Matchers.containsString("api/authz/resourcepolicies/search/eperson")))
.andExpect(jsonPath("$.page.totalElements", is(2))); .andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -497,11 +496,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson1), ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson1),
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyAnonymous) ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyAnonymous)
))) )))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/resource"))) Matchers.containsString("api/authz/resourcepolicies/search/resource")))
.andExpect(jsonPath("$.page.totalElements", is(2))); .andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -549,10 +548,10 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains( .andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2) ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)
))) )))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson2))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/resource"))) Matchers.containsString("api/authz/resourcepolicies/search/resource")))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -764,11 +763,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.containsInAnyOrder( Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1), ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1),
ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1), ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1),
ResoucePolicyMatcher.matchResourcePolicy(collectionResourcePolicyOfGroup1)))) ResourcePolicyMatcher.matchResourcePolicy(collectionResourcePolicyOfGroup1))))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2)))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group"))) Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(3))); .andExpect(jsonPath("$.page.totalElements", is(3)));
@@ -780,7 +779,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.contains( Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2)))) ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group"))) Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -819,9 +818,9 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.param("resource", community.getID().toString())) .param("resource", community.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.contains(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1)))) Matchers.contains(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1))))
.andExpect(jsonPath("$._embedded.resourcepolicies", .andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1))))) Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1)))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group"))) Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -971,9 +970,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.content(mapper.writeValueAsBytes(resourcePolicyRest)) .content(mapper.writeValueAsBytes(resourcePolicyRest))
.param("resource", community.getID().toString()) .param("resource", community.getID().toString())
.param("eperson", eperson1.getID().toString()) .param("eperson", eperson1.getID().toString())
.param("projections", "full")
.contentType(contentType)) .contentType(contentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", ResourcePolicyMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf( .andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.name", is(resourcePolicyRest.getName())), hasJsonPath("$.name", is(resourcePolicyRest.getName())),
hasJsonPath("$.description", is(resourcePolicyRest.getDescription())), hasJsonPath("$.description", is(resourcePolicyRest.getDescription())),
@@ -1156,7 +1157,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String token = getAuthToken(admin.getEmail(), password); String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID())) getClient(token).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy)))) .andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))))
.andExpect(jsonPath("$._links.self.href", Matchers .andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID()))); .containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID())));
} }

View File

@@ -1439,7 +1439,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest {
.withName("Sub Community") .withName("Sub Community")
.build(); .build();
// the reviewer2 is a reviewer in a different step for the col1 and with the same role than reviewer1 for // the reviewer2 is a reviewer in a different step for the colAA1 and with the same role than reviewer1 for
// another collection // another collection
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1")
.withWorkflowGroup(1, reviewer1) .withWorkflowGroup(1, reviewer1)
@@ -1613,7 +1613,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest {
.withName("Sub Community") .withName("Sub Community")
.build(); .build();
// the reviewer2 is a reviewer in a different step for the col1 and with the same role than reviewer1 for // the reviewer2 is a reviewer in a different step for the colAA1 and with the same role than reviewer1 for
// another collection // another collection
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1")
.withWorkflowGroup(1, reviewer1) .withWorkflowGroup(1, reviewer1)

View File

@@ -0,0 +1,128 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.matcher.WorkflowActionMatcher;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.repository.WorkflowActionRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowActionRestRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL;
@Test
public void getAllWorkflowActions_NonImplementedEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 405 Method not allowed status
.andExpect(status().isMethodNotAllowed());
}
@Test
public void getAllWorkflowActions_NonImplementedEndpoint_NonValidToken() throws Exception {
String token = "nonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowActions_NonImplementedEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowActionByName_NonExistentWorkflowAction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameNonExistentWorkflowActionName = "TestNameNonExistentWorkflowAction9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameNonExistentWorkflowActionName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_editaction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 200 is ok status
.andExpect(status().isOk())
// has options
.andExpect(jsonPath("$.options", not(empty())))
//Matches expected corresponding rest action values
.andExpect(jsonPath("$", Matchers.is(
WorkflowActionMatcher.matchWorkflowActionEntry(existentWorkflow)
)));
}
@Test
public void getWorkflowActionByName_ExistentWithoutOptions_claimaction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameActionWithoutOptions = "claimaction";
WorkflowActionConfig existentWorkflowNoOptions = xmlWorkflowFactory.getActionByName(nameActionWithoutOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithoutOptions))
//We expect a 200 is ok status
.andExpect(status().isOk())
// has no options
.andExpect(jsonPath("$.options", empty()))
//Matches expected corresponding rest action values
.andExpect(jsonPath("$", Matchers.is(
WorkflowActionMatcher.matchWorkflowActionEntry(existentWorkflowNoOptions)
)));
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_NonValidToken() throws Exception {
String token = "nonValidToken";
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_NoToken() throws Exception {
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
}

View File

@@ -0,0 +1,458 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.matcher.WorkflowDefinitionMatcher;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.repository.WorkflowDefinitionRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowDefinitionRestRepository}
* and {@link WorkflowDefinitionCollectionsLinkRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 17/12/2019
*/
public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_DEFINITIONS_ENDPOINT
= "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL;
@Test
public void getAllWorkflowDefinitionsEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_Pagination_Size1() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT)
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(0))
)))
//Doesn't contain the other workflows
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.not(
Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(1))
)
)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_Pagination_Size1_Page1() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT)
.param("size", "1")
.param("page", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 2
.andExpect(jsonPath("$.page.number", is(1)))
//Contains only the second configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(1))
)))
//Doesn't contain 1st configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.not(
Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(0))
)
)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_NonValidToken() throws Exception {
String token = "NonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowDefinitionsEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 200 OK status
.andExpect(status().isOk())
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)))
// its name is default
.andExpect(jsonPath("$.name", equalToIgnoringCase(workflowName)))
// is default
.andExpect(jsonPath("$.isDefault", is(true)));
}
@Test
public void getWorkflowDefinitionByName_NonDefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
String firstNonDefaultWorkflowName = "";
for (Workflow workflow : allConfiguredWorkflows) {
if (!workflow.getID().equalsIgnoreCase(defaultWorkflow.getID())) {
firstNonDefaultWorkflowName = workflow.getID();
}
}
if (StringUtils.isNotBlank(firstNonDefaultWorkflowName)) {
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + firstNonDefaultWorkflowName))
//We expect a 200 OK status
.andExpect(status().isOk())
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)))
// its name is name of non-default workflow
.andExpect(jsonPath("$.name", equalToIgnoringCase(firstNonDefaultWorkflowName)))
// is not default
.andExpect(jsonPath("$.isDefault", is(false)));
}
}
@Test
public void getWorkflowDefinitionByName_NonExistentWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String workflowName = "TestNameNonExistentWorkflow9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow_NonValidToken() throws Exception {
String token = "UnvalidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowDefinitionByCollectionId_ExistentCollection() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
context.restoreAuthSystemState();
Workflow workflowForThisCollection = xmlWorkflowFactory.getWorkflow(col1);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid=" + col1.getID()))
//We expect a 200 OK status
.andExpect(status().isOk())
// its name is name of corresponding workflow
.andExpect(jsonPath("$.name", equalToIgnoringCase(workflowForThisCollection.getID())));
}
@Test
public void getWorkflowDefinitionByCollectionId_nonValidUUID() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nonValidUUID = "TestNonValidUUID";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid=" + nonValidUUID))
//We expect a 400 Illegal Argument Exception (Bad Request) cannot convert UUID
.andExpect(status().isBadRequest())
.andExpect(status().reason(containsString("Failed to convert " + nonValidUUID)));
}
@Test
public void getWorkflowDefinitionByCollectionId_nonExistentCollection() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
UUID nonExistentCollectionUUID = UUID.randomUUID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid="
+ nonExistentCollectionUUID))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of non-mapped collections
.andExpect(jsonPath("$.page.totalElements", is(allNonMappedCollections.size())));
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections_Paginated_Size1()
throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 1")
.build();
Collection col2 = CollectionBuilder.createCollection(context, child1, "123456789/non-mapped-collection")
.withName("Collection 2")
.build();
context.restoreAuthSystemState();
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
if (allNonMappedCollections.size() > 0) {
Collection firstNonMappedCollection = allNonMappedCollections.get(0);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections")
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allNonMappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first non-mapped collection
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstNonMappedCollection.getName(),
firstNonMappedCollection.getID(), firstNonMappedCollection.getHandle())
)));
}
}
@Test
public void getCollectionsOfWorkflowByName_NonDefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
// Collection with handle used in workflow.xml!
Collection col1 = CollectionBuilder.createCollection(context, child1, "123456789/workflow-test-1")
.withName("Collection 1")
.build();
context.restoreAuthSystemState();
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
String firstNonDefaultWorkflowName = "";
for (Workflow workflow : allConfiguredWorkflows) {
if (!workflow.getID().equalsIgnoreCase(defaultWorkflow.getID())) {
firstNonDefaultWorkflowName = workflow.getID();
}
}
if (StringUtils.isNotBlank(firstNonDefaultWorkflowName)) {
List<Collection> mappedCollections
= xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context, firstNonDefaultWorkflowName);
//When we call this facets endpoint
if (mappedCollections.size() > 0) {
//returns array of collection jsons that are mapped to given workflow
//When we call this facets endpoint
Collection firstMappedCollection = mappedCollections.get(0);
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + firstNonDefaultWorkflowName
+ "/collections")
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(mappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first mapped collection
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstMappedCollection.getName(),
firstMappedCollection.getID(), firstMappedCollection.getHandle())
)));
} else {
//no collections mapped to this workflow
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/"
+ firstNonDefaultWorkflowName + "/collections"))
//We expect a 200 OK status
.andExpect(status().isOk())
//results in empty list
.andExpect(jsonPath("$._embedded.collections", empty()));
}
}
}
@Test
public void getCollectionsOfWorkflowByName_NonExistentWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String workflowName = "TestNameNonExistentWorkflow9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName + "/collections"))
//We expect a 404 Not Found
.andExpect(status().isNotFound());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_NoValidToken() throws Exception {
String token = "NonValidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps")
.param("projection", "full"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of non-mapped collections
.andExpect(jsonPath("$.page.totalElements", is(defaultWorkflow.getSteps().size())));
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow_NoValidToken() throws Exception {
String token = "NonValidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps"))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps"))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
}

View File

@@ -458,8 +458,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/collection") getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/collection"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers .andExpect(jsonPath("$", Matchers
.is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())))); .is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()))));
@@ -767,6 +766,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
// submit the workspaceitem to start the workflow // submit the workspaceitem to start the workflow
getClient(authToken) getClient(authToken)
.perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems") .perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
.param("projection", "full")
.content("/api/submission/workspaceitems/" + wsitem.getID()) .content("/api/submission/workspaceitems/" + wsitem.getID())
.contentType(textUriContentType)) .contentType(textUriContentType))
.andExpect(status().isCreated()) .andExpect(status().isCreated())

View File

@@ -0,0 +1,87 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.matcher.WorkflowStepMatcher;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.repository.WorkflowStepRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Step;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowStepRestRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 13/01/2020
*/
public class WorkflowStepRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL;
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 405 Method not allowed status
.andExpect(status().isMethodNotAllowed());
}
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint_NonValidToken() throws Exception {
String token = "NonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowStepByName_NonExistentWorkflowStep() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameNonExistentWorkflowActionName = "TestNameNonExistentWorkflowStep9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameNonExistentWorkflowActionName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowStepByName_ExistentStep_reviewstep() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameStep = "reviewstep";
Step existentStep = xmlWorkflowFactory.getStepByName(nameStep);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameStep)
.param("projection", "full"))
//We expect a 200 is ok status
.andExpect(status().isOk())
//Matches expected step
.andExpect(jsonPath("$", Matchers.is(
WorkflowStepMatcher.matchWorkflowStepEntry(existentStep)
)));
}
}

View File

@@ -283,8 +283,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
String token = getAuthToken(admin.getEmail(), password); String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/collection") getClient(token).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/collection"))
.param("projection", "full"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers .andExpect(jsonPath("$", Matchers
.is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())) .is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()))
@@ -492,14 +491,14 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
// create a workspaceitem explicitly in the col1 // create a workspaceitem explicitly in the colAA1
getClient(authToken).perform(post("/api/submission/workspaceitems") getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("owningCollection", col1.getID().toString()) .param("owningCollection", col1.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON)) .contentType(org.springframework.http.MediaType.APPLICATION_JSON))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString()))); .andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString())));
// create a workspaceitem explicitly in the col2 // create a workspaceitem explicitly in the colAA2
getClient(authToken).perform(post("/api/submission/workspaceitems") getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("owningCollection", col2.getID().toString()) .param("owningCollection", col2.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON)) .contentType(org.springframework.http.MediaType.APPLICATION_JSON))
@@ -508,10 +507,11 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
// create a workspaceitem without an explicit collection, this will go in the first valid collection for the // create a workspaceitem without an explicit collection, this will go in the first valid collection for the
// user: the col1 // user: the col1
getClient(authToken).perform(post("/api/submission/workspaceitems") getClient(authToken).perform(post("/api/submission/workspaceitems").param("projection", "full")
.contentType(org.springframework.http.MediaType.APPLICATION_JSON)) .contentType(org.springframework.http.MediaType.APPLICATION_JSON))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString()))); .andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString())))
.andExpect(jsonPath("$", WorkspaceItemMatcher.matchFullEmbeds()));
// TODO cleanup the context!!! // TODO cleanup the context!!!
} }
@@ -542,7 +542,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
final MockMultipartFile bibtexFile = new MockMultipartFile("file", "bibtex-test.bib", "application/x-bibtex", final MockMultipartFile bibtexFile = new MockMultipartFile("file", "bibtex-test.bib", "application/x-bibtex",
bibtex); bibtex);
// bulk create workspaceitems in the default collection (col1) // bulk create workspaceitems in the default collection (colAA1)
getClient(authToken).perform(fileUpload("/api/submission/workspaceitems") getClient(authToken).perform(fileUpload("/api/submission/workspaceitems")
.file(bibtexFile)) .file(bibtexFile))
// bulk create should return 200, 201 (created) is better for single resource // bulk create should return 200, 201 (created) is better for single resource
@@ -563,7 +563,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
jsonPath("$._embedded.workspaceitems[*]._embedded.upload").doesNotExist()) jsonPath("$._embedded.workspaceitems[*]._embedded.upload").doesNotExist())
; ;
// bulk create workspaceitems explicitly in the col2 // bulk create workspaceitems explicitly in the colAA2
getClient(authToken).perform(fileUpload("/api/submission/workspaceitems") getClient(authToken).perform(fileUpload("/api/submission/workspaceitems")
.file(bibtexFile) .file(bibtexFile)
.param("collection", col2.getID().toString())) .param("collection", col2.getID().toString()))
@@ -681,7 +681,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
))))) )))))
; ;
// create an empty workspaceitem explicitly in the col1, check validation on creation // create an empty workspaceitem explicitly in the colAA1, check validation on creation
getClient(authToken).perform(post("/api/submission/workspaceitems") getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("collection", col1.getID().toString()) .param("collection", col1.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON)) .contentType(org.springframework.http.MediaType.APPLICATION_JSON))

View File

@@ -42,6 +42,13 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder<Collection> {
return builder.create(parent); return builder.create(parent);
} }
public static CollectionBuilder createCollection(final Context context,
final Community parent,
final String handle) {
CollectionBuilder builder = new CollectionBuilder(context);
return builder.create(parent, handle);
}
private CollectionBuilder create(final Community parent) { private CollectionBuilder create(final Community parent) {
try { try {
this.collection = collectionService.create(context, parent); this.collection = collectionService.create(context, parent);
@@ -51,6 +58,20 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder<Collection> {
return this; return this;
} }
private CollectionBuilder create(final Community parent, final String handle) {
try {
for (Collection collection : this.collectionService.findAll(context)) {
if (collection.getHandle().equalsIgnoreCase(handle)) {
this.collection = collection;
}
}
this.collection = this.collectionService.create(context, parent, handle);
} catch (Exception e) {
return handleException(e);
}
return this;
}
public CollectionBuilder withName(final String name) { public CollectionBuilder withName(final String name) {
return setMetadataSingleValue(collection, MetadataSchemaEnum.DC.getName(), "title", null, name); return setMetadataSingleValue(collection, MetadataSchemaEnum.DC.getName(), "title", null, name);
} }

View File

@@ -74,6 +74,12 @@ public class CommunityBuilder extends AbstractDSpaceObjectBuilder<Community> {
return this; return this;
} }
public CommunityBuilder addParentCommunity(final Context context, final Community parent)
throws SQLException, AuthorizeException {
communityService.addSubcommunity(context, parent, community);
return this;
}
@Override @Override
public Community build() { public Community build() {
try { try {

View File

@@ -75,5 +75,4 @@ public class BitstreamFormatMatcher {
hasJsonPath("$.type", is("bitstreamformat")) hasJsonPath("$.type", is("bitstreamformat"))
); );
} }
} }

View File

@@ -31,8 +31,22 @@ public class CollectionMatcher {
public static Matcher<? super Object> matchCollectionEntry(String name, UUID uuid, String handle, Bitstream logo) { public static Matcher<? super Object> matchCollectionEntry(String name, UUID uuid, String handle, Bitstream logo) {
return allOf( return allOf(
matchProperties(name, uuid, handle), matchProperties(name, uuid, handle),
matchLinks(uuid), matchLinks(uuid)
matchLogo(logo) );
}
public static Matcher<? super Object> matchCollectionEntryFullProjection(String name, UUID uuid, String handle) {
return matchCollectionEntryFullProjection(name, uuid, handle, null);
}
public static Matcher<? super Object> matchCollectionEntryFullProjection(String name, UUID uuid, String handle,
Bitstream logo) {
return allOf(
matchProperties(name, uuid, handle),
matchLinks(uuid),
matchLogo(logo),
matchFullEmbeds()
); );
} }
@@ -54,6 +68,7 @@ public class CollectionMatcher {
return matchEmbeds( return matchEmbeds(
"license", "license",
"logo", "logo",
"parentCommunity",
"mappedItems[]" "mappedItems[]"
); );
} }
@@ -68,6 +83,7 @@ public class CollectionMatcher {
"license", "license",
"logo", "logo",
"mappedItems", "mappedItems",
"parentCommunity",
"self" "self"
); );
} }

View File

@@ -31,8 +31,6 @@ public class CommunityMatcher {
hasJsonPath("$.uuid", is(uuid.toString())), hasJsonPath("$.uuid", is(uuid.toString())),
hasJsonPath("$.handle", is(handle)), hasJsonPath("$.handle", is(handle)),
hasJsonPath("$.type", is("community")), hasJsonPath("$.type", is("community")),
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
hasJsonPath("$._embedded.logo", Matchers.not(Matchers.empty())),
matchLinks(uuid) matchLinks(uuid)
); );
} }
@@ -53,6 +51,13 @@ public class CommunityMatcher {
} }
public static Matcher<? super Object> matchCommunityEntry(String name, UUID uuid, String handle) { public static Matcher<? super Object> matchCommunityEntry(String name, UUID uuid, String handle) {
return allOf(
matchProperties(name, uuid, handle),
matchLinks(uuid)
);
}
public static Matcher<? super Object> matchCommunityEntryFullProjection(String name, UUID uuid, String handle) {
return allOf( return allOf(
matchProperties(name, uuid, handle), matchProperties(name, uuid, handle),
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())), hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
@@ -80,6 +85,7 @@ public class CommunityMatcher {
return matchEmbeds( return matchEmbeds(
"collections[]", "collections[]",
"logo", "logo",
"parentCommunity",
"subcommunities[]" "subcommunities[]"
); );
} }
@@ -92,6 +98,7 @@ public class CommunityMatcher {
"collections", "collections",
"logo", "logo",
"self", "self",
"parentCommunity",
"subcommunities" "subcommunities"
); );
} }

View File

@@ -8,6 +8,7 @@
package org.dspace.app.rest.matcher; package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@@ -48,4 +49,13 @@ public class RelationshipMatcher {
RelationshipTypeMatcher.matchRelationshipTypeEntry(relationshipType)) RelationshipTypeMatcher.matchRelationshipTypeEntry(relationshipType))
); );
} }
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"relationshipType"
);
}
} }

View File

@@ -10,6 +10,7 @@ package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@@ -24,9 +25,9 @@ import org.hamcrest.Matcher;
* @author Mykhaylo Boychuk (4science.it) * @author Mykhaylo Boychuk (4science.it)
* *
*/ */
public class ResoucePolicyMatcher { public class ResourcePolicyMatcher {
private ResoucePolicyMatcher() { private ResourcePolicyMatcher() {
} }
public static Matcher<? super Object> matchResourcePolicy(ResourcePolicy resourcePolicy) { public static Matcher<? super Object> matchResourcePolicy(ResourcePolicy resourcePolicy) {
@@ -52,4 +53,15 @@ public class ResoucePolicyMatcher {
); );
} }
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"eperson",
"group",
"resource"
);
}
} }

View File

@@ -0,0 +1,38 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.hamcrest.Matcher;
/**
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionMatcher {
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL + "/";
private WorkflowActionMatcher() {
}
public static Matcher<? super Object> matchWorkflowActionEntry(WorkflowActionConfig workflowAction) {
return allOf(
hasJsonPath("$.id", is(workflowAction.getId())),
hasJsonPath("$.options", is(workflowAction.getOptions())),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_ACTIONS_ENDPOINT + workflowAction.getId()))
);
}
}

View File

@@ -0,0 +1,65 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import java.util.UUID;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
/**
* @author Maria Verdonck (Atmire) on 03/01/2020
*/
public class WorkflowDefinitionMatcher {
private static XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_DEFINITIONS_ENDPOINT
= "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL + "/";
private WorkflowDefinitionMatcher() {
}
public static Matcher<? super Object> matchWorkflowDefinitionEntry(Workflow workflow) {
return allOf(
hasJsonPath("$.name", is(workflow.getID())),
hasJsonPath("$.isDefault", is(xmlWorkflowFactory.isDefaultWorkflow(workflow.getID()))),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT + workflow.getID()))
);
}
public static Matcher<? super Object> matchWorkflowOnWorkflowName(String workflowName) {
return allOf(
hasJsonPath("$.name", is(workflowName)),
hasJsonPath("$.isDefault", is(xmlWorkflowFactory.isDefaultWorkflow(workflowName))),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT + workflowName))
);
}
public static Matcher<? super Object> matchCollectionEntry(String name, UUID uuid, String handle) {
return allOf(
hasJsonPath("$.uuid", is(uuid.toString())),
hasJsonPath("$.name", is(name)),
hasJsonPath("$.handle", is(handle)),
hasJsonPath("$.type", is("collection")),
hasJsonPath("$.metadata", Matchers.allOf(
MetadataMatcher.matchMetadata("dc.title", name)
))
);
}
}

View File

@@ -0,0 +1,46 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.xmlworkflow.state.Step;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
/**
* @author Maria Verdonck (Atmire) on 13/01/2020
*/
public class WorkflowStepMatcher {
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL + "/";;
private WorkflowStepMatcher() {}
public static Matcher<? super Object> matchWorkflowStepEntry(Step workflowStep) {
return allOf(
hasJsonPath("$.id", is(workflowStep.getId())),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_ACTIONS_ENDPOINT + workflowStep.getId())),
hasJsonPath("$._embedded.workflowactions._embedded.workflowactions", Matchers.containsInAnyOrder(
workflowStep.getActions()
.stream()
.map(x -> WorkflowActionMatcher.matchWorkflowActionEntry(x))
.collect(Collectors.toList())
))
);
}
}

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL; import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL;
import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@@ -127,4 +128,16 @@ public class WorkspaceItemMatcher {
hasJsonPath("$._links.submissionDefinition.href", startsWith(REST_SERVER_URL))); hasJsonPath("$._links.submissionDefinition.href", startsWith(REST_SERVER_URL)));
} }
} }
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"collection",
"item",
"submitter",
"submissionDefinition"
);
}
} }