mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
64640: Move PATCH request for bitstreams in bundles
This commit is contained in:
@@ -268,6 +268,30 @@ public class BundleServiceImpl extends DSpaceObjectServiceImpl<Bundle> implement
|
||||
return authorizeService.getPolicies(context, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveBitstream(Context context, Bundle bundle, int from, int to)
|
||||
throws AuthorizeException, SQLException {
|
||||
List<Bitstream> bitstreams = bundle.getBitstreams();
|
||||
if (bitstreams.size() < 1 || from >= bitstreams.size() || to >= bitstreams.size() || from < 0 || to < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid 'from' and 'to' arguments supplied for moving a bitstream within bundle " +
|
||||
bundle.getID() + ". from: " + from + "; to: " + to
|
||||
);
|
||||
}
|
||||
List<UUID> bitstreamIds = new LinkedList<>();
|
||||
for (Bitstream bitstream : bitstreams) {
|
||||
bitstreamIds.add(bitstream.getID());
|
||||
}
|
||||
if (from < to) {
|
||||
bitstreamIds.add(to + 1, bitstreamIds.get(from));
|
||||
bitstreamIds.remove(from);
|
||||
} else {
|
||||
bitstreamIds.add(to, bitstreamIds.get(from));
|
||||
bitstreamIds.remove(from + 1);
|
||||
}
|
||||
setOrder(context, bundle, bitstreamIds.toArray(new UUID[bitstreamIds.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(Context context, Bundle bundle, UUID[] bitstreamIds) throws AuthorizeException, SQLException {
|
||||
authorizeService.authorizeAction(context, bundle, Constants.WRITE);
|
||||
|
@@ -109,6 +109,18 @@ public interface BundleService extends DSpaceObjectService<Bundle>, DSpaceObject
|
||||
|
||||
public List<ResourcePolicy> getBundlePolicies(Context context, Bundle bundle) throws SQLException;
|
||||
|
||||
/**
|
||||
* Moves a bitstream within a bundle from one place to another, shifting all other bitstreams in the process
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param bundle The bitstream bundle
|
||||
* @param from The index of the bitstream to move
|
||||
* @param to The index to move the bitstream to
|
||||
* @throws AuthorizeException when an SQL error has occurred (querying DSpace)
|
||||
* @throws SQLException If the user can't make the changes
|
||||
*/
|
||||
public void moveBitstream(Context context, Bundle bundle, int from, int to) throws AuthorizeException, SQLException;
|
||||
|
||||
/**
|
||||
* Changes bitstream order according to the array
|
||||
*
|
||||
|
@@ -10,11 +10,16 @@ package org.dspace.app.rest.repository;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.dspace.app.rest.converter.BundleConverter;
|
||||
import org.dspace.app.rest.model.BundleRest;
|
||||
import org.dspace.app.rest.model.hateoas.BundleResource;
|
||||
import org.dspace.app.rest.model.hateoas.DSpaceResource;
|
||||
import org.dspace.app.rest.model.patch.Patch;
|
||||
import org.dspace.app.rest.repository.patch.BundlePatch;
|
||||
import org.dspace.app.rest.repository.patch.DSpaceObjectPatch;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.service.BundleService;
|
||||
import org.dspace.core.Context;
|
||||
@@ -36,9 +41,13 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
|
||||
@Autowired
|
||||
private BundleService bundleService;
|
||||
|
||||
@Autowired
|
||||
private BundlePatch bundlePatch;
|
||||
|
||||
public BundleRestRepository(BundleService dsoService,
|
||||
BundleConverter dsoConverter) {
|
||||
super(dsoService, dsoConverter, new DSpaceObjectPatch<BundleRest>() {});
|
||||
BundleConverter dsoConverter,
|
||||
BundlePatch dsoPatch) {
|
||||
super(dsoService, dsoConverter, dsoPatch);
|
||||
this.bundleService = dsoService;
|
||||
}
|
||||
|
||||
@@ -60,6 +69,13 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
|
||||
throw new RuntimeException("Method not allowed!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasPermission(#uuid, 'BUNDLE', 'WRITE')")
|
||||
protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID uuid,
|
||||
Patch patch) throws AuthorizeException, SQLException {
|
||||
patchDSpaceObject(apiCategory, model, uuid, patch);
|
||||
}
|
||||
|
||||
public Class<BundleRest> getDomainClass() {
|
||||
return BundleRest.class;
|
||||
}
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package org.dspace.app.rest.repository.patch;
|
||||
|
||||
import org.dspace.app.rest.model.BundleRest;
|
||||
import org.dspace.app.rest.model.patch.Operation;
|
||||
import org.dspace.app.rest.repository.patch.factories.BundleOperationFactory;
|
||||
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePatchOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Created by kristof on 24/09/2019
|
||||
*/
|
||||
@Component
|
||||
public class BundlePatch extends DSpaceObjectPatch<BundleRest> {
|
||||
|
||||
@Autowired
|
||||
BundleOperationFactory patchFactory;
|
||||
|
||||
protected BundleRest move(BundleRest restModel, Operation operation) {
|
||||
ResourcePatchOperation<BundleRest> patchOperation = patchFactory.getMoveOperation();
|
||||
return patchOperation.perform(restModel, operation);
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package org.dspace.app.rest.repository.patch.factories;
|
||||
|
||||
import org.dspace.app.rest.model.BundleRest;
|
||||
import org.dspace.app.rest.repository.patch.factories.impl.BundleMoveOperation;
|
||||
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePatchOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Created by kristof on 24/09/2019
|
||||
*/
|
||||
@Component
|
||||
public class BundleOperationFactory {
|
||||
|
||||
@Autowired
|
||||
BundleMoveOperation bundleMoveOperation;
|
||||
|
||||
public ResourcePatchOperation<BundleRest> getMoveOperation() {
|
||||
return bundleMoveOperation;
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package org.dspace.app.rest.repository.patch.factories.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||
import org.dspace.app.rest.model.BundleRest;
|
||||
import org.dspace.app.rest.model.patch.Operation;
|
||||
import org.dspace.app.rest.utils.ContextUtil;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.service.BundleService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.services.RequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Created by kristof on 24/09/2019
|
||||
*/
|
||||
@Component
|
||||
public class BundleMoveOperation extends MovePatchOperation<BundleRest, Integer> {
|
||||
|
||||
@Autowired
|
||||
BundleService bundleService;
|
||||
|
||||
@Autowired
|
||||
RequestService requestService;
|
||||
|
||||
@Override
|
||||
public BundleRest move(BundleRest resource, Operation operation) {
|
||||
Context context = ContextUtil.obtainContext(requestService.getCurrentRequest().getServletRequest());
|
||||
try {
|
||||
Bundle bundle = bundleService.findByIdOrLegacyId(context, resource.getId());
|
||||
int totalAmount = bundle.getBitstreams().size();
|
||||
|
||||
if(totalAmount < 1) {
|
||||
throw new DSpaceBadRequestException(createMoveExceptionMessage(bundle, from, to, "No sub-communities found."));
|
||||
}
|
||||
if(from >= totalAmount) {
|
||||
throw new DSpaceBadRequestException(createMoveExceptionMessage(bundle, from, to, "\"from\" location out of bounds. Latest available position: " + (totalAmount-1)));
|
||||
}
|
||||
if(to >= totalAmount) {
|
||||
throw new DSpaceBadRequestException(createMoveExceptionMessage(bundle, from, to, "\"to\" location out of bounds. Latest available position: " + (totalAmount-1)));
|
||||
}
|
||||
|
||||
bundleService.moveBitstream(context, bundle, from, to);
|
||||
} catch (SQLException | AuthorizeException e) {
|
||||
throw new DSpaceBadRequestException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<Integer[]> getArrayClassForEvaluation() {
|
||||
return Integer[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<Integer> getClassForEvaluation() {
|
||||
return Integer.class;
|
||||
}
|
||||
|
||||
private String createMoveExceptionMessage(Bundle bundle, int from, int to, String message) {
|
||||
return "Failed moving bitstreams of bundle with id " + bundle.getID() + " from location " + from + " to " + to + ": " + message;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
package org.dspace.app.rest.repository.patch.factories.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||
import org.dspace.app.rest.model.RestModel;
|
||||
import org.dspace.app.rest.model.patch.MoveOperation;
|
||||
import org.dspace.app.rest.model.patch.Operation;
|
||||
|
||||
/**
|
||||
* Created by kristof on 24/09/2019
|
||||
*/
|
||||
public abstract class MovePatchOperation<R extends RestModel, T> extends PatchOperation<R, T> {
|
||||
|
||||
protected int from;
|
||||
protected int to;
|
||||
|
||||
@Override
|
||||
public R perform(R resource, Operation operation) {
|
||||
checkMoveOperation(operation);
|
||||
return move(resource, operation);
|
||||
}
|
||||
|
||||
abstract R move(R resource, Operation operation);
|
||||
|
||||
private void checkMoveOperation(Operation operation) {
|
||||
if(!(operation instanceof MoveOperation)) {
|
||||
throw new DSpaceBadRequestException("Expected a MoveOperation, but received " + operation.getClass().getName() + " instead.");
|
||||
}
|
||||
from = getLocationFromPath(((MoveOperation)operation).getFrom());
|
||||
to = getLocationFromPath(operation.getPath());
|
||||
if(from == to) {
|
||||
throw new DSpaceBadRequestException("The \"from\" location must be different from the \"to\" location.");
|
||||
}
|
||||
if(from < 0) {
|
||||
throw new DSpaceBadRequestException("A negative \"from\" location was provided: " + from);
|
||||
}
|
||||
if(to < 0) {
|
||||
throw new DSpaceBadRequestException("A negative \"to\" location was provided: " + to);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getLocationFromPath(String path) {
|
||||
String[] parts = StringUtils.split(path, "/");
|
||||
String locationStr;
|
||||
if(parts.length > 1) {
|
||||
if(StringUtils.equals(parts[parts.length-1], "href")) {
|
||||
locationStr = parts[parts.length-2];
|
||||
} else {
|
||||
locationStr = parts[parts.length-1];
|
||||
}
|
||||
} else {
|
||||
locationStr = parts[0];
|
||||
}
|
||||
return Integer.parseInt(locationStr);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user