[DS-4389] Refactored new ResourcePolicy Patch system to work like the improved patch system (ResourcePolicy from DS-4398)

This commit is contained in:
Marie Verdonck
2020-02-14 18:56:01 +01:00
parent 7c7422e4cf
commit 1bee20c732
28 changed files with 2036 additions and 1657 deletions

View File

@@ -8,7 +8,6 @@
package org.dspace.app.rest.repository;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
@@ -24,13 +23,11 @@ import org.dspace.app.rest.exception.RESTAuthorizationException;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.factories.ResourcePolicyOperationFactory;
import org.dspace.app.rest.repository.patch.ResourcePatch;
import org.dspace.app.rest.utils.DSpaceObjectUtils;
import org.dspace.app.rest.utils.Utils;
import org.dspace.app.util.DCInputsReaderException;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.service.ResourcePolicyService;
@@ -59,9 +56,6 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
@Autowired
ResourcePolicyService resourcePolicyService;
@Autowired
ResourcePolicyOperationFactory resourcePolicyOperationPatchFactory;
@Autowired
Utils utils;
@@ -74,6 +68,9 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
@Autowired
DSpaceObjectUtils dspaceObjectUtils;
@Autowired
ResourcePatch<ResourcePolicy> resourcePatch;
@Override
@PreAuthorize("hasPermission(#id, 'resourcepolicy', 'READ')")
@@ -103,7 +100,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
/**
* Find the resource policies matching the uuid of the resource object and/or the specified action
*
*
* @param resourceUuid
* mandatory, the uuid of the resource object of the policy
* @param action
@@ -142,7 +139,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
/**
* Find the resource policies matching uuid of the eperson and/or the one specified resource object
*
*
* @param epersonUuid
* mandatory, the uuid of the eperson that benefit of the policy
* @param resourceUuid
@@ -186,14 +183,14 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
/**
* Find the resource policies matching uuid of the group and/or the ones specified resource object
*
*
* @param groupUuid
* mandatory, the uuid of the group that benefit of the policy
* @param resourceUuid
* optional, limit the returned policies to the ones related to the specified resource
* @param pageable
* contains the pagination information
*
*
* @return It returns the list of explicit matching resource policies, no inherited or broader resource policies
* will be included in the list nor policies derived by groups' membership
*/
@@ -321,27 +318,9 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
@Override
@PreAuthorize("hasPermission(#id, 'resourcepolicy', 'ADMIN')")
protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, Integer id,
Patch patch)
throws RepositoryMethodNotImplementedException, SQLException, AuthorizeException, DCInputsReaderException {
ResourcePolicyRest rest = findOne(context,id);
if (rest == null) {
throw new ResourceNotFoundException(
ResourcePolicyRest.CATEGORY + "." + ResourcePolicyRest.NAME + " with id: " + id + " not found");
}
for (Operation op : patch.getOperations()) {
rest = resourcePolicyOperationPatchFactory.getOperationForPath(op.getPath()).perform(rest, op);
}
ResourcePolicy resourcePolicy = null;
try {
resourcePolicy = resourcePolicyService.find(context, id);
resourcePolicy.setStartDate(rest.getStartDate());
resourcePolicy.setEndDate(rest.getEndDate());
resourcePolicy.setRpDescription(rest.getDescription());
resourcePolicy.setRpName(rest.getName());
resourcePolicyService.update(context, resourcePolicy);
} catch (SQLException e) {
throw new RuntimeException("Unable to patch ResourcePolicy with id = " + id, e);
}
Patch patch) throws RepositoryMethodNotImplementedException, SQLException, AuthorizeException {
ResourcePolicy resourcePolicy = resourcePolicyService.find(context, id);
resourcePatch.patch(obtainContext(), resourcePolicy, patch.getOperations());
resourcePolicyService.update(context, resourcePolicy);
}
}

View File

