Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions dspace-api/src/main/java/org/dspace/curate/Curation.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.cli.ParseException;
import org.apache.commons.io.output.NullOutputStream;
import org.dspace.app.util.DSpaceObjectUtilsImpl;
import org.dspace.app.util.service.DSpaceObjectUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.core.Context;
import org.dspace.core.factory.CoreServiceFactory;
import org.dspace.curate.reporters.DoNothingReporter;
import org.dspace.curate.reporters.FilePrinterReporter;
import org.dspace.curate.reporters.SystemOutReporter;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
Expand All @@ -53,6 +51,7 @@ public class Curation extends DSpaceRunnable<CurationScriptConfiguration> {
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected Context context;
private CurationClientOptions curationClientOptions;
private Reporter outputReporter;

private String task;
private String taskFile;
Expand Down Expand Up @@ -173,10 +172,20 @@ private long runQueue(TaskQueue queue, Curator curator) throws SQLException, Aut
* @throws SQLException If DSpace context can't complete
*/
private void endScript(long timeRun) throws SQLException {
context.complete();
if (verbose) {
long elapsed = System.currentTimeMillis() - timeRun;
this.handler.logInfo("Ending curation. Elapsed time: " + elapsed);
try {
context.complete();
if (verbose) {
long elapsed = System.currentTimeMillis() - timeRun;
this.handler.logInfo("Ending curation. Elapsed time: " + elapsed);
}
} finally {
if (outputReporter != null) {
try {
outputReporter.close();
} catch (Exception e) {
handler.handleException("Something went wrong trying to close the reporter", e);
}
}
}
}

Expand All @@ -188,16 +197,14 @@ private void endScript(long timeRun) throws SQLException {
*/
private Curator initCurator() throws FileNotFoundException {
Curator curator = new Curator(handler);
OutputStream reporterStream;
if (null == this.reporter) {
reporterStream = NullOutputStream.NULL_OUTPUT_STREAM;
outputReporter = new DoNothingReporter();
} else if ("-".equals(this.reporter)) {
reporterStream = System.out;
outputReporter = new SystemOutReporter();
} else {
reporterStream = new PrintStream(this.reporter);
outputReporter = new FilePrinterReporter(this.reporter);
}
Writer reportWriter = new OutputStreamWriter(reporterStream);
curator.setReporter(reportWriter);
curator.setReporter(outputReporter);

if (this.scope != null) {
Curator.TxScope txScope = Curator.TxScope.valueOf(this.scope.toUpperCase());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* 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.curate.reporters;

import org.dspace.curate.Reporter;

/**
* Reporter that ignores all input.
*
* @author Milan Kuchtiak
*/
public class DoNothingReporter implements Reporter {

@Override
public Appendable append(CharSequence csq) {
return this;
}

@Override
public Appendable append(CharSequence csq, int start, int end) {
return this;
}

@Override
public Appendable append(char c) {
return this;
}

@Override
public void close() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* 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.curate.reporters;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

import org.apache.commons.lang3.StringUtils;
import org.dspace.curate.Reporter;

/**
* Reporter that writes to a specified file.
*
* @author Milan Kuchtiak
*/
public class FilePrinterReporter implements Reporter {
private final PrintWriter writer;

public FilePrinterReporter(String fileName) throws FileNotFoundException {
File file = new File(fileName);
try {
writer = new PrintWriter(file, StandardCharsets.UTF_8);
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw new RuntimeException("Error initializing FilePrinterReporter for file: " + fileName, e);
}
}

@Override
public Appendable append(CharSequence csq) {
// strip newline from the end of the string to avoid double newlines when using println
// do not print empty lines
if (!StringUtils.isEmpty(csq)) {
writer.println(StringUtils.chomp(csq.toString()));
}
return this;
}

@Override
public Appendable append(CharSequence csq, int start, int end) {
writer.append(csq, start, end);
return this;
}

@Override
public Appendable append(char c) {
writer.append(c);
return this;
}

@Override
public void close() {
// flush and close the writer to ensure all data is written to the file
writer.flush();
writer.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* 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.curate.reporters;

import java.io.PrintWriter;

import org.apache.commons.lang3.StringUtils;
import org.dspace.curate.Reporter;

/**
* Reporter that writes to console (System.out).
*
* @author Milan Kuchtiak
*/
public class SystemOutReporter implements Reporter {

private final PrintWriter writer;

public SystemOutReporter() {
// we use PrintWriter to avoid auto-flush after every println,
// which is the default behavior of System.out.println
writer = new PrintWriter(System.out, false);
}

@Override
public Appendable append(CharSequence csq) {
// strip newline from the end of the string to avoid double newlines when using println
// do not print empty lines
if (!StringUtils.isEmpty(csq)) {
writer.println(StringUtils.chomp(csq.toString()));
}
return this;
}

@Override
public Appendable append(CharSequence csq, int start, int end) {
writer.append(csq, start, end);
return this;
}

@Override
public Appendable append(char c) {
writer.append(c);
return this;
}

@Override
public void close() {
// Note: We don't close the PrintWriter to avoid closing System.out
writer.flush();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* 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.curate;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;
import java.nio.file.Files;

import org.dspace.AbstractDSpaceTest;
import org.dspace.content.Item;
import org.dspace.core.factory.CoreServiceFactory;
import org.dspace.ctask.general.NoOpCurationTask;
import org.dspace.curate.reporters.DoNothingReporter;
import org.dspace.curate.reporters.FilePrinterReporter;
import org.dspace.curate.reporters.SystemOutReporter;
import org.dspace.services.ConfigurationService;
import org.junit.Before;
import org.junit.Test;

/**
* Test different Reporter implementations with Curator.
*
* @author Milan Kuchtiak
*/
public class CuratorReporterTest extends AbstractDSpaceTest {
private static final String TASK_NAME = "noop";
private static final String TEST_HANDLE = "testHandle";
private static final String NO_OP = "No operation performed on " + TEST_HANDLE;

private Curator curator;

@Before
public void setup() {
CoreServiceFactory.getInstance().getPluginService().clearNamedPluginClasses();

// Configure the noop task to be run.
ConfigurationService cfg = kernelImpl.getConfigurationService();
cfg.setProperty("plugin.named.org.dspace.curate.CurationTask",
NoOpCurationTask.class.getName() + " = " + TASK_NAME);

// Get and configure a Curator.
curator = new Curator();
}

@Test
public void testCurateWithDoNothingReporter() throws Exception {
try (Reporter reporter = new DoNothingReporter()) {
runCuratorWithReporter(reporter);
}
}

@Test
public void testCurateWithSystemOutReporter() throws Exception {
try (Reporter reporter = new SystemOutReporter()) {
runCuratorWithReporter(reporter);
}
}

@Test
public void testCurateWithFilePrinterReporter() throws Exception {
File tempFile = File.createTempFile("curator-test-report", "txt");
try (Reporter reporter = new FilePrinterReporter(tempFile.getAbsolutePath())) {
runCuratorWithReporter(reporter);
}
// check if the file contains expected line with one line separator
String fileOutput = Files.readString(tempFile.toPath());
assertEquals(NO_OP + System.lineSeparator(), fileOutput);
}

@Test
public void testCurateWithStringBuilder() throws Exception {
StringBuilder stringBuilder = new StringBuilder();
runCuratorWithReporter(stringBuilder);
assertEquals(NO_OP, stringBuilder.toString());
}

private void runCuratorWithReporter(Appendable reporter) throws Exception {
curator.setReporter(reporter);
curator.addTask(TASK_NAME);
Item item = mock(Item.class);
when(item.getType()).thenReturn(2);
when(item.getHandle()).thenReturn(TEST_HANDLE);
curator.curate(item);

assertEquals(Curator.CURATE_SUCCESS, curator.getStatus(TASK_NAME));
assertEquals(NO_OP, curator.getResult(TASK_NAME));
}

}