mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 23:13:10 +00:00
Merge pull request #2614 from atmire/feature-external-sources-entities-post-workspace-item
Creating a workspace item from an external source
This commit is contained in:
@@ -13,7 +13,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.WorkspaceItem;
|
||||||
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;
|
||||||
@@ -66,8 +66,7 @@ public interface ExternalDataService {
|
|||||||
public int getNumberOfResults(String source, String query);
|
public int getNumberOfResults(String source, String query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will create an Item in the given Collection based on the given ExternalDataObject.
|
* This method will create a WorkspaceItem in the given Collection based on the given ExternalDataObject.
|
||||||
* Note that this Item will be Archived
|
|
||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param externalDataObject The relevant ExternalDataObject to be used
|
* @param externalDataObject The relevant ExternalDataObject to be used
|
||||||
* @param collection The Collection in which the item will be present
|
* @param collection The Collection in which the item will be present
|
||||||
@@ -75,6 +74,7 @@ public interface ExternalDataService {
|
|||||||
* @throws AuthorizeException If something goes wrong
|
* @throws AuthorizeException If something goes wrong
|
||||||
* @throws SQLException If something goes wrong
|
* @throws SQLException If something goes wrong
|
||||||
*/
|
*/
|
||||||
Item createItemFromExternalDataObject(Context context, ExternalDataObject externalDataObject, Collection collection)
|
WorkspaceItem createWorkspaceItemFromExternalDataObject(Context context, ExternalDataObject externalDataObject,
|
||||||
|
Collection collection)
|
||||||
throws AuthorizeException, SQLException;
|
throws AuthorizeException, SQLException;
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.dto.MetadataValueDTO;
|
import org.dspace.content.dto.MetadataValueDTO;
|
||||||
import org.dspace.content.service.InstallItemService;
|
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -44,9 +43,6 @@ public class ExternalDataServiceImpl implements ExternalDataService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WorkspaceItemService workspaceItemService;
|
private WorkspaceItemService workspaceItemService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private InstallItemService installItemService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AuthorizeService authorizeService;
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
@@ -95,8 +91,9 @@ public class ExternalDataServiceImpl implements ExternalDataService {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item createItemFromExternalDataObject(Context context, ExternalDataObject externalDataObject,
|
public WorkspaceItem createWorkspaceItemFromExternalDataObject(Context context,
|
||||||
Collection collection)
|
ExternalDataObject externalDataObject,
|
||||||
|
Collection collection)
|
||||||
throws AuthorizeException, SQLException {
|
throws AuthorizeException, SQLException {
|
||||||
if (!authorizeService.isAdmin(context)) {
|
if (!authorizeService.isAdmin(context)) {
|
||||||
throw new AuthorizeException("You have to be an admin to create an Item from an ExternalDataObject");
|
throw new AuthorizeException("You have to be an admin to create an Item from an ExternalDataObject");
|
||||||
@@ -113,6 +110,6 @@ public class ExternalDataServiceImpl implements ExternalDataService {
|
|||||||
log.info(LogManager.getHeader(context, "create_item_from_externalDataObject", "Created item" +
|
log.info(LogManager.getHeader(context, "create_item_from_externalDataObject", "Created item" +
|
||||||
"with id: " + item.getID() + " from source: " + externalDataObject.getSource() + " with identifier: " +
|
"with id: " + item.getID() + " from source: " + externalDataObject.getSource() + " with identifier: " +
|
||||||
externalDataObject.getId()));
|
externalDataObject.getId()));
|
||||||
return installItemService.installItem(context, workspaceItem);
|
return workspaceItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,11 +26,13 @@ import org.dspace.app.rest.Parameter;
|
|||||||
import org.dspace.app.rest.SearchRestMethod;
|
import org.dspace.app.rest.SearchRestMethod;
|
||||||
import org.dspace.app.rest.converter.WorkspaceItemConverter;
|
import org.dspace.app.rest.converter.WorkspaceItemConverter;
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
|
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||||
import org.dspace.app.rest.model.ErrorRest;
|
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.projection.Projection;
|
||||||
|
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;
|
||||||
import org.dspace.app.rest.submit.UploadableStep;
|
import org.dspace.app.rest.submit.UploadableStep;
|
||||||
@@ -109,6 +111,9 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
@Autowired
|
@Autowired
|
||||||
CollectionService collectionService;
|
CollectionService collectionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UriListHandlerService uriListHandlerService;
|
||||||
|
|
||||||
private SubmissionConfigReader submissionConfigReader;
|
private SubmissionConfigReader submissionConfigReader;
|
||||||
|
|
||||||
public WorkspaceItemRestRepository() throws SubmissionConfigReaderException {
|
public WorkspaceItemRestRepository() throws SubmissionConfigReaderException {
|
||||||
@@ -481,4 +486,14 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WorkspaceItemRest createAndReturn(Context context, List<String> stringList)
|
||||||
|
throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException {
|
||||||
|
|
||||||
|
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
|
||||||
|
WorkspaceItem workspaceItem = uriListHandlerService.handle(context, req, stringList, WorkspaceItem.class);
|
||||||
|
return converter.toRest(workspaceItem, Projection.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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.repository.handler;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.WorkspaceItem;
|
||||||
|
import org.dspace.content.service.InstallItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will handle ExternalSourceEntryUriList and it'll create Item objects based on them.
|
||||||
|
* This will create Archived items and thus only Admin users can use it
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ExternalSourceEntryArchivedItemUriListHandler extends ExternalSourceEntryItemUriListHandler<Item> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InstallItemService installItemService;
|
||||||
|
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
|
.getLogger(ExternalSourceEntryItemUriListHandler.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(List<String> uriList, String method, Class clazz) {
|
||||||
|
if (!super.supports(uriList, method, clazz)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (clazz != Item.class) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
|
throws AuthorizeException {
|
||||||
|
if (!super.validate(context, request, uriList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (!authorizeService.isAdmin(context)) {
|
||||||
|
throw new AuthorizeException("Only admins are allowed to create items using external data");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("context isAdmin check resulted in an error", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item handle(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
String owningCollectionUuid = request.getParameter("owningCollection");
|
||||||
|
try {
|
||||||
|
WorkspaceItem workspaceItem = super.createWorkspaceItem(context, request, uriList);
|
||||||
|
return installItemService.installItem(context, workspaceItem);
|
||||||
|
} catch (AuthorizeException | SQLException e) {
|
||||||
|
log.error("An error occured when trying to create item in collection with uuid: " + owningCollectionUuid,
|
||||||
|
e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -21,29 +21,25 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.model.ExternalSourceRest;
|
import org.dspace.app.rest.model.ExternalSourceRest;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.WorkspaceItem;
|
||||||
import org.dspace.content.service.CollectionService;
|
import org.dspace.content.service.CollectionService;
|
||||||
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.service.ExternalDataService;
|
import org.dspace.external.service.ExternalDataService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class will handle ExternalSourceEntryUriList and it'll create Item objects based on them
|
* This provides an abstract class for the Item and WorkspaceItemUriListHandlers to extend and provide shared logic
|
||||||
|
* to reduce code duplication
|
||||||
|
* @param <T> The type of Object we're dealing with
|
||||||
*/
|
*/
|
||||||
@Component
|
public abstract class ExternalSourceEntryItemUriListHandler<T> implements UriListHandler<T> {
|
||||||
public class ExternalSourceEntryUriListHandler implements UriListHandler<Item> {
|
|
||||||
|
|
||||||
private List<RequestMethod> allowedRequestMethods = new LinkedList<>(Arrays.asList(RequestMethod.POST));
|
private List<RequestMethod> allowedRequestMethods = new LinkedList<>(Arrays.asList(RequestMethod.POST));
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AuthorizeService authorizeService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ExternalDataService externalDataService;
|
private ExternalDataService externalDataService;
|
||||||
|
|
||||||
@@ -51,11 +47,10 @@ public class ExternalSourceEntryUriListHandler implements UriListHandler<Item> {
|
|||||||
private CollectionService collectionService;
|
private CollectionService collectionService;
|
||||||
|
|
||||||
private static final Logger log = org.apache.logging.log4j.LogManager
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
.getLogger(ExternalSourceEntryUriListHandler.class);
|
.getLogger(ExternalSourceEntryItemUriListHandler.class);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(List<String> uriList, String method) {
|
public boolean supports(List<String> uriList, String method, Class clazz) {
|
||||||
if (!allowedRequestMethods.contains(RequestMethod.valueOf(method))) {
|
if (!allowedRequestMethods.contains(RequestMethod.valueOf(method))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -69,22 +64,16 @@ public class ExternalSourceEntryUriListHandler implements UriListHandler<Item> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Context context, HttpServletRequest request, List<String> uriList,
|
public boolean validate(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
Class clazz) throws AuthorizeException {
|
throws AuthorizeException {
|
||||||
if (uriList.size() > 1) {
|
if (uriList.size() > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (clazz != Item.class) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String owningCollectionString = request.getParameter("owningCollection");
|
String owningCollectionString = request.getParameter("owningCollection");
|
||||||
if (StringUtils.isBlank(owningCollectionString)) {
|
if (StringUtils.isBlank(owningCollectionString)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!authorizeService.isAdmin(context)) {
|
|
||||||
throw new AuthorizeException("Only admins are allowed to create items using external data");
|
|
||||||
}
|
|
||||||
Collection collection = collectionService.find(context, UUID.fromString(owningCollectionString));
|
Collection collection = collectionService.find(context, UUID.fromString(owningCollectionString));
|
||||||
if (collection == null) {
|
if (collection == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -97,23 +86,30 @@ public class ExternalSourceEntryUriListHandler implements UriListHandler<Item> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Item handle(Context context, HttpServletRequest request, List<String> uriList)
|
* This method will create a WorkspaceItem made from the ExternalDataObject that will be created from the given
|
||||||
|
* uriList. The Collection for the WorkspaceItem will be retrieved through the request.
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param request The relevant Request
|
||||||
|
* @param uriList The uriList that contains the data for the ExternalDataObject
|
||||||
|
* @return A WorkspaceItem created from the given information
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
public WorkspaceItem createWorkspaceItem(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
throws SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException {
|
||||||
ExternalDataObject dataObject = getExternalDataObjectFromUriList(uriList);
|
ExternalDataObject dataObject = getExternalDataObjectFromUriList(uriList);
|
||||||
|
|
||||||
String owningCollectionUuid = request.getParameter("owningCollection");
|
String owningCollectionUuid = request.getParameter("owningCollection");
|
||||||
Collection collection = null;
|
|
||||||
Item item = null;
|
|
||||||
try {
|
try {
|
||||||
collection = collectionService.find(context, UUID.fromString(owningCollectionUuid));
|
Collection collection = collectionService.find(context, UUID.fromString(owningCollectionUuid));
|
||||||
item = externalDataService.createItemFromExternalDataObject(context, dataObject, collection);
|
return externalDataService.createWorkspaceItemFromExternalDataObject(context, dataObject, collection);
|
||||||
} catch (AuthorizeException | SQLException e) {
|
} catch (AuthorizeException | SQLException e) {
|
||||||
log.error("An error occured when trying to create item in collection with uuid: " + owningCollectionUuid,
|
log.error("An error occured when trying to create item in collection with uuid: " + owningCollectionUuid,
|
||||||
e);
|
e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,5 +134,4 @@ public class ExternalSourceEntryUriListHandler implements UriListHandler<Item> {
|
|||||||
"Couldn't find an ExternalSource for source: " + externalSourceIdentifer + " and ID: " + id));
|
"Couldn't find an ExternalSource for source: " + externalSourceIdentifer + " and ID: " + id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* 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.handler;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.WorkspaceItem;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class extends the {@link ExternalSourceEntryItemUriListHandler} abstract class and implements it specifically
|
||||||
|
* for the WorkspaceItem objects. It'll add extra checks and validations based on a WorkspaceItem and call the super
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ExternalSourceEntryWorkspaceItemUriListHandler
|
||||||
|
extends ExternalSourceEntryItemUriListHandler<WorkspaceItem> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(List<String> uriList, String method, Class clazz) {
|
||||||
|
if (!super.supports(uriList, method, clazz)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (clazz != WorkspaceItem.class) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
|
throws AuthorizeException {
|
||||||
|
|
||||||
|
if (!super.validate(context, request, uriList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorkspaceItem handle(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
|
throws SQLException, AuthorizeException {
|
||||||
|
return super.createWorkspaceItem(context, request, uriList);
|
||||||
|
}
|
||||||
|
}
|
@@ -25,9 +25,10 @@ public interface UriListHandler<T> {
|
|||||||
* can handle this input or not
|
* can handle this input or not
|
||||||
* @param uriList The list of UriList Strings to be checked if they're supported
|
* @param uriList The list of UriList Strings to be checked if they're supported
|
||||||
* @param method The request method to be checked if it's supported
|
* @param method The request method to be checked if it's supported
|
||||||
|
* @param clazz The class to be returned by the handle method
|
||||||
* @return A boolean indicating whether the implementing UriListHandler can handle this input
|
* @return A boolean indicating whether the implementing UriListHandler can handle this input
|
||||||
*/
|
*/
|
||||||
boolean supports(List<String> uriList, String method);
|
boolean supports(List<String> uriList, String method, Class clazz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will take all the required input and validate them to see if there are any issues before
|
* This method will take all the required input and validate them to see if there are any issues before
|
||||||
@@ -35,10 +36,9 @@ public interface UriListHandler<T> {
|
|||||||
* @param context The relevant DSpace context
|
* @param context The relevant DSpace context
|
||||||
* @param request The current request
|
* @param request The current request
|
||||||
* @param uriList The list of UriList Strings
|
* @param uriList The list of UriList Strings
|
||||||
* @param clazz The class to be returned by the handle method
|
|
||||||
* @return A boolean indicating whether all this input is valid for the implementing UriListHandler
|
* @return A boolean indicating whether all this input is valid for the implementing UriListHandler
|
||||||
*/
|
*/
|
||||||
boolean validate(Context context, HttpServletRequest request, List<String> uriList, Class clazz)
|
boolean validate(Context context, HttpServletRequest request, List<String> uriList)
|
||||||
throws AuthorizeException;
|
throws AuthorizeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -47,9 +47,9 @@ public class UriListHandlerService {
|
|||||||
// Loop all the uriListHandlers
|
// Loop all the uriListHandlers
|
||||||
for (UriListHandler uriListHandler : uriListHandlers) {
|
for (UriListHandler uriListHandler : uriListHandlers) {
|
||||||
// Does the class support the given uri list and the request method
|
// Does the class support the given uri list and the request method
|
||||||
if (uriListHandler.supports(uriList, request.getMethod())) {
|
if (uriListHandler.supports(uriList, request.getMethod(), clazz)) {
|
||||||
// Can the class handle the given uri list and can the given class, params and authorization be handled
|
// Can the class handle the given uri list and can the given class, params and authorization be handled
|
||||||
if (uriListHandler.validate(context, request, uriList, clazz)) {
|
if (uriListHandler.validate(context, request, uriList)) {
|
||||||
// If all these things succeed, call handle
|
// If all these things succeed, call handle
|
||||||
return (T) uriListHandler.handle(context, request, uriList);
|
return (T) uriListHandler.handle(context, request, uriList);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -92,7 +92,7 @@ public class SubmissionService {
|
|||||||
public WorkspaceItem createWorkspaceItem(Context context, Request request) throws SQLException, AuthorizeException {
|
public WorkspaceItem createWorkspaceItem(Context context, Request request) throws SQLException, AuthorizeException {
|
||||||
WorkspaceItem wsi = null;
|
WorkspaceItem wsi = null;
|
||||||
Collection collection = null;
|
Collection collection = null;
|
||||||
String collectionUUID = request.getHttpServletRequest().getParameter("collection");
|
String collectionUUID = request.getHttpServletRequest().getParameter("owningCollection");
|
||||||
|
|
||||||
if (StringUtils.isBlank(collectionUUID)) {
|
if (StringUtils.isBlank(collectionUUID)) {
|
||||||
collectionUUID = configurationService.getProperty("submission.default.collection");
|
collectionUUID = configurationService.getProperty("submission.default.collection");
|
||||||
|
@@ -9,6 +9,8 @@ package org.dspace.app.rest;
|
|||||||
|
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE;
|
||||||
|
import static org.springframework.http.MediaType.parseMediaType;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
@@ -26,6 +28,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.CharEncoding;
|
import org.apache.commons.lang3.CharEncoding;
|
||||||
import org.dspace.app.rest.builder.BitstreamBuilder;
|
import org.dspace.app.rest.builder.BitstreamBuilder;
|
||||||
@@ -35,6 +38,7 @@ import org.dspace.app.rest.builder.EPersonBuilder;
|
|||||||
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
|
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
|
||||||
import org.dspace.app.rest.matcher.CollectionMatcher;
|
import org.dspace.app.rest.matcher.CollectionMatcher;
|
||||||
import org.dspace.app.rest.matcher.ItemMatcher;
|
import org.dspace.app.rest.matcher.ItemMatcher;
|
||||||
|
import org.dspace.app.rest.matcher.MetadataMatcher;
|
||||||
import org.dspace.app.rest.matcher.WorkspaceItemMatcher;
|
import org.dspace.app.rest.matcher.WorkspaceItemMatcher;
|
||||||
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;
|
||||||
@@ -50,6 +54,7 @@ import org.dspace.eperson.EPerson;
|
|||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test suite for the WorkspaceItem endpoint
|
* Test suite for the WorkspaceItem endpoint
|
||||||
@@ -445,14 +450,14 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
|
|
||||||
// create a workspaceitem explicitly in the col1
|
// create a workspaceitem explicitly in the col1
|
||||||
getClient(authToken).perform(post("/api/submission/workspaceitems")
|
getClient(authToken).perform(post("/api/submission/workspaceitems")
|
||||||
.param("collection", 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 col2
|
||||||
getClient(authToken).perform(post("/api/submission/workspaceitems")
|
getClient(authToken).perform(post("/api/submission/workspaceitems")
|
||||||
.param("collection", col2.getID().toString())
|
.param("owningCollection", col2.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(col2.getID().toString())));
|
.andExpect(jsonPath("$._embedded.collection.id", is(col2.getID().toString())));
|
||||||
@@ -1625,4 +1630,201 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSources() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
MvcResult mvcResult = getClient(token).perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/" +
|
||||||
|
"externalsources/mock/entryValues/one"))
|
||||||
|
.andExpect(status().isCreated()).andReturn();
|
||||||
|
|
||||||
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
|
Integer workspaceItemId = (Integer) map.get("id");
|
||||||
|
String itemUuidString = String.valueOf(((Map) ((Map) map.get("_embedded")).get("item")).get("uuid"));
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/submission/workspaceitems/" + workspaceItemId))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
hasJsonPath("$.id", is(workspaceItemId)),
|
||||||
|
hasJsonPath("$.type", is("workspaceitem")),
|
||||||
|
hasJsonPath("$._embedded.item", Matchers.allOf(
|
||||||
|
hasJsonPath("$.id", is(itemUuidString)),
|
||||||
|
hasJsonPath("$.uuid", is(itemUuidString)),
|
||||||
|
hasJsonPath("$.type", is("item")),
|
||||||
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
|
MetadataMatcher.matchMetadata("dc.contributor.author", "Donald, Smith")
|
||||||
|
)))))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesNoOwningCollectionUuidBadRequest() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems")
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mock/entryValues/one"))
|
||||||
|
.andExpect(status().isBadRequest()).andReturn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesRandomOwningCollectionUuidBadRequest() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems?owningCollection=" + UUID.randomUUID())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mock/entryValues/one"))
|
||||||
|
.andExpect(status().isBadRequest()).andReturn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesWrongUriList() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/mock/mock/mock/" +
|
||||||
|
"mock/entryValues/one")).andExpect(status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesWrongSourceBadRequest() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mockWrongSource/entryValues/one"))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesWrongIdResourceNotFound() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mock/entryValues/azeazezaezeaz"))
|
||||||
|
.andExpect(status().is(404));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesForbidden() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(token).perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mock/entryValues/one"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWorkspaceItemFromExternalSourcesUnauthorized() throws Exception {
|
||||||
|
//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();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(post("/api/submission/workspaceitems?owningCollection="
|
||||||
|
+ col1.getID().toString())
|
||||||
|
.contentType(parseMediaType(
|
||||||
|
TEXT_URI_LIST_VALUE))
|
||||||
|
.content("https://localhost:8080/server/api/integration/externalsources/" +
|
||||||
|
"mock/entryValues/one"))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user