mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 10:04:21 +00:00
[DS 4389] Improving patch system framework: Fixing merge issues with master
This commit is contained in:
@@ -24,7 +24,6 @@ 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.app.rest.projection.Projection;
|
||||||
import org.dspace.app.rest.repository.patch.BundlePatch;
|
|
||||||
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;
|
||||||
@@ -70,8 +69,8 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
|
|||||||
@Autowired
|
@Autowired
|
||||||
private BitstreamFormatService bitstreamFormatService;
|
private BitstreamFormatService bitstreamFormatService;
|
||||||
|
|
||||||
public BundleRestRepository(BundleService dsoService, BundlePatch dsoPatch) {
|
public BundleRestRepository(BundleService dsoService) {
|
||||||
super(dsoService, dsoPatch);
|
super(dsoService);
|
||||||
this.bundleService = dsoService;
|
this.bundleService = dsoService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,8 +53,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
private static final Logger log = org.apache.logging.log4j.LogManager
|
private static final Logger log = org.apache.logging.log4j.LogManager
|
||||||
.getLogger(CommunityRestRepository.class);
|
.getLogger(CommunityRestRepository.class);
|
||||||
|
|
||||||
private final CommunityService cs;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
BitstreamService bitstreamService;
|
BitstreamService bitstreamService;
|
||||||
|
|
||||||
@@ -64,9 +62,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CommunityService cs;
|
private CommunityService cs;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private BitstreamService bitstreamService;
|
|
||||||
|
|
||||||
public CommunityRestRepository(CommunityService dsoService) {
|
public CommunityRestRepository(CommunityService dsoService) {
|
||||||
super(dsoService);
|
super(dsoService);
|
||||||
this.cs = dsoService;
|
this.cs = dsoService;
|
||||||
|
@@ -357,8 +357,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
|
|||||||
JsonPatchConverter patchConverter = new JsonPatchConverter(mapper);
|
JsonPatchConverter patchConverter = new JsonPatchConverter(mapper);
|
||||||
Patch patch = patchConverter.convert(jsonNode);
|
Patch patch = patchConverter.convert(jsonNode);
|
||||||
|
|
||||||
ItemRest patchedItemRest = dsoPatch.patch(converter.toRest(item, Projection.DEFAULT), patch.getOperations());
|
patchDSpaceObject(ItemRest.CATEGORY, ItemRest.NAME, item.getID(), patch);
|
||||||
updateDSpaceObject(item, patchedItemRest);
|
|
||||||
|
|
||||||
return converter.toRest(item, Projection.DEFAULT);
|
return converter.toRest(item, Projection.DEFAULT);
|
||||||
}
|
}
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.patch;
|
|
||||||
|
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides PATCH operations for bundle updates.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class BundlePatch extends DSpaceObjectPatch<BundleRest> {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
BundleOperationFactory patchFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the move operation.
|
|
||||||
* @param restModel the rest representation of the bundle
|
|
||||||
* @param operation the move operation
|
|
||||||
* @throws UnprocessableEntityException
|
|
||||||
* @throws DSpaceBadRequestException
|
|
||||||
*/
|
|
||||||
protected BundleRest move(BundleRest restModel, Operation operation) {
|
|
||||||
ResourcePatchOperation<BundleRest> patchOperation = patchFactory.getMoveOperation();
|
|
||||||
return patchOperation.perform(restModel, operation);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides factory methods for obtaining instances of bundle patch operations.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class BundleOperationFactory {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
BundleMoveOperation bundleMoveOperation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the patch instance for the move operation
|
|
||||||
*/
|
|
||||||
public ResourcePatchOperation<BundleRest> getMoveOperation() {
|
|
||||||
return bundleMoveOperation;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -10,14 +10,12 @@ package org.dspace.app.rest.repository.patch.factories.impl;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.model.BundleRest;
|
import org.dspace.app.rest.model.patch.MoveOperation;
|
||||||
import org.dspace.app.rest.model.patch.Operation;
|
import org.dspace.app.rest.model.patch.Operation;
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Bundle;
|
import org.dspace.content.Bundle;
|
||||||
import org.dspace.content.service.BundleService;
|
import org.dspace.content.service.BundleService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.services.RequestService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -32,27 +30,31 @@ import org.springframework.stereotype.Component;
|
|||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BundleMoveOperation extends MovePatchOperation<BundleRest, Integer> {
|
public class BundleMoveOperation extends PatchOperation<Bundle> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
BundleService bundleService;
|
BundleService bundleService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RequestService requestService;
|
DspaceObjectMetadataPatchUtils dspaceObjectMetadataPatchUtils;
|
||||||
|
|
||||||
|
private static final String OPERATION_PATH_BUNDLE_MOVE = "/_links/bitstreams/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the move patch operation.
|
* Executes the move patch operation.
|
||||||
*
|
*
|
||||||
* @param resource the rest model.
|
* @param bundle the bundle in which we want to move files around.
|
||||||
* @param operation the move patch operation.
|
* @param operation the move patch operation.
|
||||||
* @return the updated rest model.
|
* @return the updated rest model.
|
||||||
* @throws DSpaceBadRequestException
|
* @throws DSpaceBadRequestException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BundleRest move(BundleRest resource, Operation operation) {
|
public Bundle perform(Context context, Bundle bundle, Operation operation) {
|
||||||
Context context = ContextUtil.obtainContext(requestService.getCurrentRequest().getServletRequest());
|
|
||||||
try {
|
try {
|
||||||
Bundle bundle = bundleService.findByIdOrLegacyId(context, resource.getId());
|
MoveOperation moveOperation = (MoveOperation) operation;
|
||||||
|
final int from = Integer.parseInt(dspaceObjectMetadataPatchUtils.getIndexFromPath(moveOperation.getFrom()));
|
||||||
|
final int to = Integer.parseInt(dspaceObjectMetadataPatchUtils.getIndexFromPath(moveOperation.getPath()));
|
||||||
|
|
||||||
int totalAmount = bundle.getBitstreams().size();
|
int totalAmount = bundle.getBitstreams().size();
|
||||||
|
|
||||||
if (totalAmount < 1) {
|
if (totalAmount < 1) {
|
||||||
@@ -78,29 +80,13 @@ public class BundleMoveOperation extends MovePatchOperation<BundleRest, Integer>
|
|||||||
throw new DSpaceBadRequestException(e.getMessage(), e);
|
throw new DSpaceBadRequestException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resource;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should return the typed array to be used in the
|
|
||||||
* LateObjectEvaluator evaluation of json arrays.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<Integer[]> getArrayClassForEvaluation() {
|
public boolean supports(Object objectToMatch, Operation operation) {
|
||||||
return Integer[].class;
|
return (objectToMatch instanceof Bundle && operation.getOp().trim().equalsIgnoreCase(OPERATION_MOVE)
|
||||||
}
|
&& operation.getPath().trim().startsWith(OPERATION_PATH_BUNDLE_MOVE));
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should return the object type to be used in the
|
|
||||||
* LateObjectEvaluator evaluation of json objects.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Class<Integer> getClassForEvaluation() {
|
|
||||||
return Integer.class;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -42,7 +42,7 @@ public class DspaceObjectMetadataAddOperation<R extends DSpaceObject> extends Pa
|
|||||||
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
||||||
MetadataValueRest metadataValueToAdd = metadataPatchUtils.extractMetadataValueFromOperation(operation);
|
MetadataValueRest metadataValueToAdd = metadataPatchUtils.extractMetadataValueFromOperation(operation);
|
||||||
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
||||||
String indexInPath = metadataPatchUtils.getIndexFromPath(operation);
|
String indexInPath = metadataPatchUtils.getIndexFromPath(operation.getPath());
|
||||||
|
|
||||||
add(context, resource, dsoService, metadataField, metadataValueToAdd, indexInPath);
|
add(context, resource, dsoService, metadataField, metadataValueToAdd, indexInPath);
|
||||||
return resource;
|
return resource;
|
||||||
|
@@ -44,9 +44,8 @@ public class DspaceObjectMetadataMoveOperation<R extends DSpaceObject> extends P
|
|||||||
public R perform(Context context, R resource, Operation operation) throws SQLException {
|
public R perform(Context context, R resource, Operation operation) throws SQLException {
|
||||||
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
||||||
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
||||||
String indexInPath = metadataPatchUtils.getIndexFromPath(operation);
|
String indexInPath = metadataPatchUtils.getIndexFromPath(operation.getPath());
|
||||||
String[] partsFromMove = ((MoveOperation) operation).getFrom().split("/");
|
String indexToMoveFrom = metadataPatchUtils.getIndexFromPath(((MoveOperation) operation).getFrom());
|
||||||
String indexToMoveFrom = (partsFromMove.length > 3) ? partsFromMove[3] : null;
|
|
||||||
|
|
||||||
move(context, resource, dsoService, metadataField, indexInPath, indexToMoveFrom);
|
move(context, resource, dsoService, metadataField, indexInPath, indexToMoveFrom);
|
||||||
return resource;
|
return resource;
|
||||||
|
@@ -143,11 +143,11 @@ public final class DspaceObjectMetadataPatchUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieved the index from the path of the patch operation, if one can be found
|
* Retrieved the index from the path of the patch operation, if one can be found
|
||||||
* @param operation The operation of the patch
|
* @param path The string from the operation
|
||||||
* @return The index in the path if there is one (path ex: /metadata/dc.title/1 (1 being the index))
|
* @return The index in the path if there is one (path ex: /metadata/dc.title/1 (1 being the index))
|
||||||
*/
|
*/
|
||||||
protected String getIndexFromPath(Operation operation) {
|
protected String getIndexFromPath(String path) {
|
||||||
String[] partsOfPath = operation.getPath().split("/");
|
String[] partsOfPath = path.split("/");
|
||||||
// Index of md being patched
|
// Index of md being patched
|
||||||
String indexInPath = (partsOfPath.length > 3) ? partsOfPath[3] : null;
|
String indexInPath = (partsOfPath.length > 3) ? partsOfPath[3] : null;
|
||||||
return indexInPath;
|
return indexInPath;
|
||||||
|
@@ -47,7 +47,7 @@ public class DspaceObjectMetadataRemoveOperation<R extends DSpaceObject> extends
|
|||||||
@Override
|
@Override
|
||||||
public R perform(Context context, R resource, Operation operation) throws SQLException {
|
public R perform(Context context, R resource, Operation operation) throws SQLException {
|
||||||
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
|
||||||
String indexInPath = metadataPatchUtils.getIndexFromPath(operation);
|
String indexInPath = metadataPatchUtils.getIndexFromPath(operation.getPath());
|
||||||
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
|
||||||
|
|
||||||
remove(context, resource, dsoService, metadataField, indexInPath);
|
remove(context, resource, dsoService, metadataField, indexInPath);
|
||||||
|
@@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.patch.factories.impl;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
|
||||||
import org.dspace.app.rest.model.RestModel;
|
|
||||||
import org.dspace.app.rest.model.patch.MoveOperation;
|
|
||||||
import org.dspace.app.rest.model.patch.Operation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for move patch operations.
|
|
||||||
*/
|
|
||||||
public abstract class MovePatchOperation<R extends RestModel, T> extends PatchOperation<R, T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The index to move the object from
|
|
||||||
*/
|
|
||||||
protected int from;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The index to move the object to
|
|
||||||
*/
|
|
||||||
protected int to;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the patch operation for move operations.
|
|
||||||
* Before performing the move operation this method checks
|
|
||||||
* if the arguments provided are valid
|
|
||||||
*
|
|
||||||
* @param resource the rest model.
|
|
||||||
* @param operation the move patch operation.
|
|
||||||
* @return the updated rest model.
|
|
||||||
* @throws DSpaceBadRequestException
|
|
||||||
* @throws UnprocessableEntityException
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public R perform(R resource, Operation operation) {
|
|
||||||
checkMoveOperation(operation);
|
|
||||||
return move(resource, operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the move patch operation.
|
|
||||||
*
|
|
||||||
* @param resource the rest model.
|
|
||||||
* @param operation the move patch operation.
|
|
||||||
* @return the updated rest model.
|
|
||||||
* @throws DSpaceBadRequestException
|
|
||||||
* @throws UnprocessableEntityException
|
|
||||||
*/
|
|
||||||
abstract R move(R resource, Operation operation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method checks if the operation contains any invalid arguments. Invalid arguments include:
|
|
||||||
* - from and path point to the same index
|
|
||||||
* - either of the indexes are negative
|
|
||||||
* @param operation the move patch 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches and returns the index from a path argument
|
|
||||||
* @param path the provided path (e.g. "/_links/bitstreams/1/href")
|
|
||||||
*/
|
|
||||||
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