Skip to content

Commit

Permalink
Merge pull request DSpace#9037 from DSpace/backport-9018-to-dspace-7_x
Browse files Browse the repository at this point in the history
[Port dspace-7_x] Fix different CLI commands throw an exception on help argument
  • Loading branch information
alanorth authored Aug 24, 2023
2 parents bd1eb00 + 1fc8fc6 commit d307727
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.logging.log4j.Logger;
import org.dspace.core.Context;
import org.dspace.scripts.DSpaceRunnable;
import org.dspace.scripts.DSpaceRunnable.StepResult;
import org.dspace.scripts.configuration.ScriptConfiguration;
import org.dspace.scripts.factory.ScriptServiceFactory;
import org.dspace.scripts.handler.DSpaceRunnableHandler;
Expand Down Expand Up @@ -145,8 +146,13 @@ public static int handleScript(String[] args, Document commandConfigs,
private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
DSpaceRunnable script) {
try {
script.initialize(args, dSpaceRunnableHandler, null);
script.run();
StepResult result = script.initialize(args, dSpaceRunnableHandler, null);
// check the StepResult, only run the script if the result is Continue;
// otherwise - for example the script is started with the help as argument, nothing is to do
if (StepResult.Continue.equals(result)) {
// runs the script, the normal initialization is successful
script.run();
}
return 0;
} catch (ParseException e) {
script.printHelp();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* 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.cli;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

/**
* Extended version of the DefaultParser. This parser skip/ignore unknown arguments.
*/
public class DSpaceSkipUnknownArgumentsParser extends DefaultParser {


@Override
public CommandLine parse(Options options, String[] arguments) throws ParseException {
return super.parse(options, getOnlyKnownArguments(options, arguments));
}

@Override
public CommandLine parse(Options options, String[] arguments, Properties properties) throws ParseException {
return super.parse(options, getOnlyKnownArguments(options, arguments), properties);
}

/**
* Parse the arguments according to the specified options and properties.
* @param options the specified Options
* @param arguments the command line arguments
* @param stopAtNonOption can be ignored - an unrecognized argument is ignored, an unrecognized argument doesn't
* stop the parsing and doesn't trigger a ParseException
*
* @return the list of atomic option and value tokens
* @throws ParseException if there are any problems encountered while parsing the command line tokens.
*/
@Override
public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {
return super.parse(options, getOnlyKnownArguments(options, arguments), stopAtNonOption);
}

/**
* Parse the arguments according to the specified options and properties.
* @param options the specified Options
* @param arguments the command line arguments
* @param properties command line option name-value pairs
* @param stopAtNonOption can be ignored - an unrecognized argument is ignored, an unrecognized argument doesn't
* stop the parsing and doesn't trigger a ParseException
*
* @return the list of atomic option and value tokens
* @throws ParseException if there are any problems encountered while parsing the command line tokens.
*/
@Override
public CommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption)
throws ParseException {
return super.parse(options, getOnlyKnownArguments(options, arguments), properties, stopAtNonOption);
}


private String[] getOnlyKnownArguments(Options options, String[] arguments) {
List<String> knownArguments = new ArrayList<>();
for (String arg : arguments) {
if (options.hasOption(arg)) {
knownArguments.add(arg);
}
}
return knownArguments.toArray(new String[0]);
}
}
56 changes: 53 additions & 3 deletions dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.dspace.cli.DSpaceSkipUnknownArgumentsParser;
import org.dspace.eperson.EPerson;
import org.dspace.scripts.configuration.ScriptConfiguration;
import org.dspace.scripts.handler.DSpaceRunnableHandler;
Expand All @@ -36,6 +37,11 @@ public abstract class DSpaceRunnable<T extends ScriptConfiguration> implements R
*/
protected CommandLine commandLine;

/**
* The minimal CommandLine object for the script that'll hold help information
*/
protected CommandLine helpCommandLine;

/**
* This EPerson identifier variable is the UUID of the EPerson that's running the script
*/
Expand Down Expand Up @@ -64,26 +70,66 @@ private void setHandler(DSpaceRunnableHandler dSpaceRunnableHandler) {
* @param args The arguments given to the script
* @param dSpaceRunnableHandler The DSpaceRunnableHandler object that defines from where the script was ran
* @param currentUser
* @return the result of this step; StepResult.Continue: continue the normal process,
* initialize is successful; otherwise exit the process (the help or version is shown)
* @throws ParseException If something goes wrong
*/
public void initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
public StepResult initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler,
EPerson currentUser) throws ParseException {
if (currentUser != null) {
this.setEpersonIdentifier(currentUser.getID());
}
this.setHandler(dSpaceRunnableHandler);
this.parse(args);

// parse the command line in a first step for the help options
// --> no other option is required
StepResult result = this.parseForHelp(args);
switch (result) {
case Exit:
// arguments of the command line matches the help options, handle this
handleHelpCommandLine();
break;

case Continue:
// arguments of the command line matches NOT the help options, parse the args for the normal options
result = this.parse(args);
break;
default:
break;
}

return result;
}


/**
* This method handle the help command line. In this easy implementation only the help is printed. For more
* complexity override this method.
*/
private void handleHelpCommandLine() {
printHelp();
}


/**
* This method will take the primitive array of String objects that represent the parameters given to the String
* and it'll parse these into a CommandLine object that can be used by the script to retrieve the data
* @param args The primitive array of Strings representing the parameters
* @throws ParseException If something goes wrong
*/
private void parse(String[] args) throws ParseException {
private StepResult parse(String[] args) throws ParseException {
commandLine = new DefaultParser().parse(getScriptConfiguration().getOptions(), args);
setup();
return StepResult.Continue;
}

private StepResult parseForHelp(String[] args) throws ParseException {
helpCommandLine = new DSpaceSkipUnknownArgumentsParser().parse(getScriptConfiguration().getHelpOptions(), args);
if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) {
return StepResult.Exit;
}

return StepResult.Continue;
}

/**
Expand Down Expand Up @@ -158,4 +204,8 @@ public UUID getEpersonIdentifier() {
public void setEpersonIdentifier(UUID epersonIdentifier) {
this.epersonIdentifier = epersonIdentifier;
}

public enum StepResult {
Continue, Exit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
Expand Down Expand Up @@ -105,6 +106,19 @@ public boolean isAllowedToExecute(Context context, List<DSpaceCommandLineParamet
*/
public abstract Options getOptions();

/**
* The getter for the options of the Script (help informations)
*
* @return the options value of this ScriptConfiguration for help
*/
public Options getHelpOptions() {
Options options = new Options();

options.addOption(Option.builder("h").longOpt("help").desc("help").hasArg(false).required(false).build());

return options;
}

@Override
public void setBeanName(String beanName) {
this.name = beanName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ public void metadataExportWithoutFileParameter()
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}
}

