mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Added allow-bulk-deletion property to specify erasable fields via bulk deletion
This commit is contained in:
@@ -10,12 +10,15 @@ package org.dspace.app.bulkedit;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.MetadataFieldService;
|
||||
import org.dspace.content.service.MetadataValueService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
@@ -27,38 +30,65 @@ import org.dspace.utils.DSpace;
|
||||
*/
|
||||
public class MetadataDeletion extends DSpaceRunnable<MetadataDeletionScriptConfiguration<MetadataDeletion>> {
|
||||
|
||||
private MetadataValueService metadataValueService;
|
||||
|
||||
private MetadataFieldService metadataFieldService;
|
||||
|
||||
private ConfigurationService configurationService;
|
||||
|
||||
private String metadataField;
|
||||
|
||||
private boolean list;
|
||||
|
||||
@Override
|
||||
public void internalRun() throws Exception {
|
||||
Context context = new Context();
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
try {
|
||||
performMetadataValuesDeletion(context);
|
||||
} catch (SQLException e) {
|
||||
handler.handleException(e);
|
||||
if (list) {
|
||||
listErasableMetadata();
|
||||
return;
|
||||
}
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
context.complete();
|
||||
Context context = new Context();
|
||||
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
performMetadataValuesDeletion(context);
|
||||
} finally {
|
||||
context.restoreAuthSystemState();
|
||||
context.complete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void listErasableMetadata() {
|
||||
String[] erasableMetadata = getErasableMetadata();
|
||||
if (ArrayUtils.isEmpty(erasableMetadata)) {
|
||||
handler.logInfo("No fields has been configured to be cleared via bulk deletion");
|
||||
} else {
|
||||
handler.logInfo("The fields that can be bulk deleted are: " + String.join(", ", erasableMetadata));
|
||||
}
|
||||
}
|
||||
|
||||
private void performMetadataValuesDeletion(Context context) throws SQLException {
|
||||
MetadataValueService metadataValueService = ContentServiceFactory.getInstance()
|
||||
.getMetadataValueService();
|
||||
|
||||
MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance()
|
||||
.getMetadataFieldService();
|
||||
|
||||
MetadataField field = metadataFieldService.findByString(context, metadataField, '.');
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("No metadata field found with name " + metadataField);
|
||||
}
|
||||
|
||||
if (!ArrayUtils.contains(getErasableMetadata(), metadataField)) {
|
||||
throw new IllegalArgumentException("The given metadata field cannot be bulk deleted");
|
||||
}
|
||||
|
||||
handler.logInfo(String.format("Deleting the field '%s' from all objects", metadataField));
|
||||
|
||||
metadataValueService.deleteByMetadataField(context, field);
|
||||
}
|
||||
|
||||
private String[] getErasableMetadata() {
|
||||
return configurationService.getArrayProperty("bulkedit.allow-bulk-deletion");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public MetadataDeletionScriptConfiguration<MetadataDeletion> getScriptConfiguration() {
|
||||
@@ -68,7 +98,18 @@ public class MetadataDeletion extends DSpaceRunnable<MetadataDeletionScriptConfi
|
||||
|
||||
@Override
|
||||
public void setup() throws ParseException {
|
||||
|
||||
metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
||||
metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService();
|
||||
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
|
||||
metadataField = commandLine.getOptionValue('m');
|
||||
list = commandLine.hasOption('l');
|
||||
|
||||
if (!list && metadataField == null) {
|
||||
throw new ParseException("One of the following parameters is required: -m or -l");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -37,9 +37,15 @@ public class MetadataDeletionScriptConfiguration<T extends MetadataDeletion> ext
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
if (options == null) {
|
||||
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("m", "metadata", true, "metadata field name");
|
||||
options.getOption("m").setType(String.class);
|
||||
|
||||
options.addOption("l", "list", false, "lists the metadata fields that can be deleted");
|
||||
options.getOption("l").setType(boolean.class);
|
||||
|
||||
super.options = options;
|
||||
}
|
||||
return options;
|
||||
|
@@ -7,8 +7,17 @@
|
||||
*/
|
||||
package org.dspace.app.bulkedit;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.AbstractIntegrationTestWithDatabase;
|
||||
import org.dspace.app.launcher.ScriptLauncher;
|
||||
@@ -22,6 +31,9 @@ import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.MetadataFieldService;
|
||||
import org.dspace.content.service.MetadataValueService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -36,15 +48,100 @@ public class MetadataDeletionIT extends AbstractIntegrationTestWithDatabase {
|
||||
|
||||
private MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService();
|
||||
|
||||
@Test
|
||||
public void metadataDeletionTest() throws Exception {
|
||||
private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context).build();
|
||||
Collection collection = CollectionBuilder.createCollection(context, community).build();
|
||||
createItem(collection, "My First publication", "Mario Rossi");
|
||||
createItem(collection, "Another publication", "John Smith");
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataDeletionListTest() throws Exception {
|
||||
|
||||
configurationService.setProperty("bulkedit.allow-bulk-deletion", new String[] { "dc.title", "dc.type" });
|
||||
|
||||
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||
|
||||
String[] args = new String[] { "metadata-deletion", "-l" };
|
||||
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
List<String> infoMessages = testDSpaceRunnableHandler.getInfoMessages();
|
||||
assertThat(infoMessages, hasSize(1));
|
||||
assertThat(infoMessages, hasItem(equalTo("The fields that can be bulk deleted are: dc.title, dc.type")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataDeletionListWithoutErasableMetadataTest() throws Exception {
|
||||
|
||||
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||
|
||||
String[] args = new String[] { "metadata-deletion", "-l" };
|
||||
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
List<String> infoMessages = testDSpaceRunnableHandler.getInfoMessages();
|
||||
assertThat(infoMessages, hasSize(1));
|
||||
assertThat(infoMessages, hasItem(equalTo("No fields has been configured to be cleared via bulk deletion")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataDeletionTest() throws Exception {
|
||||
|
||||
MetadataField titleField = metadataFieldService.findByElement(context, "dc", "title", null);
|
||||
MetadataField authorField = metadataFieldService.findByElement(context, "dc", "contributor", "author");
|
||||
|
||||
assertThat(metadataValueService.findByField(context, titleField), hasSize(2));
|
||||
assertThat(metadataValueService.findByField(context, authorField), hasSize(2));
|
||||
|
||||
configurationService.setProperty("bulkedit.allow-bulk-deletion", "dc.title");
|
||||
|
||||
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||
|
||||
String[] args = new String[] { "metadata-deletion", "-m", "dc.title" };
|
||||
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
assertThat(metadataValueService.findByField(context, titleField), empty());
|
||||
assertThat(metadataValueService.findByField(context, authorField), hasSize(2));
|
||||
|
||||
List<String> infoMessages = testDSpaceRunnableHandler.getInfoMessages();
|
||||
assertThat(infoMessages, hasSize(1));
|
||||
assertThat(infoMessages, hasItem(equalTo("Deleting the field 'dc.title' from all objects")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataDeletionNotAllowedTest() throws Exception {
|
||||
|
||||
MetadataField titleField = metadataFieldService.findByElement(context, "dc", "title", null);
|
||||
MetadataField authorField = metadataFieldService.findByElement(context, "dc", "contributor", "author");
|
||||
|
||||
assertEquals(2, metadataValueService.findByField(context, titleField).size());
|
||||
assertEquals(2, metadataValueService.findByField(context, authorField).size());
|
||||
|
||||
configurationService.setProperty("bulkedit.allow-bulk-deletion", "dc.type");
|
||||
|
||||
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||
|
||||
String[] args = new String[] { "metadata-deletion", "-m", "dc.title" };
|
||||
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
Exception exception = testDSpaceRunnableHandler.getException();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception, instanceOf(IllegalArgumentException.class));
|
||||
assertThat(exception.getMessage(), is("The given metadata field cannot be bulk deleted"));
|
||||
|
||||
assertEquals(2, metadataValueService.findByField(context, titleField).size());
|
||||
assertEquals(2, metadataValueService.findByField(context, authorField).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataDeletionWithUnknownMetadataTest() throws Exception {
|
||||
|
||||
MetadataField titleField = metadataFieldService.findByElement(context, "dc", "title", null);
|
||||
MetadataField authorField = metadataFieldService.findByElement(context, "dc", "contributor", "author");
|
||||
@@ -54,10 +151,15 @@ public class MetadataDeletionIT extends AbstractIntegrationTestWithDatabase {
|
||||
|
||||
TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler();
|
||||
|
||||
String[] args = new String[] { "metadata-deletion", "-m", "dc.title" };
|
||||
String[] args = new String[] { "metadata-deletion", "-m", "dc.unknown" };
|
||||
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), testDSpaceRunnableHandler, kernelImpl);
|
||||
|
||||
assertTrue(metadataValueService.findByField(context, titleField).isEmpty());
|
||||
Exception exception = testDSpaceRunnableHandler.getException();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception, instanceOf(IllegalArgumentException.class));
|
||||
assertThat(exception.getMessage(), is("No metadata field found with name dc.unknown"));
|
||||
|
||||
assertEquals(2, metadataValueService.findByField(context, titleField).size());
|
||||
assertEquals(2, metadataValueService.findByField(context, authorField).size());
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,9 @@
|
||||
*/
|
||||
package org.dspace.app.scripts.handler.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler;
|
||||
|
||||
/**
|
||||
@@ -17,6 +20,12 @@ public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler
|
||||
|
||||
private Exception exception = null;
|
||||
|
||||
private final List<String> infoMessages = new ArrayList<>();
|
||||
|
||||
private final List<String> errorMessages = new ArrayList<>();
|
||||
|
||||
private final List<String> warningMessages = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* We're overriding this method so that we can stop the script from doing the System.exit() if
|
||||
* an exception within the script is thrown
|
||||
@@ -33,4 +42,34 @@ public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logInfo(String message) {
|
||||
super.logInfo(message);
|
||||
infoMessages.add(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logWarning(String message) {
|
||||
super.logWarning(message);
|
||||
warningMessages.add(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logError(String message) {
|
||||
super.logError(message);
|
||||
errorMessages.add(message);
|
||||
}
|
||||
|
||||
public List<String> getInfoMessages() {
|
||||
return infoMessages;
|
||||
}
|
||||
|
||||
public List<String> getErrorMessages() {
|
||||
return errorMessages;
|
||||
}
|
||||
|
||||
public List<String> getWarningMessages() {
|
||||
return warningMessages;
|
||||
}
|
||||
}
|
||||
|
@@ -1488,6 +1488,9 @@ mail.helpdesk.name = Help Desk
|
||||
# Should all Request Copy emails go to the helpdesk instead of the item submitter?
|
||||
request.item.helpdesk.override = false
|
||||
|
||||
### metadata-deletion script configuration ###
|
||||
bulkedit.allow-bulk-deletion = dspace.agreements.end-user
|
||||
|
||||
|
||||
#------------------------------------------------------------------#
|
||||
#-------------------MODULE CONFIGURATIONS--------------------------#
|
||||
|
Reference in New Issue
Block a user