@@ -14,7 +14,6 @@ import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -23,7 +22,7 @@ import org.springframework.stereotype.Component;
* The base class for resource PATCH operations.
*/
@Component
public class ResourcePatch<M extends DSpaceObject> {
public class ResourcePatch<M extends Object> {
@Autowired
private List<PatchOperation> patchOperations;
@@ -48,15 +47,15 @@ public class ResourcePatch<M extends DSpaceObject> {
* Checks with all possible patch operations whether they support this operation
* (based on instanceof dso and operation.path)
* @param context Context of patch operation
* @param dso the dso resource to patch
* @param object the resource to patch
* @param operation the patch operation
* @throws DSpaceBadRequestException
*/
protected void performPatchOperation(Context context, M dso, Operation operation)
protected void performPatchOperation(Context context, M object, Operation operation)
throws DSpaceBadRequestException, SQLException {
for (PatchOperation patchOperation: patchOperations) {
if (patchOperation.supports(dso, operation)) {
patchOperation.perform(context, dso, operation);
if (patchOperation.supports(object, operation)) {
patchOperation.perform(context,object, operation);
return;
}
}

View File

@@ -1,67 +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.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePatchOperation;
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePolicyDescriptionOperations;
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePolicyEndDateOperations;
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePolicyNameOperations;
import org.dspace.app.rest.repository.patch.factories.impl.ResourcePolicyStartDateOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Provides factory methods for obtaining instances of ResourcePolicy patch operations.
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyOperationFactory {
@Autowired
ResourcePolicyStartDateOperations resourcePolicyStartDateOperations;
@Autowired
ResourcePolicyEndDateOperations resourcePolicyEndDateOperations;
@Autowired
ResourcePolicyNameOperations resourcePolicyNameOperations;
@Autowired
ResourcePolicyDescriptionOperations resourcePolicyDescriptionOperations;
private static final String OPERATION_PATH_STARTDATE = "/startDate";
private static final String OPERATION_PATH_ENDDATE = "/endDate";
private static final String OPERATION_PATH_DESCRIPTION = "/description";
private static final String OPERATION_PATH_NAME = "/name";
/**
* Returns the patch instance for the operation (based on the operation path).
*
* @param path the operation path
* @return the patch operation implementation
* @throws DSpaceBadRequestException
*/
public ResourcePatchOperation<ResourcePolicyRest> getOperationForPath(String path) {
switch (path) {
case OPERATION_PATH_STARTDATE:
return resourcePolicyStartDateOperations;
case OPERATION_PATH_ENDDATE:
return resourcePolicyEndDateOperations;
case OPERATION_PATH_DESCRIPTION:
return resourcePolicyDescriptionOperations;
case OPERATION_PATH_NAME:
return resourcePolicyNameOperations;
default:
throw new DSpaceBadRequestException("Missing patch operation for: " + path);
}
}
}

View File

@@ -1,107 +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.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Operation;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy name patches.
*
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /description", "value": "my description"]'
* </code>
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyDescriptionOperations implements ResourcePatchOperation<ResourcePolicyRest> {
@Override
public ResourcePolicyRest perform(ResourcePolicyRest resource, Operation operation)
throws DSpaceBadRequestException {
switch (operation.getOp()) {
case "replace":
checkOperationValue(operation.getValue());
checkModelForExistingValue(resource, operation);
return replace(resource, operation);
case "add":
checkOperationValue(operation.getValue());
checkModelForNotExistingValue(resource, operation);
return add(resource, operation);
case "remove":
checkModelForExistingValue(resource, operation);
return delete(resource, operation);
default:
throw new DSpaceBadRequestException("Unsupported operation " + operation.getOp());
}
}
public ResourcePolicyRest replace(ResourcePolicyRest resourcePolicy, Operation operation) {
String newDescription = (String) operation.getValue();
resourcePolicy.setDescription(newDescription);
return resourcePolicy;
}
public ResourcePolicyRest add(ResourcePolicyRest resourcePolicy, Operation operation) {
String description = (String) operation.getValue();
resourcePolicy.setDescription(description);
return resourcePolicy;
}
public ResourcePolicyRest delete(ResourcePolicyRest resourcePolicy, Operation operation) {
resourcePolicy.setDescription(null);
return resourcePolicy;
}
/**
* Throws PatchBadRequestException for missing operation value.
*
* @param value
* the value to test
*/
void checkOperationValue(Object value) {
if (value == null || value.equals("")) {
throw new DSpaceBadRequestException("No value provided for the operation.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /description path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getDescription() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp() + " a non-existent value.");
}
}
/**
* Throws PatchBadRequestException if a value is already set in the /description path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForNotExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getDescription() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
}

View File

@@ -1,147 +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 java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Operation;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy endDate patches.
*
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /endDate", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyEndDateOperations implements ResourcePatchOperation<ResourcePolicyRest> {
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public ResourcePolicyRest perform(ResourcePolicyRest resource, Operation operation)
throws DSpaceBadRequestException {
switch (operation.getOp()) {
case "replace":
checkOperationValue(operation.getValue());
checkModelForExistingValue(resource, operation);
checkModelForConsistentValue(resource, operation);
return replace(resource, operation);
case "add":
checkOperationValue(operation.getValue());
checkModelForNotExistingValue(resource, operation);
checkModelForConsistentValue(resource, operation);
return add(resource, operation);
case "remove":
checkModelForExistingValue(resource, operation);
return delete(resource, operation);
default:
throw new DSpaceBadRequestException("Unsupported operation " + operation.getOp());
}
}
ResourcePolicyRest add(ResourcePolicyRest resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
resourcePolicy.setEndDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
return resourcePolicy;
}
ResourcePolicyRest delete(ResourcePolicyRest resourcePolicy, Operation operation) {
resourcePolicy.setEndDate(null);
return resourcePolicy;
}
ResourcePolicyRest replace(ResourcePolicyRest resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
resourcePolicy.setEndDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
return resourcePolicy;
}
/**
* Throws PatchBadRequestException for missing operation value.
*
* @param value
* the value to test
*/
void checkOperationValue(Object value) {
if (value == null) {
throw new DSpaceBadRequestException("No value provided for the operation.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /endDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getEndDate() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp() + " a non-existent value.");
}
}
/**
* Throws PatchBadRequestException if a value is already set in the /endDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForNotExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getEndDate() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
/**
* Throws PatchBadRequestException if the value for endDate is not consistent with the startDate value, if present
* (smaller than).
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForConsistentValue(ResourcePolicyRest resource, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
if (resource.getEndDate() != null && resource.getStartDate().after(date)) {
throw new DSpaceBadRequestException("Attempting to set an invalid endDate smaller than the startDate.");
}
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
}
}

View File

@@ -1,107 +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.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Operation;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy name patches.
*
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /name", "value": "New Name"]'
* </code>
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyNameOperations implements ResourcePatchOperation<ResourcePolicyRest> {
@Override
public ResourcePolicyRest perform(ResourcePolicyRest resource, Operation operation)
throws DSpaceBadRequestException {
switch (operation.getOp()) {
case "replace":
checkOperationValue(operation.getValue());
checkModelForExistingValue(resource, operation);
return replace(resource, operation);
case "add":
checkOperationValue(operation.getValue());
checkModelForNotExistingValue(resource, operation);
return add(resource, operation);
case "remove":
checkModelForExistingValue(resource, operation);
return delete(resource, operation);
default:
throw new DSpaceBadRequestException("Unsupported operation " + operation.getOp());
}
}
public ResourcePolicyRest replace(ResourcePolicyRest resourcePolicy, Operation operation) {
String newName = (String) operation.getValue();
resourcePolicy.setName(newName);
return resourcePolicy;
}
public ResourcePolicyRest add(ResourcePolicyRest resourcePolicy, Operation operation) {
String name = (String) operation.getValue();
resourcePolicy.setName(name);
return resourcePolicy;
}
public ResourcePolicyRest delete(ResourcePolicyRest resourcePolicy, Operation operation) {
resourcePolicy.setName(null);
return resourcePolicy;
}
/**
* Throws PatchBadRequestException for missing operation value.
*
* @param value
* the value to test
*/
void checkOperationValue(Object value) {
if (value == null || value.equals("")) {
throw new DSpaceBadRequestException("No value provided for the operation.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /name path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getName() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp() + " a non-existent value.");
}
}
/**
* Throws PatchBadRequestException if a value is already set in the /name path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForNotExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getName() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
}

View File

@@ -1,161 +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 java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Operation;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy startDate patches.
*
* Examples:
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /startDate", "value": "YYYY-MM-DD"]'
* </code>
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "add", "path": "
* /startDate", "value": "YYYY-MM-DD"]'
* </code>
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "delete", "path": "
* /startDate"]'
* </code>
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyStartDateOperations implements ResourcePatchOperation<ResourcePolicyRest> {
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public ResourcePolicyRest perform(ResourcePolicyRest resource, Operation operation)
throws DSpaceBadRequestException {
switch (operation.getOp()) {
case "replace":
checkOperationValue(operation.getValue());
checkModelForExistingValue(resource, operation);
checkModelForConsistentValue(resource, operation);
return replace(resource, operation);
case "add":
checkOperationValue(operation.getValue());
checkModelForNotExistingValue(resource, operation);
checkModelForConsistentValue(resource, operation);
return add(resource, operation);
case "remove":
checkModelForExistingValue(resource, operation);
return delete(resource, operation);
default:
throw new DSpaceBadRequestException("Unsupported operation " + operation.getOp());
}
}
ResourcePolicyRest add(ResourcePolicyRest resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
resourcePolicy.setStartDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
return resourcePolicy;
}
ResourcePolicyRest delete(ResourcePolicyRest resourcePolicy, Operation operation) {
resourcePolicy.setStartDate(null);
return resourcePolicy;
}
ResourcePolicyRest replace(ResourcePolicyRest resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
resourcePolicy.setStartDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
return resourcePolicy;
}
/**
* Throws PatchBadRequestException for missing operation value.
*
* @param value
* the value to test
*/
void checkOperationValue(Object value) {
if (value == null) {
throw new DSpaceBadRequestException("No value provided for the operation.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /startDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getStartDate() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp() + " a non-existent value.");
}
}
/**
* Throws PatchBadRequestException if a value is already set in the /startDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForNotExistingValue(ResourcePolicyRest resource, Operation operation) {
if (resource.getStartDate() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
/**
* Throws PatchBadRequestException if the value for startDate is not consistent with the endDate value, if present
* (greater than).
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
void checkModelForConsistentValue(ResourcePolicyRest resource, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
if (resource.getEndDate() != null && resource.getEndDate().before(date)) {
throw new DSpaceBadRequestException("Attempting to set an invalid startDate greater than the endDate.");
}
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
}
}

View File

@@ -77,8 +77,8 @@ public class DSpaceObjectMetadataAddOperation<R extends DSpaceObject> extends Pa
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return ((operation.getPath().startsWith(metadataPatchUtils.METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.METADATA_PATH))
return ((operation.getPath().startsWith(metadataPatchUtils.OPERATION_METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.OPERATION_METADATA_PATH))
&& operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)
&& objectToMatch instanceof DSpaceObject);
}

View File

@@ -94,8 +94,8 @@ public class DSpaceObjectMetadataCopyOperation<R extends DSpaceObject> extends P
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return ((operation.getPath().startsWith(metadataPatchUtils.METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.METADATA_PATH))
return ((operation.getPath().startsWith(metadataPatchUtils.OPERATION_METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.OPERATION_METADATA_PATH))
&& operation.getOp().trim().equalsIgnoreCase(OPERATION_COPY)
&& objectToMatch instanceof DSpaceObject);
}

View File

@@ -76,8 +76,8 @@ public class DSpaceObjectMetadataMoveOperation<R extends DSpaceObject> extends P
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return ((operation.getPath().startsWith(metadataPatchUtils.METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.METADATA_PATH))
return ((operation.getPath().startsWith(metadataPatchUtils.OPERATION_METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.OPERATION_METADATA_PATH))
&& operation.getOp().trim().equalsIgnoreCase(OPERATION_MOVE)
&& objectToMatch instanceof DSpaceObject);
}

View File

@@ -37,9 +37,9 @@ public final class DSpaceObjectMetadataPatchUtils {
private MetadataFieldService metadataFieldService;
/**
* Path in json body of patch that uses this operation
* Path in json body of patch that uses these metadata operations
*/
protected static final String METADATA_PATH = "/metadata";
protected static final String OPERATION_METADATA_PATH = "/metadata";
private DSpaceObjectMetadataPatchUtils() {
}
@@ -84,9 +84,9 @@ public final class DSpaceObjectMetadataPatchUtils {
* @return The mdField (schema.element.qualifier) patch is being performed on
*/
protected String extractMdFieldStringFromOperation(Operation operation) {
String mdElement = StringUtils.substringBetween(operation.getPath(), METADATA_PATH + "/", "/");
String mdElement = StringUtils.substringBetween(operation.getPath(), OPERATION_METADATA_PATH + "/", "/");
if (mdElement == null) {
mdElement = StringUtils.substringAfter(operation.getPath(), METADATA_PATH + "/");
mdElement = StringUtils.substringAfter(operation.getPath(), OPERATION_METADATA_PATH + "/");
if (mdElement == null) {
throw new DSpaceBadRequestException("No metadata field string found in path: " + operation.getPath());
}

View File

@@ -99,8 +99,8 @@ public class DSpaceObjectMetadataRemoveOperation<R extends DSpaceObject> extends
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return ((operation.getPath().startsWith(metadataPatchUtils.METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.METADATA_PATH))
return ((operation.getPath().startsWith(metadataPatchUtils.OPERATION_METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.OPERATION_METADATA_PATH))
&& operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)
&& objectToMatch instanceof DSpaceObject);
}

View File

@@ -214,8 +214,8 @@ public class DSpaceObjectMetadataReplaceOperation<R extends DSpaceObject> extend
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return ((operation.getPath().startsWith(metadataPatchUtils.METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.METADATA_PATH))
return ((operation.getPath().startsWith(metadataPatchUtils.OPERATION_METADATA_PATH)
|| operation.getPath().equals(metadataPatchUtils.OPERATION_METADATA_PATH))
&& operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)
&& objectToMatch instanceof DSpaceObject);
}

View File

@@ -40,12 +40,16 @@ public abstract class PatchOperation<M> {
/**
* Throws PatchBadRequestException for missing operation value.
*
* @param value the value to test
* @param value
* the value to test
*/
void checkOperationValue(Object value) {
public void checkOperationValue(Object value) {
if (value == null) {
throw new DSpaceBadRequestException("No value provided for the operation.");
}
if (value instanceof String && (((String) value).trim().isBlank())) {
throw new DSpaceBadRequestException("Value can't be empty or just spaces.");
}
}
/**

View File

@@ -0,0 +1,78 @@
/**
* 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.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy description ADD patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "add", "path": "
* /description", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyDescriptionAddOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
this.checkResourcePolicyForNonExistingDescriptionValue(resourcePolicy);
this.add(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual add description of resourcePolicy operation
*
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void add(ResourcePolicy resourcePolicy, Operation operation) {
String description = (String) operation.getValue();
resourcePolicy.setRpDescription(description);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_DESCRIPTION));
}
/**
* Throws PatchBadRequestException if a value is already set in the /description path.
*
* @param resource the resource to update
*/
void checkResourcePolicyForNonExistingDescriptionValue(ResourcePolicy resource) {
if (resource.getRpDescription() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
}

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.repository.patch.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy description DELETE patch.
*
* Example:
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "remove", "path": "
* /description"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyDescriptionRemoveOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingDescriptionValue(resourcePolicy, operation);
this.delete(resourcePolicy);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual delete description of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
*/
private void delete(ResourcePolicy resourcePolicy) {
resourcePolicy.setRpDescription(null);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_DESCRIPTION));
}
}

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.patch.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy description REPLACE patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /description", "value": "my description"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyDescriptionReplaceOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingDescriptionValue(resourcePolicy, operation);
this.replace(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual replace description of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void replace(ResourcePolicy resourcePolicy, Operation operation) {
String newDescription = (String) operation.getValue();
resourcePolicy.setRpDescription(newDescription);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_DESCRIPTION));
}
}

View File

@@ -0,0 +1,75 @@
/**
* 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.operation.resourcePolicy;
import java.text.ParseException;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy startDate ADD patch.
*
* Example:
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "add", "path": "
* /endDate", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyEndDateAddOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingEndDateValue(resourcePolicy, operation);
resourcePolicyUtils.checkResourcePolicyForConsistentEndDateValue(resourcePolicy, operation);
this.add(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual add endDate of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void add(ResourcePolicy resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = resourcePolicyUtils.simpleDateFormat.parse(dateS);
resourcePolicy.setEndDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_ENDDATE));
}
}

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.repository.patch.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy endDate DELETE patch.
*
* Example:
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "remove", "path": "
* /endDate"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyEndDateRemoveOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingEndDateValue(resourcePolicy, operation);
this.delete(resourcePolicy);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual delete endDate of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
*/
private void delete(ResourcePolicy resourcePolicy) {
resourcePolicy.setEndDate(null);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_ENDDATE));
}
}

View File

@@ -0,0 +1,75 @@
/**
* 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.operation.resourcePolicy;
import java.text.ParseException;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy endDate REPLACE patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /endDate", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyEndDateReplaceOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingEndDateValue(resourcePolicy, operation);
resourcePolicyUtils.checkResourcePolicyForConsistentEndDateValue(resourcePolicy, operation);
this.replace(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual replace endDate of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void replace(ResourcePolicy resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = resourcePolicyUtils.simpleDateFormat.parse(dateS);
resourcePolicy.setEndDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_ENDDATE));
}
}

View File

@@ -0,0 +1,76 @@
/**
* 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.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy name ADD patch.
*
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "add", "path": "
* /name", "value": "New Name"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyNameAddOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
this.checkModelForNotExistingValue(resourcePolicy);
this.add(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual add name of resourcePolicy operation
*
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
public void add(ResourcePolicy resourcePolicy, Operation operation) {
String name = (String) operation.getValue();
resourcePolicy.setRpName(name);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_NAME));
}
/**
* Throws PatchBadRequestException if a value is already set in the /name path.
*
* @param resource the resource to update
*/
private void checkModelForNotExistingValue(ResourcePolicy resource) {
if (resource.getRpName() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
}

View File

@@ -0,0 +1,62 @@
/**
* 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.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy name DELETE patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "remove", "path": "
* /name"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyNameRemoveOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingNameValue(resourcePolicy, operation);
this.delete(resourcePolicy);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual delete name of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
*/
private void delete(ResourcePolicy resourcePolicy) {
resourcePolicy.setRpName(null);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_NAME));
}
}

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.patch.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy name REPLACE patch.
*
* Example:
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /name", "value": "New Name"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyNameReplaceOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingNameValue(resourcePolicy, operation);
this.replace(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual replace name of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void replace(ResourcePolicy resourcePolicy, Operation operation) {
String newName = (String) operation.getValue();
resourcePolicy.setRpName(newName);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_NAME));
}
}

View File

@@ -0,0 +1,86 @@
/**
* 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.operation.resourcePolicy;
import java.text.ParseException;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy startDate ADD patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "add", "path": "
* /startDate", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyStartDateAddOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
this.checkResourcePolicyForNotExistingStartDateValue(resourcePolicy);
resourcePolicyUtils.checkResourcePolicyForConsistentStartDateValue(resourcePolicy, operation);
this.add(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual add startDate of resourcePolicy operation
*
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void add(ResourcePolicy resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = resourcePolicyUtils.simpleDateFormat.parse(dateS);
resourcePolicy.setStartDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_STARTDATE));
}
/**
* Throws PatchBadRequestException if a value is already set in the /startDate path.
*
* @param resource the resource to update
*/
void checkResourcePolicyForNotExistingStartDateValue(ResourcePolicy resource) {
if (resource.getStartDate() != null) {
throw new DSpaceBadRequestException("Attempting to add a value to an already existing path.");
}
}
}

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.repository.patch.operation.resourcePolicy;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy startDate DELETE patch.
*
* Example:
*
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "remove", "path": "
* /startDate"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyStartDateRemoveOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingStartDateValue(resourcePolicy, operation);
this.delete(resourcePolicy);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual delete startDate of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
*/
private void delete(ResourcePolicy resourcePolicy) {
resourcePolicy.setStartDate(null);
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_STARTDATE));
}
}

