From 0bafa3a1598a219b579520135b97901c596c8109 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 7 Jan 2013 14:50:44 -0500 Subject: [PATCH 01/15] [DS-1083] Command line tool for manipulating EPersons --- .../main/java/org/dspace/eperson/EPerson.java | 222 ++++++++++++++++++ dspace/config/launcher.xml | 8 + 2 files changed, 230 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index 6800f065ef..44db019d12 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -10,6 +10,14 @@ package org.dspace.eperson; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionGroup; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.commons.cli.HelpFormatter; import org.apache.commons.codec.DecoderException; import org.apache.log4j.Logger; @@ -1163,4 +1171,218 @@ public class EPerson extends DSpaceObject } + /** + * Tool for manipulating user accounts. + */ + public static void main(String argv[]) + { + final Option VERB_ADD = new Option("a", "add", false, "create a new EPerson"); + final Option VERB_DELETE = new Option("d", "delete", false, "delete an existing EPerson"); + final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); + final Option VERB_MODIFY = new Option("M", "modify", false, "modify an EPerson"); + + final Option OPT_GIVENNAME = new Option("g", "givenname", true, "the person's actual first or personal name"); + final Option OPT_SURNAME = new Option("s", "surname", true, "the person's actual last or family name"); + final Option OPT_TELEPHONE = new Option("t", "telephone", true, "telephone number, empty for none"); + final Option OPT_LANGUAGE = new Option("l", "language", true, "the person's preferred language"); + final Option OPT_REQUIRE_CERTIFICATE = new Option("c", "requireCertificate", false, "if specified, an X.509 certificate will be required for login"); + final Option OPT_NO_CERTIFICATE = new Option("C", "noCertificate", false, "if specified, no X.509 certificate will be demanded for login"); + + final CommandLineParser parser = new PosixParser(); + CommandLine command = null; + Option option; + + final OptionGroup verbs = new OptionGroup(); + verbs.addOption(VERB_ADD); + verbs.addOption(VERB_DELETE); + verbs.addOption(VERB_LIST); + verbs.addOption(VERB_MODIFY); + + final Options globalOptions = new Options(); + globalOptions.addOptionGroup(verbs); + globalOptions.addOption("h", "help", false, "explain options"); + + final OptionGroup identity; + identity = new OptionGroup(); + identity.setRequired(true); + option = new Option("m", "email", true, "the user's email address, empty for none"); + identity.addOption(option); + option = new Option("n", "netid", true, "network ID associated with the person, empty for none"); + identity.addOption(option); + + try { + command = parser.parse(globalOptions, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user [options]", globalOptions); + System.exit(0); + } + + Context context = null; + try { + context = new Context(); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } + + // Disable authorization since this only runs from the local commandline. + context.turnOffAuthorisationSystem(); + + if (command.hasOption('a')) + { + // Create a user. + Options options = new Options(); + + options.addOption(VERB_ADD); + + options.addOptionGroup(identity); + + option = new Option("p", "password", true, "password to match the EPerson name"); + option.setRequired(true); + options.addOption(option); + + options.addOption(OPT_GIVENNAME); + options.addOption(OPT_SURNAME); + options.addOption(OPT_TELEPHONE); + options.addOption(OPT_LANGUAGE); + options.addOption(OPT_REQUIRE_CERTIFICATE); + options.addOption(OPT_NO_CERTIFICATE); + + options.addOption("h", "help", false, "explain -add options"); + + try { + command = parser.parse(options, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user --add [options]", globalOptions); + System.exit(0); + } + + EPerson eperson = null; + try { + eperson = create(context); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { /* XXX SNH */ } + eperson.setCanLogIn(true); + eperson.setEmail(command.getOptionValue('m')); + eperson.setFirstName(command.getOptionValue('g')); + eperson.setLastName(command.getOptionValue('s')); + eperson.setLanguage(command.getOptionValue('l')); + eperson.setNetid(command.getOptionValue('n')); + eperson.setPassword(command.getOptionValue('p')); + eperson.setRequireCertificate(command.hasOption('c')); + eperson.setSelfRegistered(false); + try { + eperson.update(); + context.commit(); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { /* XXX SNH */ } + } + else if (command.hasOption('d')) + { + // Delete a user. + Options options = new Options(); + + options.addOption(VERB_DELETE); + + options.addOptionGroup(identity); + + try { + command = parser.parse(options, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user --delete [options]", globalOptions); + System.exit(0); + } + + EPerson eperson = null; + try { + if (command.hasOption('n')) + { + eperson = findByNetid(context, command.getOptionValue('n')); + } + else + { + eperson = findByEmail(context, command.getOptionValue('m')); + } + } catch (SQLException e) { + System.err.append(e.getMessage()); + System.exit(1); + } catch (AuthorizeException e) { /* XXX SNH */ } + + if (null == eperson) + { + System.err.println("No such EPerson"); + } + else + { + try { + eperson.delete(); + context.commit(); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } catch (EPersonDeletionException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } + } + } + else if (command.hasOption('m')) + { + // TODO Modify a user. + } + else if (command.hasOption('L')) + { + // List users + // XXX ideas: + // specific user/netid + // wild or regex match user/netid + // select details (pseudo-format string) + try { + for (EPerson person : findAll(context, EMAIL)) + { + System.out.printf("%d\t%s/%s\t%s, %s\n", + person.getID(), + person.getEmail(), + person.getNetid(), + person.getLastName(), person.getFirstName()); // TODO more user details + } + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } + } + else + { + System.err.println("Unknown operation."); + context.abort(); + System.exit(1); + } + } } diff --git a/dspace/config/launcher.xml b/dspace/config/launcher.xml index 52d9a3c900..32e5ba767b 100644 --- a/dspace/config/launcher.xml +++ b/dspace/config/launcher.xml @@ -371,6 +371,14 @@ + + user + Manipulate a normal user account + + org.dspace.eperson.EPerson + + + migrate-embargo Embargo manager tool used to migrate old version of Embargo to the new one included in dspace3 From 6bd7a1d6af8925c0cdc259c9c653e8d21ecac323 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 9 Jan 2013 10:31:31 -0500 Subject: [PATCH 02/15] Add 'read' command to execute a file of commands. --- .../dspace/app/launcher/ScriptLauncher.java | 403 +++++++++++------- 1 file changed, 252 insertions(+), 151 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index e912038b89..3eed844101 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -7,6 +7,15 @@ */ package org.dspace.app.launcher; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StreamTokenizer; +import java.lang.reflect.Method; +import java.util.List; +import java.util.ArrayList; import org.dspace.core.ConfigurationManager; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; @@ -14,8 +23,6 @@ import org.dspace.services.RequestService; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; -import java.util.List; -import java.lang.reflect.Method; /** * A DSpace script launcher. @@ -34,6 +41,7 @@ public class ScriptLauncher * @param args Any parameters required to be passed to the scripts it executes */ public static void main(String[] args) + throws FileNotFoundException, IOException { // Check that there is at least one argument if (args.length < 1) @@ -66,155 +74,24 @@ public class ScriptLauncher throw new IllegalStateException(message, e); } - // Parse the configuration file looking for the command entered + // Parse the configuration file. Document doc = getConfig(); - String request = args[0]; - Element root = doc.getRootElement(); - List commands = root.getChildren("command"); - for (Element command : commands) + + // Look up command(s) in the configuration, and execute. + int status; + if ("read".equalsIgnoreCase(args[0])) { - if (request.equalsIgnoreCase(command.getChild("name").getValue())) + if (args.length < 2) { - // Run each step - List steps = command.getChildren("step"); - for (Element step : steps) - { - // Instantiate the class - Class target = null; - - // Is it the special case 'dsrun' where the user provides the class name? - String className; - if ("dsrun".equals(request)) - { - if (args.length < 2) - { - System.err.println("Error in launcher.xml: Missing class name"); - System.exit(1); - } - className = args[1]; - } - else { - className = step.getChild("class").getValue(); - } - try - { - target = Class.forName(className, - true, - Thread.currentThread().getContextClassLoader()); - } - catch (ClassNotFoundException e) - { - System.err.println("Error in launcher.xml: Invalid class name: " + className); - System.exit(1); - } - - // Strip the leading argument from the args, and add the arguments - // Set false if the arguments should not be passed on - String[] useargs = args.clone(); - Class[] argTypes = {useargs.getClass()}; - boolean passargs = true; - if ((step.getAttribute("passuserargs") != null) && - ("false".equalsIgnoreCase(step.getAttribute("passuserargs").getValue()))) - { - passargs = false; - } - if ((args.length == 1) || (("dsrun".equals(request)) && (args.length == 2)) || (!passargs)) - { - useargs = new String[0]; - } - else - { - // The number of arguments to ignore - // If dsrun is the command, ignore the next, as it is the class name not an arg - int x = 1; - if ("dsrun".equals(request)) - { - x = 2; - } - String[] argsnew = new String[useargs.length - x]; - for (int i = x; i < useargs.length; i++) - { - argsnew[i - x] = useargs[i]; - } - useargs = argsnew; - } - - // Add any extra properties - List bits = step.getChildren("argument"); - if (step.getChild("argument") != null) - { - String[] argsnew = new String[useargs.length + bits.size()]; - int i = 0; - for (Element arg : bits) - { - argsnew[i++] = arg.getValue(); - } - for (; i < bits.size() + useargs.length; i++) - { - argsnew[i] = useargs[i - bits.size()]; - } - useargs = argsnew; - } - - // Establish the request service startup - RequestService requestService = kernelImpl.getServiceManager().getServiceByName(RequestService.class.getName(), RequestService.class); - if (requestService == null) { - throw new IllegalStateException("Could not get the DSpace RequestService to start the request transaction"); - } - - // Establish a request related to the current session - // that will trigger the various request listeners - requestService.startRequest(); - - // Run the main() method - try - { - Object[] arguments = {useargs}; - - // Useful for debugging, so left in the code... - /**System.out.print("About to execute: " + className); - for (String param : useargs) - { - System.out.print(" " + param); - } - System.out.println("");**/ - - Method main = target.getMethod("main", argTypes); - main.invoke(null, arguments); - - // ensure we close out the request (happy request) - requestService.endRequest(null); - } - catch (Exception e) - { - // Failure occurred in the request so we destroy it - requestService.endRequest(e); - - if (kernelImpl != null) - { - kernelImpl.destroy(); - kernelImpl = null; - } - - // Exceptions from the script are reported as a 'cause' - Throwable cause = e.getCause(); - System.err.println("Exception: " + cause.getMessage()); - cause.printStackTrace(); - System.exit(1); - } - - } - - // Destroy the service kernel - if (kernelImpl != null) - { - kernelImpl.destroy(); - kernelImpl = null; - } - - // Everything completed OK - System.exit(0); + System.err.println("'read' must have a single filename argument"); + System.exit(1); } + + status = runManyCommands(doc, args[1]); + } + else + { + status = runOneCommand(doc, args); } // Destroy the service kernel if it is still alive @@ -224,10 +101,234 @@ public class ScriptLauncher kernelImpl = null; } - // The command wasn't found - System.err.println("Command not found: " + args[0]); - display(); - System.exit(1); + System.exit(status); + } + + /** + * Read a file of command lines and execute each in turn. + * + * @param doc details of recognized commands. + * @param script the file of command lines to be executed. + * @return + * @throws FileNotFoundException + * @throws IOException + */ + static private int runManyCommands(Document doc, String script) + throws FileNotFoundException, IOException + { + Reader input; + if ("-".equals(script)) + { + input = new InputStreamReader(System.in); + } + else + { + input = new FileReader(script); + } + + StreamTokenizer tokenizer = new StreamTokenizer(input); + + tokenizer.eolIsSignificant(true); + tokenizer.ordinaryChar('-'); + tokenizer.wordChars('-', '-'); + tokenizer.ordinaryChars('0', '9'); + tokenizer.wordChars('0', '9'); + tokenizer.ordinaryChar('.'); + tokenizer.wordChars('.', '.'); + + int status = 0; + List tokens = new ArrayList(); + while (StreamTokenizer.TT_EOF != tokenizer.nextToken()) + { + if (StreamTokenizer.TT_EOL == tokenizer.ttype) + { + status = runOneCommand(doc, + tokens.toArray(new String[tokens.size()])); + if (status > 0) + { + break; + } + tokens.clear(); + } + else + { + tokens.add(tokenizer.sval); + } + } + + return status; + } + + /** + * Recognize and execute a single command. + * @param doc + * @param args + */ + static private int runOneCommand(Document doc, String[] args) + { + String request = args[0]; + Element root = doc.getRootElement(); + List commands = root.getChildren("command"); + Element command = null; + for (Element candidate : commands) + { + if (request.equalsIgnoreCase(command.getChild("name").getValue())) + { + command = candidate; + break; + } + } + + if (null == command) + { + // The command wasn't found + System.err.println("Command not found: " + args[0]); + display(); + return 1; + } + + // Run each step + List steps = command.getChildren("step"); + for (Element step : steps) + { + // Instantiate the class + Class target = null; + + // Is it the special case 'dsrun' where the user provides the class name? + String className; + if ("dsrun".equals(request)) + { + if (args.length < 2) + { + System.err.println("Error in launcher.xml: Missing class name"); + return 1; + } + className = args[1]; + } + else { + className = step.getChild("class").getValue(); + } + try + { + target = Class.forName(className, + true, + Thread.currentThread().getContextClassLoader()); + } + catch (ClassNotFoundException e) + { + System.err.println("Error in launcher.xml: Invalid class name: " + className); + return 1; + } + + // Strip the leading argument from the args, and add the arguments + // Set false if the arguments should not be passed on + String[] useargs = args.clone(); + Class[] argTypes = {useargs.getClass()}; + boolean passargs = true; + if ((step.getAttribute("passuserargs") != null) && + ("false".equalsIgnoreCase(step.getAttribute("passuserargs").getValue()))) + { + passargs = false; + } + if ((args.length == 1) || (("dsrun".equals(request)) && (args.length == 2)) || (!passargs)) + { + useargs = new String[0]; + } + else + { + // The number of arguments to ignore + // If dsrun is the command, ignore the next, as it is the class name not an arg + int x = 1; + if ("dsrun".equals(request)) + { + x = 2; + } + String[] argsnew = new String[useargs.length - x]; + for (int i = x; i < useargs.length; i++) + { + argsnew[i - x] = useargs[i]; + } + useargs = argsnew; + } + + // Add any extra properties + List bits = step.getChildren("argument"); + if (step.getChild("argument") != null) + { + String[] argsnew = new String[useargs.length + bits.size()]; + int i = 0; + for (Element arg : bits) + { + argsnew[i++] = arg.getValue(); + } + for (; i < bits.size() + useargs.length; i++) + { + argsnew[i] = useargs[i - bits.size()]; + } + useargs = argsnew; + } + + // Establish the request service startup + RequestService requestService = kernelImpl.getServiceManager().getServiceByName( + RequestService.class.getName(), RequestService.class); + if (requestService == null) + { + throw new IllegalStateException( + "Could not get the DSpace RequestService to start the request transaction"); + } + + // Establish a request related to the current session + // that will trigger the various request listeners + requestService.startRequest(); + + // Run the main() method + try + { + Object[] arguments = {useargs}; + + // Useful for debugging, so left in the code... + /**System.out.print("About to execute: " + className); + for (String param : useargs) + { + System.out.print(" " + param); + } + System.out.println("");**/ + + Method main = target.getMethod("main", argTypes); + main.invoke(null, arguments); + + // ensure we close out the request (happy request) + requestService.endRequest(null); + } + catch (Exception e) + { + // Failure occurred in the request so we destroy it + requestService.endRequest(e); + + if (kernelImpl != null) + { + kernelImpl.destroy(); + kernelImpl = null; + } + + // Exceptions from the script are reported as a 'cause' + Throwable cause = e.getCause(); + System.err.println("Exception: " + cause.getMessage()); + cause.printStackTrace(); + return 1; + } + + } + + // Destroy the service kernel + if (kernelImpl != null) + { + kernelImpl.destroy(); + kernelImpl = null; + } + + // Everything completed OK + return 0; } /** From 61f0a30bd7d86d75c05ce1c96994b06fa245c8e0 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 9 Jan 2013 12:20:14 -0500 Subject: [PATCH 03/15] Factor runManyCommands() out to a new class, so that 'read' can be an ordinary command --- .../dspace/app/launcher/CommandRunner.java | 91 +++++++++++++++ .../dspace/app/launcher/ScriptLauncher.java | 106 ++---------------- dspace/config/launcher.xml | 8 ++ 3 files changed, 108 insertions(+), 97 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java new file mode 100644 index 0000000000..f9dab25c3d --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java @@ -0,0 +1,91 @@ +package org.dspace.app.launcher; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StreamTokenizer; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author mwood + */ +public class CommandRunner +{ + public static void main(String[] args) + throws FileNotFoundException, IOException + { + if (args.length > 0) + { + runManyCommands(args[0]); + } + else + { + runManyCommands("-"); + } + // There is no sensible way to use the status returned by runManyCommands(). + // If called from the command line then we would want to return it + // through System.exit(). But if called (normally) from ScriptLauncher, + // there is no way to return it and we don't want to interrupt + // ScriptLauncher. + // + // "'tis a puzzlement." -- the King of Siam + } + + /** + * Read a file of command lines and execute each in turn. + * + * @param doc details of recognized commands. + * @param script the file of command lines to be executed. + * @return + * @throws FileNotFoundException + * @throws IOException + */ + static int runManyCommands(String script) + throws FileNotFoundException, IOException + { + Reader input; + if ("-".equals(script)) + { + input = new InputStreamReader(System.in); + } + else + { + input = new FileReader(script); + } + + StreamTokenizer tokenizer = new StreamTokenizer(input); + + tokenizer.eolIsSignificant(true); + tokenizer.ordinaryChar('-'); + tokenizer.wordChars('-', '-'); + tokenizer.ordinaryChars('0', '9'); + tokenizer.wordChars('0', '9'); + tokenizer.ordinaryChar('.'); + tokenizer.wordChars('.', '.'); + + int status = 0; + List tokens = new ArrayList(); + while (StreamTokenizer.TT_EOF != tokenizer.nextToken()) + { + if (StreamTokenizer.TT_EOL == tokenizer.ttype) + { + status = ScriptLauncher.runOneCommand(tokens.toArray(new String[tokens.size()])); + if (status > 0) + { + break; + } + tokens.clear(); + } + else + { + tokens.add(tokenizer.sval); + } + } + + return status; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index 3eed844101..918dbe8823 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -8,14 +8,9 @@ package org.dspace.app.launcher; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StreamTokenizer; import java.lang.reflect.Method; import java.util.List; -import java.util.ArrayList; import org.dspace.core.ConfigurationManager; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; @@ -35,6 +30,9 @@ public class ScriptLauncher /** The service manager kernel */ private static transient DSpaceKernelImpl kernelImpl; + /** Definitions of all commands. */ + private static final Document commandConfigs = getConfig(); + /** * Execute the DSpace script launcher * @@ -74,25 +72,9 @@ public class ScriptLauncher throw new IllegalStateException(message, e); } - // Parse the configuration file. - Document doc = getConfig(); - - // Look up command(s) in the configuration, and execute. + // Look up command in the configuration, and execute. int status; - if ("read".equalsIgnoreCase(args[0])) - { - if (args.length < 2) - { - System.err.println("'read' must have a single filename argument"); - System.exit(1); - } - - status = runManyCommands(doc, args[1]); - } - else - { - status = runOneCommand(doc, args); - } + status = runOneCommand(args); // Destroy the service kernel if it is still alive if (kernelImpl != null) @@ -104,70 +86,15 @@ public class ScriptLauncher System.exit(status); } - /** - * Read a file of command lines and execute each in turn. - * - * @param doc details of recognized commands. - * @param script the file of command lines to be executed. - * @return - * @throws FileNotFoundException - * @throws IOException - */ - static private int runManyCommands(Document doc, String script) - throws FileNotFoundException, IOException - { - Reader input; - if ("-".equals(script)) - { - input = new InputStreamReader(System.in); - } - else - { - input = new FileReader(script); - } - - StreamTokenizer tokenizer = new StreamTokenizer(input); - - tokenizer.eolIsSignificant(true); - tokenizer.ordinaryChar('-'); - tokenizer.wordChars('-', '-'); - tokenizer.ordinaryChars('0', '9'); - tokenizer.wordChars('0', '9'); - tokenizer.ordinaryChar('.'); - tokenizer.wordChars('.', '.'); - - int status = 0; - List tokens = new ArrayList(); - while (StreamTokenizer.TT_EOF != tokenizer.nextToken()) - { - if (StreamTokenizer.TT_EOL == tokenizer.ttype) - { - status = runOneCommand(doc, - tokens.toArray(new String[tokens.size()])); - if (status > 0) - { - break; - } - tokens.clear(); - } - else - { - tokens.add(tokenizer.sval); - } - } - - return status; - } - /** * Recognize and execute a single command. * @param doc - * @param args + * @param args */ - static private int runOneCommand(Document doc, String[] args) + static int runOneCommand(String[] args) { String request = args[0]; - Element root = doc.getRootElement(); + Element root = commandConfigs.getRootElement(); List commands = root.getChildren("command"); Element command = null; for (Element candidate : commands) @@ -305,26 +232,12 @@ public class ScriptLauncher // Failure occurred in the request so we destroy it requestService.endRequest(e); - if (kernelImpl != null) - { - kernelImpl.destroy(); - kernelImpl = null; - } - // Exceptions from the script are reported as a 'cause' Throwable cause = e.getCause(); System.err.println("Exception: " + cause.getMessage()); cause.printStackTrace(); return 1; } - - } - - // Destroy the service kernel - if (kernelImpl != null) - { - kernelImpl.destroy(); - kernelImpl = null; } // Everything completed OK @@ -362,8 +275,7 @@ public class ScriptLauncher */ private static void display() { - Document doc = getConfig(); - List commands = doc.getRootElement().getChildren("command"); + List commands = commandConfigs.getRootElement().getChildren("command"); System.out.println("Usage: dspace [command-name] {parameters}"); for (Element command : commands) { diff --git a/dspace/config/launcher.xml b/dspace/config/launcher.xml index 32e5ba767b..464559b153 100644 --- a/dspace/config/launcher.xml +++ b/dspace/config/launcher.xml @@ -215,6 +215,14 @@ + + run + Execute a stream of 'dspace' commands from a file or pipe + + org.dspace.app.launcher.CommandRunner + + + stat-general Compile the general statistics From 113f287e144cd0ad24d2ef5463aa67c3e64f67c0 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 9 Jan 2013 13:26:26 -0500 Subject: [PATCH 04/15] Give feedback when an EPerson is created or destroyed --- dspace-api/src/main/java/org/dspace/eperson/EPerson.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index 44db019d12..c656974dd4 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -1289,6 +1289,7 @@ public class EPerson extends DSpaceObject try { eperson.update(); context.commit(); + System.out.printf("Created EPerson %d\n", eperson.getID()); } catch (SQLException ex) { context.abort(); System.err.println(ex.getMessage()); @@ -1341,6 +1342,7 @@ public class EPerson extends DSpaceObject try { eperson.delete(); context.commit(); + System.out.printf("Deleted EPerson %d\n", eperson.getID()); } catch (SQLException ex) { System.err.println(ex.getMessage()); System.exit(1); From 5ed660a5f31b70aed3250c5cbea7c2ecad245601 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 9 Jan 2013 14:07:15 -0500 Subject: [PATCH 05/15] Factor that looong 'if' into one function per operation (add etc.) --- .../main/java/org/dspace/eperson/EPerson.java | 356 ++++++++++-------- 1 file changed, 192 insertions(+), 164 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index c656974dd4..9189a08dfb 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -1171,44 +1171,49 @@ public class EPerson extends DSpaceObject } + private static final Option VERB_ADD = new Option("a", "add", false, "create a new EPerson"); + private static final Option VERB_DELETE = new Option("d", "delete", false, "delete an existing EPerson"); + private static final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); + private static final Option VERB_MODIFY = new Option("M", "modify", false, "modify an EPerson"); + + private static final OptionGroup verbs = new OptionGroup(); + static { + verbs.addOption(VERB_ADD); + verbs.addOption(VERB_DELETE); + verbs.addOption(VERB_LIST); + verbs.addOption(VERB_MODIFY); + } + + private static final Option OPT_GIVENNAME = new Option("g", "givenname", true, "the person's actual first or personal name"); + private static final Option OPT_SURNAME = new Option("s", "surname", true, "the person's actual last or family name"); + private static final Option OPT_TELEPHONE = new Option("t", "telephone", true, "telephone number, empty for none"); + private static final Option OPT_LANGUAGE = new Option("l", "language", true, "the person's preferred language"); + private static final Option OPT_REQUIRE_CERTIFICATE = new Option("c", "requireCertificate", false, "if specified, an X.509 certificate will be required for login"); + private static final Option OPT_NO_CERTIFICATE = new Option("C", "noCertificate", false, "if specified, no X.509 certificate will be demanded for login"); + + private static final Option OPT_EMAIL = new Option("m", "email", true, "the user's email address, empty for none"); + private static final Option OPT_NETID = new Option("n", "netid", true, "network ID associated with the person, empty for none"); + + private static final Options globalOptions = new Options(); + static { + globalOptions.addOptionGroup(verbs); + globalOptions.addOption("h", "help", false, "explain options"); + } + + private static final OptionGroup identity = new OptionGroup(); + static { + identity.setRequired(true); + identity.addOption(OPT_EMAIL); + identity.addOption(OPT_NETID); + } + /** * Tool for manipulating user accounts. */ public static void main(String argv[]) { - final Option VERB_ADD = new Option("a", "add", false, "create a new EPerson"); - final Option VERB_DELETE = new Option("d", "delete", false, "delete an existing EPerson"); - final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); - final Option VERB_MODIFY = new Option("M", "modify", false, "modify an EPerson"); - - final Option OPT_GIVENNAME = new Option("g", "givenname", true, "the person's actual first or personal name"); - final Option OPT_SURNAME = new Option("s", "surname", true, "the person's actual last or family name"); - final Option OPT_TELEPHONE = new Option("t", "telephone", true, "telephone number, empty for none"); - final Option OPT_LANGUAGE = new Option("l", "language", true, "the person's preferred language"); - final Option OPT_REQUIRE_CERTIFICATE = new Option("c", "requireCertificate", false, "if specified, an X.509 certificate will be required for login"); - final Option OPT_NO_CERTIFICATE = new Option("C", "noCertificate", false, "if specified, no X.509 certificate will be demanded for login"); - final CommandLineParser parser = new PosixParser(); CommandLine command = null; - Option option; - - final OptionGroup verbs = new OptionGroup(); - verbs.addOption(VERB_ADD); - verbs.addOption(VERB_DELETE); - verbs.addOption(VERB_LIST); - verbs.addOption(VERB_MODIFY); - - final Options globalOptions = new Options(); - globalOptions.addOptionGroup(verbs); - globalOptions.addOption("h", "help", false, "explain options"); - - final OptionGroup identity; - identity = new OptionGroup(); - identity.setRequired(true); - option = new Option("m", "email", true, "the user's email address, empty for none"); - identity.addOption(option); - option = new Option("n", "netid", true, "network ID associated with the person, empty for none"); - identity.addOption(option); try { command = parser.parse(globalOptions, argv); @@ -1236,149 +1241,20 @@ public class EPerson extends DSpaceObject if (command.hasOption('a')) { - // Create a user. - Options options = new Options(); - - options.addOption(VERB_ADD); - - options.addOptionGroup(identity); - - option = new Option("p", "password", true, "password to match the EPerson name"); - option.setRequired(true); - options.addOption(option); - - options.addOption(OPT_GIVENNAME); - options.addOption(OPT_SURNAME); - options.addOption(OPT_TELEPHONE); - options.addOption(OPT_LANGUAGE); - options.addOption(OPT_REQUIRE_CERTIFICATE); - options.addOption(OPT_NO_CERTIFICATE); - - options.addOption("h", "help", false, "explain -add options"); - - try { - command = parser.parse(options, argv); - } catch (ParseException e) { - System.err.println(e.getMessage()); - System.exit(1); - } - - if (command.hasOption('h')) - { - new HelpFormatter().printHelp("user --add [options]", globalOptions); - System.exit(0); - } - - EPerson eperson = null; - try { - eperson = create(context); - } catch (SQLException ex) { - context.abort(); - System.err.println(ex.getMessage()); - System.exit(1); - } catch (AuthorizeException ex) { /* XXX SNH */ } - eperson.setCanLogIn(true); - eperson.setEmail(command.getOptionValue('m')); - eperson.setFirstName(command.getOptionValue('g')); - eperson.setLastName(command.getOptionValue('s')); - eperson.setLanguage(command.getOptionValue('l')); - eperson.setNetid(command.getOptionValue('n')); - eperson.setPassword(command.getOptionValue('p')); - eperson.setRequireCertificate(command.hasOption('c')); - eperson.setSelfRegistered(false); - try { - eperson.update(); - context.commit(); - System.out.printf("Created EPerson %d\n", eperson.getID()); - } catch (SQLException ex) { - context.abort(); - System.err.println(ex.getMessage()); - System.exit(1); - } catch (AuthorizeException ex) { /* XXX SNH */ } + cmd_add(context, parser, argv); } else if (command.hasOption('d')) { - // Delete a user. - Options options = new Options(); - - options.addOption(VERB_DELETE); - - options.addOptionGroup(identity); - - try { - command = parser.parse(options, argv); - } catch (ParseException e) { - System.err.println(e.getMessage()); - System.exit(1); - } - - if (command.hasOption('h')) - { - new HelpFormatter().printHelp("user --delete [options]", globalOptions); - System.exit(0); - } - - EPerson eperson = null; - try { - if (command.hasOption('n')) - { - eperson = findByNetid(context, command.getOptionValue('n')); - } - else - { - eperson = findByEmail(context, command.getOptionValue('m')); - } - } catch (SQLException e) { - System.err.append(e.getMessage()); - System.exit(1); - } catch (AuthorizeException e) { /* XXX SNH */ } - - if (null == eperson) - { - System.err.println("No such EPerson"); - } - else - { - try { - eperson.delete(); - context.commit(); - System.out.printf("Deleted EPerson %d\n", eperson.getID()); - } catch (SQLException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } catch (AuthorizeException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } catch (EPersonDeletionException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } - } + cmd_delete(context, parser, argv); } else if (command.hasOption('m')) { // TODO Modify a user. + // cmd_modify(context, parser, argv); } else if (command.hasOption('L')) { - // List users - // XXX ideas: - // specific user/netid - // wild or regex match user/netid - // select details (pseudo-format string) - try { - for (EPerson person : findAll(context, EMAIL)) - { - System.out.printf("%d\t%s/%s\t%s, %s\n", - person.getID(), - person.getEmail(), - person.getNetid(), - person.getLastName(), person.getFirstName()); // TODO more user details - } - } catch (SQLException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } + cmd_list(context, parser, argv); } else { @@ -1387,4 +1263,156 @@ public class EPerson extends DSpaceObject System.exit(1); } } + + private static void cmd_add(Context context, CommandLineParser parser, String[] argv) + { + // Create a user. + Options options = new Options(); + + options.addOption(VERB_ADD); + + options.addOptionGroup(identity); + + Option option = new Option("p", "password", true, "password to match the EPerson name"); + option.setRequired(true); + options.addOption(option); + + options.addOption(OPT_GIVENNAME); + options.addOption(OPT_SURNAME); + options.addOption(OPT_TELEPHONE); + options.addOption(OPT_LANGUAGE); + options.addOption(OPT_REQUIRE_CERTIFICATE); + options.addOption(OPT_NO_CERTIFICATE); + + options.addOption("h", "help", false, "explain -add options"); + + CommandLine command = null; + try { + command = parser.parse(options, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user --add [options]", globalOptions); + System.exit(0); + } + + EPerson eperson = null; + try { + eperson = create(context); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { /* XXX SNH */ } + eperson.setCanLogIn(true); + eperson.setEmail(command.getOptionValue('m')); + eperson.setFirstName(command.getOptionValue('g')); + eperson.setLastName(command.getOptionValue('s')); + eperson.setLanguage(command.getOptionValue('l')); + eperson.setNetid(command.getOptionValue('n')); + eperson.setPassword(command.getOptionValue('p')); + eperson.setRequireCertificate(command.hasOption('c')); + eperson.setSelfRegistered(false); + try { + eperson.update(); + context.commit(); + System.out.printf("Created EPerson %d\n", eperson.getID()); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { /* XXX SNH */ } + } + + private static void cmd_delete(Context context, CommandLineParser parser, String[] argv) + { + // Delete a user. + Options options = new Options(); + + options.addOption(VERB_DELETE); + + options.addOptionGroup(identity); + + CommandLine command = null; + try { + command = parser.parse(options, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user --delete [options]", globalOptions); + System.exit(0); + } + + EPerson eperson = null; + try { + if (command.hasOption('n')) + { + eperson = findByNetid(context, command.getOptionValue('n')); + } + else + { + eperson = findByEmail(context, command.getOptionValue('m')); + } + } catch (SQLException e) { + System.err.append(e.getMessage()); + System.exit(1); + } catch (AuthorizeException e) { /* XXX SNH */ } + + if (null == eperson) + { + System.err.println("No such EPerson"); + } + else + { + try { + eperson.delete(); + context.commit(); + System.out.printf("Deleted EPerson %d\n", eperson.getID()); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } catch (EPersonDeletionException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } + } + } + + private static void cmd_modify(Context context, CommandLineParser parser, String[] argv) + { + // TODO modify a user + } + + private static void cmd_list(Context context, CommandLineParser parser, String[] argv) + { + // List users + // XXX ideas: + // specific user/netid + // wild or regex match user/netid + // select details (pseudo-format string) + try { + for (EPerson person : findAll(context, EMAIL)) + { + System.out.printf("%d\t%s/%s\t%s, %s\n", + person.getID(), + person.getEmail(), + person.getNetid(), + person.getLastName(), person.getFirstName()); // TODO more user details + } + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + System.exit(1); + } + } } From 6f43cfde0f2456e64711815e0651d3121320ed85 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 10 Jan 2013 13:58:06 -0500 Subject: [PATCH 06/15] Normalize some naming, implement --modify verb. --- .../main/java/org/dspace/eperson/EPerson.java | 167 +++++++++++++----- 1 file changed, 127 insertions(+), 40 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index 9189a08dfb..3b85933f37 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -1160,6 +1160,7 @@ public class EPerson extends DSpaceObject } } + @Override public String getName() { return getEmail(); @@ -1176,37 +1177,47 @@ public class EPerson extends DSpaceObject private static final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); private static final Option VERB_MODIFY = new Option("M", "modify", false, "modify an EPerson"); - private static final OptionGroup verbs = new OptionGroup(); + private static final OptionGroup VERBS = new OptionGroup(); static { - verbs.addOption(VERB_ADD); - verbs.addOption(VERB_DELETE); - verbs.addOption(VERB_LIST); - verbs.addOption(VERB_MODIFY); + VERBS.addOption(VERB_ADD); + VERBS.addOption(VERB_DELETE); + VERBS.addOption(VERB_LIST); + VERBS.addOption(VERB_MODIFY); } private static final Option OPT_GIVENNAME = new Option("g", "givenname", true, "the person's actual first or personal name"); private static final Option OPT_SURNAME = new Option("s", "surname", true, "the person's actual last or family name"); - private static final Option OPT_TELEPHONE = new Option("t", "telephone", true, "telephone number, empty for none"); + private static final Option OPT_PHONE = new Option("t", "telephone", true, "telephone number, empty for none"); private static final Option OPT_LANGUAGE = new Option("l", "language", true, "the person's preferred language"); - private static final Option OPT_REQUIRE_CERTIFICATE = new Option("c", "requireCertificate", false, "if specified, an X.509 certificate will be required for login"); - private static final Option OPT_NO_CERTIFICATE = new Option("C", "noCertificate", false, "if specified, no X.509 certificate will be demanded for login"); + private static final Option OPT_REQUIRE_CERTIFICATE = new Option("c", "requireCertificate", true, "if 'true', an X.509 certificate will be required for login"); + private static final Option OPT_CAN_LOGIN = new Option("C", "canLogIn", true, "'true' if the user can log in"); private static final Option OPT_EMAIL = new Option("m", "email", true, "the user's email address, empty for none"); private static final Option OPT_NETID = new Option("n", "netid", true, "network ID associated with the person, empty for none"); private static final Options globalOptions = new Options(); static { - globalOptions.addOptionGroup(verbs); + globalOptions.addOptionGroup(VERBS); globalOptions.addOption("h", "help", false, "explain options"); } - private static final OptionGroup identity = new OptionGroup(); + private static final OptionGroup identityOptions = new OptionGroup(); static { - identity.setRequired(true); - identity.addOption(OPT_EMAIL); - identity.addOption(OPT_NETID); + identityOptions.setRequired(true); + identityOptions.addOption(OPT_EMAIL); + identityOptions.addOption(OPT_NETID); } + private static final OptionGroup attributeOptions = new OptionGroup(); + static { + + attributeOptions.addOption(OPT_GIVENNAME); + attributeOptions.addOption(OPT_SURNAME); + attributeOptions.addOption(OPT_PHONE); + attributeOptions.addOption(OPT_LANGUAGE); + attributeOptions.addOption(OPT_REQUIRE_CERTIFICATE); + } + /** * Tool for manipulating user accounts. */ @@ -1241,20 +1252,19 @@ public class EPerson extends DSpaceObject if (command.hasOption('a')) { - cmd_add(context, parser, argv); + cmdAdd(context, parser, argv); } else if (command.hasOption('d')) { - cmd_delete(context, parser, argv); + cmdDelete(context, parser, argv); } else if (command.hasOption('m')) { - // TODO Modify a user. - // cmd_modify(context, parser, argv); + cmdModify(context, parser, argv); } else if (command.hasOption('L')) { - cmd_list(context, parser, argv); + cmdList(context, parser, argv); } else { @@ -1264,26 +1274,21 @@ public class EPerson extends DSpaceObject } } - private static void cmd_add(Context context, CommandLineParser parser, String[] argv) + private static void cmdAdd(Context context, CommandLineParser parser, String[] argv) { // Create a user. Options options = new Options(); options.addOption(VERB_ADD); - options.addOptionGroup(identity); + options.addOptionGroup(identityOptions); + + options.addOptionGroup(attributeOptions); Option option = new Option("p", "password", true, "password to match the EPerson name"); option.setRequired(true); options.addOption(option); - options.addOption(OPT_GIVENNAME); - options.addOption(OPT_SURNAME); - options.addOption(OPT_TELEPHONE); - options.addOption(OPT_LANGUAGE); - options.addOption(OPT_REQUIRE_CERTIFICATE); - options.addOption(OPT_NO_CERTIFICATE); - options.addOption("h", "help", false, "explain -add options"); CommandLine command = null; @@ -1296,7 +1301,7 @@ public class EPerson extends DSpaceObject if (command.hasOption('h')) { - new HelpFormatter().printHelp("user --add [options]", globalOptions); + new HelpFormatter().printHelp("user --add [options]", options); System.exit(0); } @@ -1309,13 +1314,18 @@ public class EPerson extends DSpaceObject System.exit(1); } catch (AuthorizeException ex) { /* XXX SNH */ } eperson.setCanLogIn(true); - eperson.setEmail(command.getOptionValue('m')); - eperson.setFirstName(command.getOptionValue('g')); - eperson.setLastName(command.getOptionValue('s')); - eperson.setLanguage(command.getOptionValue('l')); - eperson.setNetid(command.getOptionValue('n')); + eperson.setEmail(command.getOptionValue(OPT_EMAIL.getOpt())); + eperson.setFirstName(command.getOptionValue(OPT_GIVENNAME.getOpt())); + eperson.setLastName(command.getOptionValue(OPT_SURNAME.getOpt())); + eperson.setLanguage(command.getOptionValue(OPT_LANGUAGE.getOpt())); + eperson.setMetadata("phone", command.getOptionValue(OPT_PHONE.getOpt())); + eperson.setNetid(command.getOptionValue(OPT_NETID.getOpt())); eperson.setPassword(command.getOptionValue('p')); - eperson.setRequireCertificate(command.hasOption('c')); + if (command.hasOption(OPT_REQUIRE_CERTIFICATE.getOpt())) + { + eperson.setRequireCertificate(Boolean.valueOf(command.getOptionValue( + OPT_REQUIRE_CERTIFICATE.getOpt()))); + } eperson.setSelfRegistered(false); try { eperson.update(); @@ -1328,14 +1338,14 @@ public class EPerson extends DSpaceObject } catch (AuthorizeException ex) { /* XXX SNH */ } } - private static void cmd_delete(Context context, CommandLineParser parser, String[] argv) + private static void cmdDelete(Context context, CommandLineParser parser, String[] argv) { // Delete a user. Options options = new Options(); options.addOption(VERB_DELETE); - options.addOptionGroup(identity); + options.addOptionGroup(identityOptions); CommandLine command = null; try { @@ -1347,7 +1357,7 @@ public class EPerson extends DSpaceObject if (command.hasOption('h')) { - new HelpFormatter().printHelp("user --delete [options]", globalOptions); + new HelpFormatter().printHelp("user --delete [options]", options); System.exit(0); } @@ -1389,12 +1399,89 @@ public class EPerson extends DSpaceObject } } - private static void cmd_modify(Context context, CommandLineParser parser, String[] argv) + private static void cmdModify(Context context, CommandLineParser parser, String[] argv) { - // TODO modify a user + Options options = new Options(); + + options.addOption(VERB_MODIFY); + + options.addOptionGroup(identityOptions); + + options.addOption(OPT_CAN_LOGIN); + + CommandLine command = null; + try { + command = parser.parse(options, argv); + } catch (ParseException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user --modify [options]", options); + System.exit(0); + } + + EPerson eperson = null; + try { + if (command.hasOption('n')) + { + eperson = findByNetid(context, command.getOptionValue('n')); + } + else + { + eperson = findByEmail(context, command.getOptionValue('m')); + } + } catch (SQLException e) { + System.err.append(e.getMessage()); + System.exit(1); + } catch (AuthorizeException e) { /* XXX SNH */ } + + if (null == eperson) + { + System.err.println("No such EPerson"); + } + else + { + if (command.hasOption(OPT_GIVENNAME.getOpt())) + { + eperson.setFirstName(command.getOptionValue(OPT_GIVENNAME.getOpt())); + } + if (command.hasOption(OPT_SURNAME.getOpt())) + { + eperson.setLastName(command.getOptionValue(OPT_SURNAME.getOpt())); + } + if (command.hasOption(OPT_PHONE.getOpt())) + { + eperson.setMetadata("phone", command.getOptionValue(OPT_PHONE.getOpt())); + } + if (command.hasOption(OPT_LANGUAGE.getOpt())) + { + eperson.setLanguage(command.getOptionValue(OPT_LANGUAGE.getOpt())); + } + if (command.hasOption(OPT_REQUIRE_CERTIFICATE.getOpt())) + { + eperson.setRequireCertificate(Boolean.valueOf(command.getOptionValue( + OPT_REQUIRE_CERTIFICATE.getOpt()))); + } + if (command.hasOption(OPT_CAN_LOGIN.getOpt())) + { + eperson.setCanLogIn(Boolean.valueOf(command.getOptionValue(OPT_CAN_LOGIN.getOpt()))); + } + try { + eperson.update(); + context.commit(); + System.out.printf("Modified EPerson %d\n", eperson.getID()); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + System.exit(1); + } catch (AuthorizeException ex) { /* XXX SNH */ } + } } - private static void cmd_list(Context context, CommandLineParser parser, String[] argv) + private static void cmdList(Context context, CommandLineParser parser, String[] argv) { // List users // XXX ideas: From 318d696943202c7f1dc61bad96b6adad753a2707 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 11 Jan 2013 10:10:53 -0500 Subject: [PATCH 07/15] Used the wrong reference to test command and got an NPE --- .../src/main/java/org/dspace/app/launcher/ScriptLauncher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index 918dbe8823..202c877346 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -99,7 +99,7 @@ public class ScriptLauncher Element command = null; for (Element candidate : commands) { - if (request.equalsIgnoreCase(command.getChild("name").getValue())) + if (request.equalsIgnoreCase(candidate.getChild("name").getValue())) { command = candidate; break; From 853d81d600eca614150bb14e9649402dbf17ca26 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 11 Jan 2013 10:15:32 -0500 Subject: [PATCH 08/15] Make command reparsing work properly, and general cleanup --- .../main/java/org/dspace/eperson/EPerson.java | 240 ++++++++++++------ 1 file changed, 164 insertions(+), 76 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index 3b85933f37..d457a63ba7 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -10,6 +10,7 @@ package org.dspace.eperson; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.Option; @@ -1172,6 +1173,10 @@ public class EPerson extends DSpaceObject } + /* + * Commandline tool for manipulating EPersons. + */ + private static final Option VERB_ADD = new Option("a", "add", false, "create a new EPerson"); private static final Option VERB_DELETE = new Option("d", "delete", false, "delete an existing EPerson"); private static final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); @@ -1195,6 +1200,9 @@ public class EPerson extends DSpaceObject private static final Option OPT_EMAIL = new Option("m", "email", true, "the user's email address, empty for none"); private static final Option OPT_NETID = new Option("n", "netid", true, "network ID associated with the person, empty for none"); + private static final Option OPT_NEW_EMAIL = new Option("i", "newEmail", true, "new email address"); + private static final Option OPT_NEW_NETID = new Option("I", "newNetid", true, "new network ID"); + private static final Options globalOptions = new Options(); static { globalOptions.addOptionGroup(VERBS); @@ -1203,14 +1211,12 @@ public class EPerson extends DSpaceObject private static final OptionGroup identityOptions = new OptionGroup(); static { - identityOptions.setRequired(true); identityOptions.addOption(OPT_EMAIL); identityOptions.addOption(OPT_NETID); } private static final OptionGroup attributeOptions = new OptionGroup(); static { - attributeOptions.addOption(OPT_GIVENNAME); attributeOptions.addOption(OPT_SURNAME); attributeOptions.addOption(OPT_PHONE); @@ -1223,22 +1229,16 @@ public class EPerson extends DSpaceObject */ public static void main(String argv[]) { - final CommandLineParser parser = new PosixParser(); + final PosixParser parser = new PosixParser(); CommandLine command = null; try { - command = parser.parse(globalOptions, argv); + command = parser.parse(globalOptions, argv, true); } catch (ParseException e) { System.err.println(e.getMessage()); System.exit(1); } - if (command.hasOption('h')) - { - new HelpFormatter().printHelp("user [options]", globalOptions); - System.exit(0); - } - Context context = null; try { context = new Context(); @@ -1250,33 +1250,47 @@ public class EPerson extends DSpaceObject // Disable authorization since this only runs from the local commandline. context.turnOffAuthorisationSystem(); - if (command.hasOption('a')) + int status = 0; + if (command.hasOption(VERB_ADD.getOpt())) { - cmdAdd(context, parser, argv); + status = cmdAdd(context, parser, argv); } - else if (command.hasOption('d')) + else if (command.hasOption(VERB_DELETE.getOpt())) { - cmdDelete(context, parser, argv); + status = cmdDelete(context, parser, argv); } - else if (command.hasOption('m')) + else if (command.hasOption(VERB_MODIFY.getOpt())) { - cmdModify(context, parser, argv); + status = cmdModify(context, parser, argv); } - else if (command.hasOption('L')) + else if (command.hasOption(VERB_LIST.getOpt())) { - cmdList(context, parser, argv); + status = cmdList(context, parser, argv); + } + else if (command.hasOption('h')) + { + new HelpFormatter().printHelp("user [options]", globalOptions); } else { System.err.println("Unknown operation."); + new HelpFormatter().printHelp("user [options]", globalOptions); context.abort(); - System.exit(1); + status = 1; } + + try { + context.complete(); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + } + + System.exit(status); } - private static void cmdAdd(Context context, CommandLineParser parser, String[] argv) + /** Command to create an EPerson. */ + private static int cmdAdd(Context context, CommandLineParser parser, String[] argv) { - // Create a user. Options options = new Options(); options.addOption(VERB_ADD); @@ -1286,38 +1300,55 @@ public class EPerson extends DSpaceObject options.addOptionGroup(attributeOptions); Option option = new Option("p", "password", true, "password to match the EPerson name"); - option.setRequired(true); options.addOption(option); - options.addOption("h", "help", false, "explain -add options"); + options.addOption("h", "help", false, "explain --add options"); - CommandLine command = null; + // Rescan the command for more details. + CommandLine command; try { command = parser.parse(options, argv); } catch (ParseException e) { System.err.println(e.getMessage()); - System.exit(1); + return 1; } if (command.hasOption('h')) { new HelpFormatter().printHelp("user --add [options]", options); - System.exit(0); + return 0; } + // Check that we got sufficient credentials to define a user. + if ((!command.hasOption(OPT_EMAIL.getOpt())) && (!command.hasOption(OPT_NETID.getOpt()))) + { + System.err.println("You must provide an email address or a netid to identify the new user."); + return 1; + } + + if (!command.hasOption('p')) + { + System.err.println("You must provide a password for the new user."); + return 1; + } + + // Create! EPerson eperson = null; try { eperson = create(context); } catch (SQLException ex) { context.abort(); System.err.println(ex.getMessage()); - System.exit(1); + return 1; } catch (AuthorizeException ex) { /* XXX SNH */ } eperson.setCanLogIn(true); + eperson.setSelfRegistered(false); + eperson.setEmail(command.getOptionValue(OPT_EMAIL.getOpt())); eperson.setFirstName(command.getOptionValue(OPT_GIVENNAME.getOpt())); eperson.setLastName(command.getOptionValue(OPT_SURNAME.getOpt())); - eperson.setLanguage(command.getOptionValue(OPT_LANGUAGE.getOpt())); + eperson.setLanguage(command.getOptionValue(OPT_LANGUAGE.getOpt(), + Locale.getDefault().getLanguage())); eperson.setMetadata("phone", command.getOptionValue(OPT_PHONE.getOpt())); eperson.setNetid(command.getOptionValue(OPT_NETID.getOpt())); eperson.setPassword(command.getOptionValue('p')); @@ -1326,7 +1357,11 @@ public class EPerson extends DSpaceObject eperson.setRequireCertificate(Boolean.valueOf(command.getOptionValue( OPT_REQUIRE_CERTIFICATE.getOpt()))); } - eperson.setSelfRegistered(false); + else + { + eperson.setRequireCertificate(false); + } + try { eperson.update(); context.commit(); @@ -1334,72 +1369,84 @@ public class EPerson extends DSpaceObject } catch (SQLException ex) { context.abort(); System.err.println(ex.getMessage()); - System.exit(1); + return 1; } catch (AuthorizeException ex) { /* XXX SNH */ } + + return 0; } - private static void cmdDelete(Context context, CommandLineParser parser, String[] argv) + /** Command to delete an EPerson. */ + private static int cmdDelete(Context context, CommandLineParser parser, String[] argv) { - // Delete a user. Options options = new Options(); options.addOption(VERB_DELETE); options.addOptionGroup(identityOptions); - CommandLine command = null; + options.addOption("h", "help", false, "explain --delete options"); + + CommandLine command; try { command = parser.parse(options, argv); } catch (ParseException e) { System.err.println(e.getMessage()); - System.exit(1); + return 1; } if (command.hasOption('h')) { new HelpFormatter().printHelp("user --delete [options]", options); - System.exit(0); + return 0; } + // Delete! EPerson eperson = null; try { - if (command.hasOption('n')) + if (command.hasOption(OPT_NETID.getOpt())) { - eperson = findByNetid(context, command.getOptionValue('n')); + eperson = findByNetid(context, command.getOptionValue(OPT_NETID.getOpt())); + } + else if (command.hasOption(OPT_EMAIL.getOpt())) + { + eperson = findByEmail(context, command.getOptionValue(OPT_EMAIL.getOpt())); } else { - eperson = findByEmail(context, command.getOptionValue('m')); + System.err.println("You must specify the user's email address or netid."); + return 1; } } catch (SQLException e) { System.err.append(e.getMessage()); - System.exit(1); + return 1; } catch (AuthorizeException e) { /* XXX SNH */ } if (null == eperson) { System.err.println("No such EPerson"); + return 1; } - else - { - try { - eperson.delete(); - context.commit(); - System.out.printf("Deleted EPerson %d\n", eperson.getID()); - } catch (SQLException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } catch (AuthorizeException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } catch (EPersonDeletionException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } + + try { + eperson.delete(); + context.commit(); + System.out.printf("Deleted EPerson %d\n", eperson.getID()); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + return 1; + } catch (AuthorizeException ex) { + System.err.println(ex.getMessage()); + return 1; + } catch (EPersonDeletionException ex) { + System.err.println(ex.getMessage()); + return 1; } + + return 0; } - private static void cmdModify(Context context, CommandLineParser parser, String[] argv) + /** Command to modify an EPerson. */ + private static int cmdModify(Context context, CommandLineParser parser, String[] argv) { Options options = new Options(); @@ -1407,83 +1454,122 @@ public class EPerson extends DSpaceObject options.addOptionGroup(identityOptions); - options.addOption(OPT_CAN_LOGIN); + options.addOptionGroup(attributeOptions); - CommandLine command = null; + options.addOption(OPT_CAN_LOGIN); + options.addOption(OPT_NEW_EMAIL); + options.addOption(OPT_NEW_NETID); + + options.addOption("h", "help", false, "explain --modify options"); + + CommandLine command; try { command = parser.parse(options, argv); } catch (ParseException e) { System.err.println(e.getMessage()); - System.exit(1); + return 1; } if (command.hasOption('h')) { new HelpFormatter().printHelp("user --modify [options]", options); - System.exit(0); + return 0; } + // Modify! EPerson eperson = null; try { - if (command.hasOption('n')) + if (command.hasOption(OPT_NETID.getOpt())) { - eperson = findByNetid(context, command.getOptionValue('n')); + eperson = findByNetid(context, command.getOptionValue(OPT_NETID.getOpt())); + } + else if (command.hasOption(OPT_EMAIL.getOpt())) + { + eperson = findByEmail(context, command.getOptionValue(OPT_EMAIL.getOpt())); } else { - eperson = findByEmail(context, command.getOptionValue('m')); + System.err.println("No EPerson selected"); + return 1; } } catch (SQLException e) { System.err.append(e.getMessage()); - System.exit(1); + return 1; } catch (AuthorizeException e) { /* XXX SNH */ } + boolean modified = false; if (null == eperson) { System.err.println("No such EPerson"); + return 1; } else { + if (command.hasOption(OPT_NEW_EMAIL.getOpt())) + { + eperson.setEmail(command.getOptionValue(OPT_NEW_EMAIL.getOpt())); + modified = true; + } + if (command.hasOption(OPT_NEW_NETID.getOpt())) + { + eperson.setNetid(command.getOptionValue(OPT_NEW_NETID.getOpt())); + modified = true; + } if (command.hasOption(OPT_GIVENNAME.getOpt())) { eperson.setFirstName(command.getOptionValue(OPT_GIVENNAME.getOpt())); + modified = true; } if (command.hasOption(OPT_SURNAME.getOpt())) { eperson.setLastName(command.getOptionValue(OPT_SURNAME.getOpt())); + modified = true; } if (command.hasOption(OPT_PHONE.getOpt())) { eperson.setMetadata("phone", command.getOptionValue(OPT_PHONE.getOpt())); + modified = true; } if (command.hasOption(OPT_LANGUAGE.getOpt())) { eperson.setLanguage(command.getOptionValue(OPT_LANGUAGE.getOpt())); + modified = true; } if (command.hasOption(OPT_REQUIRE_CERTIFICATE.getOpt())) { eperson.setRequireCertificate(Boolean.valueOf(command.getOptionValue( OPT_REQUIRE_CERTIFICATE.getOpt()))); + modified = true; } if (command.hasOption(OPT_CAN_LOGIN.getOpt())) { eperson.setCanLogIn(Boolean.valueOf(command.getOptionValue(OPT_CAN_LOGIN.getOpt()))); + modified = true; + } + if (modified) + { + try { + eperson.update(); + context.commit(); + System.out.printf("Modified EPerson %d\n", eperson.getID()); + } catch (SQLException ex) { + context.abort(); + System.err.println(ex.getMessage()); + return 1; + } catch (AuthorizeException ex) { /* XXX SNH */ } + } + else + { + System.out.println("No changes."); } - try { - eperson.update(); - context.commit(); - System.out.printf("Modified EPerson %d\n", eperson.getID()); - } catch (SQLException ex) { - context.abort(); - System.err.println(ex.getMessage()); - System.exit(1); - } catch (AuthorizeException ex) { /* XXX SNH */ } } + + return 0; } - private static void cmdList(Context context, CommandLineParser parser, String[] argv) + /** Command to list known EPersons. */ + private static int cmdList(Context context, CommandLineParser parser, String[] argv) { - // List users // XXX ideas: // specific user/netid // wild or regex match user/netid @@ -1499,7 +1585,9 @@ public class EPerson extends DSpaceObject } } catch (SQLException ex) { System.err.println(ex.getMessage()); - System.exit(1); + return 1; } + + return 0; } } From 7d16c10aa3d65bd52ee9a9d412f8c70aee750a1c Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 11 Jan 2013 10:49:34 -0500 Subject: [PATCH 09/15] Inadvertently named the batch-input command 'run' rather than 'read' --- dspace/config/launcher.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace/config/launcher.xml b/dspace/config/launcher.xml index 464559b153..2d2f71ccb6 100644 --- a/dspace/config/launcher.xml +++ b/dspace/config/launcher.xml @@ -216,7 +216,7 @@ - run + read Execute a stream of 'dspace' commands from a file or pipe org.dspace.app.launcher.CommandRunner From aa419fa5df1d35c578a25ffe4b315544f9347a82 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 5 Feb 2013 16:09:47 -0500 Subject: [PATCH 10/15] Context is not valid if there was no understandable verb --- .../src/main/java/org/dspace/eperson/EPerson.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index d457a63ba7..d6d8c86b06 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -1279,10 +1279,13 @@ public class EPerson extends DSpaceObject status = 1; } - try { - context.complete(); - } catch (SQLException ex) { - System.err.println(ex.getMessage()); + if (context.isValid()) + { + try { + context.complete(); + } catch (SQLException ex) { + System.err.println(ex.getMessage()); + } } System.exit(status); From 3acfcaba2bd5738fee153156a5256db6ea6a5722 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 6 Feb 2013 12:44:04 -0500 Subject: [PATCH 11/15] Email addresses need at-symbol to be a word character when tokenizing --- .../main/java/org/dspace/app/launcher/CommandRunner.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java index f9dab25c3d..93198f7afd 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java @@ -60,13 +60,19 @@ public class CommandRunner StreamTokenizer tokenizer = new StreamTokenizer(input); tokenizer.eolIsSignificant(true); + tokenizer.ordinaryChar('-'); tokenizer.wordChars('-', '-'); + tokenizer.ordinaryChars('0', '9'); tokenizer.wordChars('0', '9'); + tokenizer.ordinaryChar('.'); tokenizer.wordChars('.', '.'); + tokenizer.ordinaryChar('@'); + tokenizer.wordChars('@', '@'); + int status = 0; List tokens = new ArrayList(); while (StreamTokenizer.TT_EOF != tokenizer.nextToken()) From dfafcf657f30372f9f05347f5f199fb4fd3c6a46 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 6 Feb 2013 12:45:33 -0500 Subject: [PATCH 12/15] Don't call System.exit() in a launcher step; throw something instead. At least don't use exit() for a normal completion. That prevents streaming multiple commands. --- .../main/java/org/dspace/eperson/EPerson.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index d6d8c86b06..c3c947ea66 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -1228,24 +1228,12 @@ public class EPerson extends DSpaceObject * Tool for manipulating user accounts. */ public static void main(String argv[]) + throws ParseException, SQLException { final PosixParser parser = new PosixParser(); - CommandLine command = null; + CommandLine command = parser.parse(globalOptions, argv, true); - try { - command = parser.parse(globalOptions, argv, true); - } catch (ParseException e) { - System.err.println(e.getMessage()); - System.exit(1); - } - - Context context = null; - try { - context = new Context(); - } catch (SQLException ex) { - System.err.println(ex.getMessage()); - System.exit(1); - } + Context context = new Context(); // Disable authorization since this only runs from the local commandline. context.turnOffAuthorisationSystem(); @@ -1277,6 +1265,7 @@ public class EPerson extends DSpaceObject new HelpFormatter().printHelp("user [options]", globalOptions); context.abort(); status = 1; + throw new IllegalArgumentException(); } if (context.isValid()) @@ -1287,8 +1276,6 @@ public class EPerson extends DSpaceObject System.err.println(ex.getMessage()); } } - - System.exit(status); } /** Command to create an EPerson. */ From c00bcffb99483d3b8032d0b5c616fcf080a664c4 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 6 Feb 2013 15:06:59 -0500 Subject: [PATCH 13/15] Add missing license reference, handle blank lines --- .../org/dspace/app/launcher/CommandRunner.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java index 93198f7afd..259acf0fa0 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/CommandRunner.java @@ -1,3 +1,10 @@ +/** + * 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.launcher; import java.io.FileNotFoundException; @@ -79,12 +86,15 @@ public class CommandRunner { if (StreamTokenizer.TT_EOL == tokenizer.ttype) { - status = ScriptLauncher.runOneCommand(tokens.toArray(new String[tokens.size()])); - if (status > 0) + if (tokens.size() > 0) { - break; + status = ScriptLauncher.runOneCommand(tokens.toArray(new String[tokens.size()])); + if (status > 0) + { + break; + } + tokens.clear(); } - tokens.clear(); } else { From 7857c0184f80ae8e17df95255ea3bb389b3a5a1c Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 6 Feb 2013 15:09:10 -0500 Subject: [PATCH 14/15] Recreate OptionGroups each time they are used. It's not obvious from the Commons CLI documentation, but an OptionGroup stores command state, specifically which of its member options was given. This causes mysterious exceptions when you reuse an OptionGroup. I suspect that Option objects also contain command state, but haven't run into trouble with that yet. --- .../main/java/org/dspace/eperson/EPerson.java | 86 ++++++++++--------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index c3c947ea66..495cf55edc 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -13,11 +13,11 @@ import java.util.List; import java.util.Locale; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.codec.DecoderException; @@ -1182,14 +1182,6 @@ public class EPerson extends DSpaceObject private static final Option VERB_LIST = new Option("L", "list", false, "list EPersons"); private static final Option VERB_MODIFY = new Option("M", "modify", false, "modify an EPerson"); - private static final OptionGroup VERBS = new OptionGroup(); - static { - VERBS.addOption(VERB_ADD); - VERBS.addOption(VERB_DELETE); - VERBS.addOption(VERB_LIST); - VERBS.addOption(VERB_MODIFY); - } - private static final Option OPT_GIVENNAME = new Option("g", "givenname", true, "the person's actual first or personal name"); private static final Option OPT_SURNAME = new Option("s", "surname", true, "the person's actual last or family name"); private static final Option OPT_PHONE = new Option("t", "telephone", true, "telephone number, empty for none"); @@ -1202,27 +1194,6 @@ public class EPerson extends DSpaceObject private static final Option OPT_NEW_EMAIL = new Option("i", "newEmail", true, "new email address"); private static final Option OPT_NEW_NETID = new Option("I", "newNetid", true, "new network ID"); - - private static final Options globalOptions = new Options(); - static { - globalOptions.addOptionGroup(VERBS); - globalOptions.addOption("h", "help", false, "explain options"); - } - - private static final OptionGroup identityOptions = new OptionGroup(); - static { - identityOptions.addOption(OPT_EMAIL); - identityOptions.addOption(OPT_NETID); - } - - private static final OptionGroup attributeOptions = new OptionGroup(); - static { - attributeOptions.addOption(OPT_GIVENNAME); - attributeOptions.addOption(OPT_SURNAME); - attributeOptions.addOption(OPT_PHONE); - attributeOptions.addOption(OPT_LANGUAGE); - attributeOptions.addOption(OPT_REQUIRE_CERTIFICATE); - } /** * Tool for manipulating user accounts. @@ -1230,7 +1201,17 @@ public class EPerson extends DSpaceObject public static void main(String argv[]) throws ParseException, SQLException { - final PosixParser parser = new PosixParser(); + final OptionGroup VERBS = new OptionGroup(); + VERBS.addOption(VERB_ADD); + VERBS.addOption(VERB_DELETE); + VERBS.addOption(VERB_LIST); + VERBS.addOption(VERB_MODIFY); + + final Options globalOptions = new Options(); + globalOptions.addOptionGroup(VERBS); + globalOptions.addOption("h", "help", false, "explain options"); + + GnuParser parser = new GnuParser(); CommandLine command = parser.parse(globalOptions, argv, true); Context context = new Context(); @@ -1241,19 +1222,19 @@ public class EPerson extends DSpaceObject int status = 0; if (command.hasOption(VERB_ADD.getOpt())) { - status = cmdAdd(context, parser, argv); + status = cmdAdd(context, argv); } else if (command.hasOption(VERB_DELETE.getOpt())) { - status = cmdDelete(context, parser, argv); + status = cmdDelete(context, argv); } else if (command.hasOption(VERB_MODIFY.getOpt())) { - status = cmdModify(context, parser, argv); + status = cmdModify(context, argv); } else if (command.hasOption(VERB_LIST.getOpt())) { - status = cmdList(context, parser, argv); + status = cmdList(context, argv); } else if (command.hasOption('h')) { @@ -1279,15 +1260,23 @@ public class EPerson extends DSpaceObject } /** Command to create an EPerson. */ - private static int cmdAdd(Context context, CommandLineParser parser, String[] argv) + private static int cmdAdd(Context context, String[] argv) { Options options = new Options(); options.addOption(VERB_ADD); + final OptionGroup identityOptions = new OptionGroup(); + identityOptions.addOption(OPT_EMAIL); + identityOptions.addOption(OPT_NETID); + options.addOptionGroup(identityOptions); - options.addOptionGroup(attributeOptions); + options.addOption(OPT_GIVENNAME); + options.addOption(OPT_SURNAME); + options.addOption(OPT_PHONE); + options.addOption(OPT_LANGUAGE); + options.addOption(OPT_REQUIRE_CERTIFICATE); Option option = new Option("p", "password", true, "password to match the EPerson name"); options.addOption(option); @@ -1295,6 +1284,7 @@ public class EPerson extends DSpaceObject options.addOption("h", "help", false, "explain --add options"); // Rescan the command for more details. + GnuParser parser = new GnuParser(); CommandLine command; try { command = parser.parse(options, argv); @@ -1366,16 +1356,21 @@ public class EPerson extends DSpaceObject } /** Command to delete an EPerson. */ - private static int cmdDelete(Context context, CommandLineParser parser, String[] argv) + private static int cmdDelete(Context context, String[] argv) { Options options = new Options(); options.addOption(VERB_DELETE); + final OptionGroup identityOptions = new OptionGroup(); + identityOptions.addOption(OPT_EMAIL); + identityOptions.addOption(OPT_NETID); + options.addOptionGroup(identityOptions); options.addOption("h", "help", false, "explain --delete options"); + GnuParser parser = new GnuParser(); CommandLine command; try { command = parser.parse(options, argv); @@ -1436,15 +1431,23 @@ public class EPerson extends DSpaceObject } /** Command to modify an EPerson. */ - private static int cmdModify(Context context, CommandLineParser parser, String[] argv) + private static int cmdModify(Context context, String[] argv) { Options options = new Options(); options.addOption(VERB_MODIFY); + final OptionGroup identityOptions = new OptionGroup(); + identityOptions.addOption(OPT_EMAIL); + identityOptions.addOption(OPT_NETID); + options.addOptionGroup(identityOptions); - options.addOptionGroup(attributeOptions); + options.addOption(OPT_GIVENNAME); + options.addOption(OPT_SURNAME); + options.addOption(OPT_PHONE); + options.addOption(OPT_LANGUAGE); + options.addOption(OPT_REQUIRE_CERTIFICATE); options.addOption(OPT_CAN_LOGIN); options.addOption(OPT_NEW_EMAIL); @@ -1452,6 +1455,7 @@ public class EPerson extends DSpaceObject options.addOption("h", "help", false, "explain --modify options"); + GnuParser parser = new GnuParser(); CommandLine command; try { command = parser.parse(options, argv); @@ -1558,7 +1562,7 @@ public class EPerson extends DSpaceObject } /** Command to list known EPersons. */ - private static int cmdList(Context context, CommandLineParser parser, String[] argv) + private static int cmdList(Context context, String[] argv) { // XXX ideas: // specific user/netid From 34ce3d1ecd28746d2d6e001468f44c83a60d0884 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 6 Feb 2013 15:21:30 -0500 Subject: [PATCH 15/15] Update version from 11-year-old commons-cli 1.0 to latest 1.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2a4a488cce..7590f17934 100644 --- a/pom.xml +++ b/pom.xml @@ -647,7 +647,7 @@ commons-cli commons-cli - 1.0 + 1.2 commons-codec