Expand Down Expand Up @@ -206,8 +207,9 @@ public void metadataExportToCsvTest_NonValidIdentifier() throws Exception {
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}

Exception exceptionDuringTestRun = testDSpaceRunnableHandler.getException();
Expand Down Expand Up @@ -235,8 +237,9 @@ public void metadataExportToCsvTest_NonValidDSOType() throws Exception {
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}

Exception exceptionDuringTestRun = testDSpaceRunnableHandler.getException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ public void metadataImportWithoutEPersonParameterTest()
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,10 @@ public int performImportScript(String[] csv, boolean validateOnly) throws Except
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue
.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}
if (testDSpaceRunnableHandler.getException() != null) {
throw testDSpaceRunnableHandler.getException();
Expand Down
10 changes: 6 additions & 4 deletions dspace-api/src/test/java/org/dspace/curate/CurationIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ public void curationWithoutEPersonParameterTest() throws Exception {
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}
}

Expand All @@ -69,8 +70,9 @@ public void curationWithEPersonParameterTest() throws Exception {
script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration);
}
if (script != null) {
script.initialize(args, testDSpaceRunnableHandler, null);
script.run();
if (DSpaceRunnable.StepResult.Continue.equals(script.initialize(args, testDSpaceRunnableHandler, null))) {
script.run();
}
}
}
}

0 comments on commit d307727

Please sign in to comment.