View File

@@ -0,0 +1,74 @@
/**
* 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.operation.resourcePolicy;
import java.text.ParseException;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.repository.patch.operation.PatchOperation;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Implementation for ResourcePolicy startDate REPLACE patch.
*
* Example:
* <code>
* curl -X PATCH http://${dspace.server.url}/api/authz/resourcepolicies/<:id-resourcepolicy> -H "
* Content-Type: application/json" -d '[{ "op": "replace", "path": "
* /startDate", "value": "YYYY-MM-DD"]'
* </code>
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyStartDateReplaceOperation<R> extends PatchOperation<R> {
@Autowired
ResourcePolicyUtils resourcePolicyUtils;
@Override
public R perform(Context context, R resource, Operation operation) {
checkOperationValue(operation.getValue());
if (this.supports(resource, operation)) {
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
resourcePolicyUtils.checkResourcePolicyForExistingStartDateValue(resourcePolicy, operation);
resourcePolicyUtils.checkResourcePolicyForConsistentStartDateValue(resourcePolicy, operation);
this.replace(resourcePolicy, operation);
return resource;
} else {
throw new DSpaceBadRequestException(this.getClass() + " does not support this operation");
}
}
/**
* Performs the actual replace startDate of resourcePolicy operation
* @param resourcePolicy resourcePolicy being patched
* @param operation patch operation
*/
private void replace(ResourcePolicy resourcePolicy, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = resourcePolicyUtils.simpleDateFormat.parse(dateS);
resourcePolicy.setStartDate(date);
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
}
@Override
public boolean supports(Object objectToMatch, Operation operation) {
return (objectToMatch instanceof ResourcePolicy && operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)
&& operation.getPath().trim().equalsIgnoreCase(resourcePolicyUtils.OPERATION_PATH_STARTDATE));
}
}

