mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
implemented patch operations for AccessConditions in submission
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
<name-map collection-handle="default" submission-name="traditional"/>
|
||||
<name-map collection-handle="123456789/language-test-1" submission-name="languagetestprocess"/>
|
||||
<name-map collection-handle="123456789/extraction-test" submission-name="extractiontestprocess"/>
|
||||
<name-map collection-handle="123456789/accessCondition-not-discoverable" submission-name="accessConditionNotDiscoverable"/>
|
||||
</submission-map>
|
||||
|
||||
|
||||
@@ -75,6 +76,18 @@
|
||||
<scope visibilityOutside="read-only">submission</scope>
|
||||
</step-definition>
|
||||
|
||||
<step-definition id="defaultAC">
|
||||
<heading>submit.progressbar.accessCondition</heading>
|
||||
<processing-class>org.dspace.app.rest.submit.step.AccessConditionStep</processing-class>
|
||||
<type>accessCondition</type>
|
||||
</step-definition>
|
||||
|
||||
<step-definition id="notDiscoverable">
|
||||
<heading>submit.progressbar.accessCondition</heading>
|
||||
<processing-class>org.dspace.app.rest.submit.step.AccessConditionStep</processing-class>
|
||||
<type>accessCondition</type>
|
||||
</step-definition>
|
||||
|
||||
<!-- Step Upload Item with Embargo Features to enable this step, please
|
||||
make sure to comment-out the previous step "UploadStep" <step-definition id="upload-with-embargo">
|
||||
<heading>submit.progressbar.upload</heading> <processing-class>org.dspace.submit.step.UploadWithEmbargoStep</processing-class>
|
||||
@@ -146,6 +159,7 @@
|
||||
<step id="upload"/>
|
||||
<!-- <step id="upload-with-embargo"/> -->
|
||||
<!-- <step id="extractionstep"/> -->
|
||||
<step id="defaultAC"/>
|
||||
|
||||
<!--Step will be to Sign off on the License -->
|
||||
<step id="license"/>
|
||||
@@ -167,6 +181,12 @@
|
||||
<step id="cclicense"/>
|
||||
</submission-process>
|
||||
|
||||
<submission-process name="accessConditionNotDiscoverable">
|
||||
<step id="collection"/>
|
||||
<step id="traditionalpageone"/>
|
||||
<step id="notDiscoverable"/>
|
||||
</submission-process>
|
||||
|
||||
</submission-definitions>
|
||||
|
||||
</item-submission>
|
||||
|
@@ -82,7 +82,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="accessConditionConfigurationNotDiscoverable" class="org.dspace.submit.model.AccessConditionConfiguration">
|
||||
<property name="name" value="defaultAC"></property>
|
||||
<property name="name" value="notDiscoverable"></property>
|
||||
<property name="discoverable" value="false"></property>
|
||||
<property name="options">
|
||||
<list>
|
||||
|
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* 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.submit.factory.impl;
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.model.AccessConditionDTO;
|
||||
import org.dspace.app.rest.model.patch.LateObjectEvaluator;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.InProgressSubmission;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.submit.model.AccessConditionConfiguration;
|
||||
import org.dspace.submit.model.AccessConditionConfigurationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Submission "add" operation to add custom resource policies.
|
||||
*
|
||||
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.com)
|
||||
*/
|
||||
public class AccessConditionAddPatchOperation extends AddPatchOperation<AccessConditionDTO> {
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
@Autowired
|
||||
private ResourcePolicyService resourcePolicyService;
|
||||
@Autowired
|
||||
private AccessConditionConfigurationService accessConditionConfigurationService;
|
||||
|
||||
@Override
|
||||
void add(Context context, HttpServletRequest currentRequest, InProgressSubmission source, String path, Object value)
|
||||
throws Exception {
|
||||
|
||||
String stepId = (String) currentRequest.getAttribute("accessConditionSectionId");
|
||||
AccessConditionConfiguration configuration = accessConditionConfigurationService.getMap().get(stepId);
|
||||
|
||||
//"path": "/sections/<:name-of-the-form>/accessConditions/-"
|
||||
String[] split = getAbsolutePath(path).split("/");
|
||||
Item item = source.getItem();
|
||||
|
||||
List<AccessConditionDTO> accessConditions = new ArrayList<AccessConditionDTO>();
|
||||
|
||||
if (split.length == 1) {
|
||||
// to replace completely the access conditions
|
||||
authorizeService.removePoliciesActionFilter(context, item, Constants.READ);
|
||||
accessConditions = evaluateArrayObject((LateObjectEvaluator) value);
|
||||
} else if (split.length == 2) {
|
||||
// to add an access condition
|
||||
// contains "-", call index-based accessConditions it make not sense
|
||||
accessConditions.add(evaluateSingleObject((LateObjectEvaluator) value));
|
||||
}
|
||||
|
||||
verifyAccessConditions(context, configuration, accessConditions);
|
||||
// check duplicate policy
|
||||
checkDuplication(context, item, accessConditions);
|
||||
// apply policies
|
||||
AccessConditionResourcePolicyUtils.findApplyResourcePolicy(context, configuration.getOptions(), item,
|
||||
accessConditions);
|
||||
}
|
||||
|
||||
private void verifyAccessConditions(Context context, AccessConditionConfiguration configuration,
|
||||
List<AccessConditionDTO> accessConditions) throws SQLException, AuthorizeException, ParseException {
|
||||
for (AccessConditionDTO dto : accessConditions) {
|
||||
AccessConditionResourcePolicyUtils.canApplyResourcePolicy(context, configuration.getOptions(),
|
||||
dto.getName(), dto.getStartDate(), dto.getEndDate());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDuplication(Context context, Item item, List<AccessConditionDTO> accessConditions)
|
||||
throws SQLException {
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(context, item, ResourcePolicy.TYPE_CUSTOM);
|
||||
for (ResourcePolicy resourcePolicy : policies) {
|
||||
for (AccessConditionDTO dto : accessConditions) {
|
||||
if (dto.getName().equals(resourcePolicy.getRpName())) {
|
||||
throw new UnprocessableEntityException("A policy of the same type already exists!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<AccessConditionDTO[]> getArrayClassForEvaluation() {
|
||||
return AccessConditionDTO[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<AccessConditionDTO> getClassForEvaluation() {
|
||||
return AccessConditionDTO.class;
|
||||
}
|
||||
|
||||
}
|
@@ -55,7 +55,7 @@ public class AccessConditionRemovePatchOperation extends RemovePatchOperation<Ac
|
||||
}
|
||||
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(context, item, ResourcePolicy.TYPE_CUSTOM);
|
||||
if ((idxToDelete < 0 || idxToDelete >= policies.size()) && policies.isEmpty()) {
|
||||
if (idxToDelete < 0 || idxToDelete >= policies.size()) {
|
||||
throw new UnprocessableEntityException("The provided index:" + idxToDelete + " is not supported,"
|
||||
+ " currently the are " + policies.size() + " access conditions");
|
||||
}
|
||||
|
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* 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.submit.factory.impl;
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.model.AccessConditionDTO;
|
||||
import org.dspace.app.rest.model.patch.JsonValueEvaluator;
|
||||
import org.dspace.app.rest.model.patch.LateObjectEvaluator;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.InProgressSubmission;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.submit.model.AccessConditionConfiguration;
|
||||
import org.dspace.submit.model.AccessConditionConfigurationService;
|
||||
import org.dspace.submit.model.AccessConditionOption;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Submission "replace" operation to replace custom resource policies.
|
||||
*
|
||||
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.com)
|
||||
*/
|
||||
public class AccessConditionReplacePatchOperation extends ReplacePatchOperation<AccessConditionDTO> {
|
||||
|
||||
@Autowired
|
||||
private ResourcePolicyService resourcePolicyService;
|
||||
@Autowired
|
||||
private AccessConditionConfigurationService accessConditionConfigurationService;
|
||||
|
||||
@Override
|
||||
void replace(Context context, HttpServletRequest currentRequest, InProgressSubmission source, String path,
|
||||
Object value) throws Exception {
|
||||
|
||||
String stepId = (String) currentRequest.getAttribute("accessConditionSectionId");
|
||||
AccessConditionConfiguration configuration = accessConditionConfigurationService.getMap().get(stepId);
|
||||
|
||||
// "path" : "/sections/<:name-of-the-form>/accessConditions/0"
|
||||
String[] split = getAbsolutePath(path).split("/");
|
||||
Item item = source.getItem();
|
||||
if (split.length == 2) {
|
||||
int toReplace = Integer.parseInt(split[1]);
|
||||
AccessConditionDTO accessConditionDTO = evaluateSingleObject((LateObjectEvaluator) value);
|
||||
if (Objects.nonNull(accessConditionDTO) && Objects.nonNull(getOption(configuration, accessConditionDTO))) {
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(context, item, ResourcePolicy.TYPE_CUSTOM);
|
||||
if ((toReplace < 0 || toReplace >= policies.size()) && policies.isEmpty()) {
|
||||
throw new UnprocessableEntityException("The provided index:" + toReplace + " is not supported,"
|
||||
+ " currently the are " + policies.size() + " access conditions");
|
||||
}
|
||||
if (checkDubblication(context, configuration, policies, accessConditionDTO, toReplace, item)) {
|
||||
context.commit();
|
||||
resourcePolicyService.delete(context, policies.get(toReplace));
|
||||
getOption(configuration, accessConditionDTO).createPolicy(context, item,
|
||||
accessConditionDTO.getName(), null, accessConditionDTO.getStartDate(),
|
||||
accessConditionDTO.getEndDate());
|
||||
}
|
||||
}
|
||||
} else if (split.length == 3) {
|
||||
String valueToReplare = getValue(value);
|
||||
int toReplace = Integer.parseInt(split[1]);
|
||||
String attributeReplace = split[2];
|
||||
List<ResourcePolicy> policies = resourcePolicyService.find(context, item, ResourcePolicy.TYPE_CUSTOM);
|
||||
if ((toReplace < 0 || toReplace >= policies.size()) && policies.isEmpty()) {
|
||||
throw new UnprocessableEntityException("The provided index:" + toReplace + " is not supported,"
|
||||
+ " currently the are " + policies.size() + " access conditions");
|
||||
}
|
||||
ResourcePolicy rpToReplace = policies.get(toReplace);
|
||||
AccessConditionDTO accessConditionDTO = createDTO(rpToReplace, attributeReplace, valueToReplare);
|
||||
boolean canApplay = AccessConditionResourcePolicyUtils.canApplyResourcePolicy(context,
|
||||
configuration.getOptions(), accessConditionDTO.getName(), accessConditionDTO.getStartDate(),
|
||||
accessConditionDTO.getEndDate());
|
||||
if (canApplay) {
|
||||
switch (attributeReplace) {
|
||||
case "name":
|
||||
rpToReplace.setRpName(valueToReplare);
|
||||
break;
|
||||
case "startDate":
|
||||
rpToReplace.setStartDate(new Date(valueToReplare));
|
||||
break;
|
||||
case "endDate":
|
||||
rpToReplace.setEndDate(new Date(valueToReplare));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
resourcePolicyService.update(context, rpToReplace);
|
||||
}
|
||||
}
|
||||
|
||||
private AccessConditionDTO createDTO(ResourcePolicy rpToReplace, String attributeReplace, String valueToReplare) {
|
||||
AccessConditionDTO accessCondition = new AccessConditionDTO();
|
||||
switch (attributeReplace) {
|
||||
case "name":
|
||||
accessCondition.setName(valueToReplare);
|
||||
accessCondition.setStartDate(rpToReplace.getStartDate());
|
||||
accessCondition.setEndDate(rpToReplace.getEndDate());
|
||||
return accessCondition;
|
||||
case "startDate":
|
||||
accessCondition.setName(rpToReplace.getRpName());
|
||||
accessCondition.setStartDate(new Date(valueToReplare));
|
||||
accessCondition.setEndDate(rpToReplace.getEndDate());
|
||||
return accessCondition;
|
||||
case "endDate":
|
||||
accessCondition.setName(rpToReplace.getRpName());
|
||||
accessCondition.setStartDate(rpToReplace.getStartDate());
|
||||
accessCondition.setEndDate(new Date(valueToReplare));
|
||||
return accessCondition;
|
||||
default:
|
||||
throw new UnprocessableEntityException("The provided attribute: "
|
||||
+ attributeReplace + " is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
private String getValue(Object value) {
|
||||
if (value instanceof JsonValueEvaluator) {
|
||||
JsonValueEvaluator jsonValue = (JsonValueEvaluator) value;
|
||||
if (jsonValue.getValueNode().fields().hasNext()) {
|
||||
return jsonValue.getValueNode().fields().next().getValue().asText();
|
||||
}
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
private AccessConditionOption getOption(AccessConditionConfiguration configuration,
|
||||
AccessConditionDTO accessConditionDTO) {
|
||||
for (AccessConditionOption option :configuration.getOptions()) {
|
||||
if (option.getName().equals(accessConditionDTO.getName())) {
|
||||
return option;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean checkDubblication(Context context, AccessConditionConfiguration configuration,
|
||||
List<ResourcePolicy> policies, AccessConditionDTO accessConditionDTO, int toReplace, Item item)
|
||||
throws SQLException, AuthorizeException, ParseException {
|
||||
ResourcePolicy rp = policies.get(toReplace);
|
||||
if (rp.getRpName().equals(accessConditionDTO.getName())) {
|
||||
boolean canApplay = AccessConditionResourcePolicyUtils.canApplyResourcePolicy(context,
|
||||
configuration.getOptions(), accessConditionDTO.getName(),
|
||||
accessConditionDTO.getStartDate(), accessConditionDTO.getEndDate());
|
||||
if (canApplay) {
|
||||
item.getResourcePolicies().remove(rp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (ResourcePolicy resourcePolicy : policies) {
|
||||
if (resourcePolicy.getRpName().equals(accessConditionDTO.getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
item.getResourcePolicies().remove(rp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<AccessConditionDTO[]> getArrayClassForEvaluation() {
|
||||
return AccessConditionDTO[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<AccessConditionDTO> getClassForEvaluation() {
|
||||
return AccessConditionDTO.class;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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.submit.factory.impl;
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.model.AccessConditionDTO;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.submit.model.AccessConditionOption;
|
||||
|
||||
/**
|
||||
* Utility class to reuse methods related to resource-policies
|
||||
*
|
||||
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
|
||||
*/
|
||||
public class AccessConditionResourcePolicyUtils {
|
||||
|
||||
private AccessConditionResourcePolicyUtils() {}
|
||||
|
||||
public static void findApplyResourcePolicy(Context context, List<AccessConditionOption> accessConditionOptions,
|
||||
DSpaceObject obj, List<AccessConditionDTO> newAccessConditions)
|
||||
throws SQLException, AuthorizeException, ParseException {
|
||||
for (AccessConditionDTO newAccessCondition : newAccessConditions) {
|
||||
String name = newAccessCondition.getName();
|
||||
String description = newAccessCondition.getDescription();
|
||||
|
||||
Date startDate = newAccessCondition.getStartDate();
|
||||
Date endDate = newAccessCondition.getEndDate();
|
||||
|
||||
findApplyResourcePolicy(context, accessConditionOptions, obj, name, description, startDate, endDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void findApplyResourcePolicy(Context context,
|
||||
List<AccessConditionOption> accessConditionOptions, DSpaceObject obj, String name,
|
||||
String description, Date startDate, Date endDate) throws SQLException, AuthorizeException, ParseException {
|
||||
boolean found = false;
|
||||
for (AccessConditionOption accessConditionOption : accessConditionOptions) {
|
||||
if (!found && accessConditionOption.getName().equalsIgnoreCase(name)) {
|
||||
accessConditionOption.createResourcePolicy(context, obj, name, description, startDate, endDate);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new UnprocessableEntityException("The provided policy: " + name + " is not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canApplyResourcePolicy(Context context,
|
||||
List<AccessConditionOption> accessConditionOptions, String name, Date startDate, Date endDate)
|
||||
throws SQLException, AuthorizeException, ParseException {
|
||||
for (AccessConditionOption accessConditionOption : accessConditionOptions) {
|
||||
if (accessConditionOption.getName().equalsIgnoreCase(name)) {
|
||||
return accessConditionOption.canCreateResourcePolicy(context, name, startDate, endDate);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -86,7 +86,7 @@
|
||||
<bean
|
||||
class="org.dspace.app.rest.submit.factory.impl.BitstreamRemovePatchOperation" />
|
||||
</entry>
|
||||
<entry key="accessConditions">
|
||||
<entry key="upload.accessConditions">
|
||||
<bean
|
||||
class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyRemovePatchOperation"/>
|
||||
</entry>
|
||||
|
Reference in New Issue
Block a user