[DS 4389] Improving patch system framework: Fixing merge issues with master

This commit is contained in:
Kevin Van de Velde
2019-11-28 10:33:32 +01:00
parent 62461febe1
commit 2bcd6013eb
11 changed files with 25 additions and 223 deletions

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.BundlePatch;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Bitstream;
@@ -70,8 +69,8 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
@Autowired
private BitstreamFormatService bitstreamFormatService;
public BundleRestRepository(BundleService dsoService, BundlePatch dsoPatch) {
super(dsoService, dsoPatch);
public BundleRestRepository(BundleService dsoService) {
super(dsoService);
this.bundleService = dsoService;
}

View File

@@ -53,8 +53,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
private static final Logger log = org.apache.logging.log4j.LogManager
.getLogger(CommunityRestRepository.class);
private final CommunityService cs;
@Autowired
BitstreamService bitstreamService;
@@ -64,9 +62,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
@Autowired
private CommunityService cs;
@Autowired
private BitstreamService bitstreamService;
public CommunityRestRepository(CommunityService dsoService) {
super(dsoService);
this.cs = dsoService;

View File

@@ -357,8 +357,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
JsonPatchConverter patchConverter = new JsonPatchConverter(mapper);
Patch patch = patchConverter.convert(jsonNode);
ItemRest patchedItemRest = dsoPatch.patch(converter.toRest(item, Projection.DEFAULT), patch.getOperations());
updateDSpaceObject(item, patchedItemRest);
patchDSpaceObject(ItemRest.CATEGORY, ItemRest.NAME, item.getID(), patch);
return converter.toRest(item, Projection.DEFAULT);
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -10,14 +10,12 @@ 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.MoveOperation;
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;
@@ -32,27 +30,31 @@ import org.springframework.stereotype.Component;
* </code>
*/
@Component
public class BundleMoveOperation extends MovePatchOperation<BundleRest, Integer> {
public class BundleMoveOperation extends PatchOperation<Bundle> {
@Autowired
BundleService bundleService;
@Autowired
RequestService requestService;
DspaceObjectMetadataPatchUtils dspaceObjectMetadataPatchUtils;
private static final String OPERATION_PATH_BUNDLE_MOVE = "/_links/bitstreams/";
/**
* 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.
* @return the updated rest model.
* @throws DSpaceBadRequestException
*/
@Override
public BundleRest move(BundleRest resource, Operation operation) {
Context context = ContextUtil.obtainContext(requestService.getCurrentRequest().getServletRequest());
public Bundle perform(Context context, Bundle bundle, Operation operation) {
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();
if (totalAmount < 1) {
@@ -78,29 +80,13 @@ public class BundleMoveOperation extends MovePatchOperation<BundleRest, Integer>
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
protected Class<Integer[]> getArrayClassForEvaluation() {
return Integer[].class;
}
/**
* 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;
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof Bundle && operation.getOp().trim().equalsIgnoreCase(OPERATION_MOVE)
&& operation.getPath().trim().startsWith(OPERATION_PATH_BUNDLE_MOVE));
}
/**

View File

@@ -42,7 +42,7 @@ public class DspaceObjectMetadataAddOperation<R extends DSpaceObject> extends Pa
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
MetadataValueRest metadataValueToAdd = metadataPatchUtils.extractMetadataValueFromOperation(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);
return resource;

View File

@@ -44,9 +44,8 @@ public class DspaceObjectMetadataMoveOperation<R extends DSpaceObject> extends P
public R perform(Context context, R resource, Operation operation) throws SQLException {
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
String indexInPath = metadataPatchUtils.getIndexFromPath(operation);
String[] partsFromMove = ((MoveOperation) operation).getFrom().split("/");
String indexToMoveFrom = (partsFromMove.length > 3) ? partsFromMove[3] : null;
String indexInPath = metadataPatchUtils.getIndexFromPath(operation.getPath());
String indexToMoveFrom = metadataPatchUtils.getIndexFromPath(((MoveOperation) operation).getFrom());
move(context, resource, dsoService, metadataField, indexInPath, indexToMoveFrom);
return resource;

View File

@@ -143,11 +143,11 @@ public final class DspaceObjectMetadataPatchUtils {
/**
* 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))
*/
protected String getIndexFromPath(Operation operation) {
String[] partsOfPath = operation.getPath().split("/");
protected String getIndexFromPath(String path) {
String[] partsOfPath = path.split("/");
// Index of md being patched
String indexInPath = (partsOfPath.length > 3) ? partsOfPath[3] : null;
return indexInPath;

View File

@@ -47,7 +47,7 @@ public class DspaceObjectMetadataRemoveOperation<R extends DSpaceObject> extends
@Override
public R perform(Context context, R resource, Operation operation) throws SQLException {
DSpaceObjectService dsoService = ContentServiceFactory.getInstance().getDSpaceObjectService(resource);
String indexInPath = metadataPatchUtils.getIndexFromPath(operation);
String indexInPath = metadataPatchUtils.getIndexFromPath(operation.getPath());
MetadataField metadataField = metadataPatchUtils.getMetadataField(context, operation);
remove(context, resource, dsoService, metadataField, indexInPath);

View File

@@ -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);
}
}