View File

@@ -0,0 +1,144 @@
/**
* 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.operation.resourcePolicy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.authorize.ResourcePolicy;
import org.springframework.stereotype.Component;
/**
* Util class for shared methods between the ResourcePolicy patches.
*
* @author Maria Verdonck (Atmire) on 14/02/2020
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@Component
public class ResourcePolicyUtils {
public static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
/**
* Paths in json body of patched that use these resourcePolicy operations
*/
public static final String OPERATION_PATH_STARTDATE = "/startDate";
public static final String OPERATION_PATH_ENDDATE = "/endDate";
public static final String OPERATION_PATH_DESCRIPTION = "/description";
public static final String OPERATION_PATH_NAME = "/name";
/**
* Throws PatchBadRequestException for missing value in the /startDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForExistingStartDateValue(ResourcePolicy resource, Operation operation) {
if (resource.getStartDate() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp()
+ " a non-existent start date value.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /endDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForExistingEndDateValue(ResourcePolicy resource, Operation operation) {
if (resource.getEndDate() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp()
+ " a non-existent end date value.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /startDate path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForExistingNameValue(ResourcePolicy resource, Operation operation) {
if (resource.getRpName() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp() + " a non-existent name value.");
}
}
/**
* Throws PatchBadRequestException for missing value in the /description path.
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForExistingDescriptionValue(ResourcePolicy resource, Operation operation) {
if (resource.getRpDescription() == null) {
throw new DSpaceBadRequestException("Attempting to " + operation.getOp()
+ " a non-existent description value.");
}
}
/**
* Throws PatchBadRequestException if the value for startDate is not consistent with the endDate value, if present
* (greater than).
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForConsistentStartDateValue(ResourcePolicy resource, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
if (resource.getEndDate() != null && resource.getEndDate().before(date)) {
throw new DSpaceBadRequestException("Attempting to set an invalid startDate greater than the endDate.");
}
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid startDate value", e);
}
}
/**
* Throws PatchBadRequestException if the value for endDate is not consistent with the startDate value, if present
* (smaller than).
*
* @param resource
* the resource to update
* @param operation
* the operation to apply
*
*/
public void checkResourcePolicyForConsistentEndDateValue(ResourcePolicy resource, Operation operation) {
String dateS = (String) operation.getValue();
try {
Date date = simpleDateFormat.parse(dateS);
if (resource.getEndDate() != null && resource.getStartDate().after(date)) {
throw new DSpaceBadRequestException("Attempting to set an invalid endDate smaller than the startDate.");
}
} catch (ParseException e) {
throw new DSpaceBadRequestException("Invalid endDate value", e);
}
}
}