Commits

Sam Adams  committed 43db62e

Improved CLI command extensibility

  • Participants
  • Parent commits b131589

Comments (0)

Files changed (9)

File client-cli/src/main/java/net/chempound/client/cli/ChempoundClientCLI.java

 
 import com.beust.jcommander.JCommander;
 import com.beust.jcommander.ParameterException;
-import net.chempound.client.cli.command.DepositCommand;
-import net.chempound.client.cli.options.*;
+import net.chempound.client.cli.command.*;
+import net.chempound.client.cli.options.GlobalOptions;
 import net.chempound.client.cli.types.URIConverter;
 
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 public class ChempoundClientCLI {
     private static final String C_EXPORT = "export";
     private static final String C_HELP = "help";
     private static final String C_MOVE = "move";
-    
+
+    private Map<String,Command> commands = new LinkedHashMap<String, Command>();
+
     final GlobalOptions globalOptions = new GlobalOptions();
 
-    final CopyOptions copyOptions = new CopyOptions();
-    final DeleteOptions deleteOptions = new DeleteOptions();
-    final DepositOptions depositOptions = new DepositOptions();
-    final ExportOptions exportOptions = new ExportOptions();
-    final HelpOptions helpOptions = new HelpOptions();
-    final MoveOptions moveOptions = new MoveOptions();
-
     final JCommander jCommander;
 
     public static void main(final String[] args) {
         jCommander = initialiseCommandLineParser();
     }
 
-    protected void runMain(final String... args) {
+    public void runMain(final String... args) {
 
         try {
             jCommander.parse(args);
         else if (jCommander.getParsedCommand() == null) {
             displayUsageAndExit();
         }
-        else if (C_COPY.equals(jCommander.getParsedAlias())) {
-            executeCopy();
-        }
-        else if (C_DELETE.equals(jCommander.getParsedAlias())) {
-            executeDelete();
-        }
-        else if (C_DEPOSIT.equals(jCommander.getParsedCommand())) {
-            executeDeposit();
-        }
-        else if (C_EXPORT.equals(jCommander.getParsedAlias())) {
-            executeExport();
-        }
-        else if (C_HELP.equals(jCommander.getParsedAlias())) {
-            executeHelp();
-        }
-        else if (C_MOVE.equals(jCommander.getParsedAlias())) {
-            executeMove();
-        }
         else {
-            throw new UnsupportedOperationException("Unsupported command: "+jCommander.getParsedCommand());
+            final Command command = commands.get(jCommander.getParsedAlias());
+            if (command != null) {
+                invokeCommand(command);
+            } else {
+                throw new UnsupportedOperationException("Unsupported command: "+jCommander.getParsedCommand());
+            }
         }
     }
 
-    protected void executeCopy() {
-        throw new UnsupportedOperationException("Not yet implemented");
+    protected void invokeCommand(final Command command) {
+        command.invoke(globalOptions, command.getOptions());
     }
 
-    protected void executeDelete() {
-        new UnsupportedOperationException("Not yet implemented");
-    }
-
-    protected void executeDeposit() {
-        DepositCommand command = new DepositCommand(globalOptions, depositOptions);
-        command.execute();
-    }
-
-    protected void executeExport() {
-        throw new UnsupportedOperationException("Not yet implemented");
-    }
-
-    protected void executeHelp() {
-        throw new UnsupportedOperationException("Not yet implemented");
-    }
-
-    protected void executeMove() {
-        throw new UnsupportedOperationException("Not yet implemented");
-    }
-
-
-
     protected void exitWithError(final ParameterException e) {
         System.err.println(e.getMessage());
         jCommander.usage();
 
         jCommander.setProgramName(CHEMPOUND);
 
-        jCommander.addCommand(C_COPY, copyOptions);
-        jCommander.addCommand(C_DELETE, deleteOptions);
-        jCommander.addCommand(C_DEPOSIT, depositOptions);
-        jCommander.addCommand(C_EXPORT, exportOptions);
-        jCommander.addCommand(C_HELP, helpOptions);
-        jCommander.addCommand(C_MOVE, moveOptions);
+        installCommands(jCommander);
 
         return jCommander;
     }
 
+    private void installCommands(final JCommander jCommander) {
+        addCommand(jCommander, C_COPY, new CopyCommand());
+        addCommand(jCommander, C_DELETE, new DeleteCommand());
+        addCommand(jCommander, C_DEPOSIT, new DepositCommand());
+        addCommand(jCommander, C_EXPORT, new ExportCommand());
+        addCommand(jCommander, C_HELP, new HelpCommand());
+        addCommand(jCommander, C_MOVE, new MoveCommand());
+    }
+
+    protected void addCommand(final JCommander jCommander, final String alias, Command<?> command) {
+        commands.put(alias, command);
+        jCommander.addCommand(alias, command.getOptions());
+    }
+
     protected void basicUsage() {
         System.out.println("Chempound CLI");
         System.out.println();

File client-cli/src/main/java/net/chempound/client/cli/command/Command.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public interface Command<T> {
+
+    void invoke(GlobalOptions globalOptions, T options);
+
+    T getOptions();
+
+}

File client-cli/src/main/java/net/chempound/client/cli/command/CopyCommand.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.CopyOptions;
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public class CopyCommand implements Command<CopyOptions> {
+
+    private final CopyOptions options = new CopyOptions();
+
+    @Override
+    public CopyOptions getOptions() {
+        return options;
+    }
+
+    @Override
+    public void invoke(final GlobalOptions globalOptions, final CopyOptions options) {
+        throw new UnsupportedOperationException();
+    }
+
+}

File client-cli/src/main/java/net/chempound/client/cli/command/DeleteCommand.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.DeleteOptions;
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public class DeleteCommand implements Command<DeleteOptions> {
+
+    private final DeleteOptions options = new DeleteOptions();
+
+    @Override
+    public DeleteOptions getOptions() {
+        return options;
+    }
+
+    @Override
+    public void invoke(final GlobalOptions globalOptions, final DeleteOptions options) {
+        throw new UnsupportedOperationException();
+    }
+
+}

File client-cli/src/main/java/net/chempound/client/cli/command/DepositCommand.java

 /**
  * @author Sam Adams
  */
-public class DepositCommand {
+public class DepositCommand implements Command<DepositOptions> {
 
-    private final GlobalOptions globalOptions;
-    private final DepositOptions depositOptions;
+    private final DepositOptions depositOptions = new DepositOptions();
 
-    public DepositCommand(final GlobalOptions globalOptions, final DepositOptions depositOptions) {
-        this.globalOptions = globalOptions;
-        this.depositOptions = depositOptions;
+    @Override
+    public DepositOptions getOptions() {
+        return depositOptions;
     }
 
-    public void execute() {
+    public void invoke(final GlobalOptions globalOptions, final DepositOptions depositOptions) {
 
         final DepositBuilder depositBuilder = new DepositBuilder();
 

File client-cli/src/main/java/net/chempound/client/cli/command/ExportCommand.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.ExportOptions;
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public class ExportCommand implements Command<ExportOptions> {
+
+    private final ExportOptions options = new ExportOptions();
+
+    @Override
+    public ExportOptions getOptions() {
+        return options;
+    }
+
+    @Override
+    public void invoke(final GlobalOptions globalOptions, final ExportOptions options) {
+        throw new UnsupportedOperationException();
+    }
+
+}

File client-cli/src/main/java/net/chempound/client/cli/command/HelpCommand.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.HelpOptions;
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public class HelpCommand implements Command<HelpOptions> {
+
+    private final HelpOptions options = new HelpOptions();
+
+    @Override
+    public HelpOptions getOptions() {
+        return options;
+    }
+
+    @Override
+    public void invoke(final GlobalOptions globalOptions, final HelpOptions options) {
+        throw new UnsupportedOperationException();
+    }
+
+}

File client-cli/src/main/java/net/chempound/client/cli/command/MoveCommand.java

+package net.chempound.client.cli.command;
+
+import net.chempound.client.cli.options.MoveOptions;
+import net.chempound.client.cli.options.GlobalOptions;
+
+/**
+ * @author Sam Adams
+ */
+public class MoveCommand implements Command<MoveOptions> {
+
+    private final MoveOptions options = new MoveOptions();
+
+    @Override
+    public MoveOptions getOptions() {
+        return options;
+    }
+
+    @Override
+    public void invoke(final GlobalOptions globalOptions, final MoveOptions options) {
+        throw new UnsupportedOperationException();
+    }
+
+}

File client-cli/src/test/java/net/chempound/client/cli/ChempoundClientCLITest.java

 package net.chempound.client.cli;
 
+import net.chempound.client.cli.command.Command;
+import net.chempound.client.cli.command.DepositCommand;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.Arrays;
 
 
     private ChempoundClientCLI chempoundClient;
 
+    private Command<?> command;
+
     @Before
     public void setUp() throws Exception {
         chempoundClient = spy(new ChempoundClientCLI());
         doNothing().when(chempoundClient).displayUsageAndExit();
         doNothing().when(chempoundClient).exit(anyInt());
 
-        doNothing().when(chempoundClient).executeDeposit();
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                command = (Command) invocation.getArguments()[0];
+                return null;
+            }
+        }).when(chempoundClient).invokeCommand(any(Command.class));
     }
 
     @Test
     public void testParseVerboseFlag() {
         chempoundClient.runMain("-v");
+
         assertEquals(true, chempoundClient.globalOptions.verbose);
     }
 
     @Test
     public void testDisplayVersion() {
         chempoundClient.runMain("--version");
+
         verify(chempoundClient).displayVersionAndExit();
     }
 
     @Test
     public void testDeposit() {
         chempoundClient.runMain("deposit");
-        verify(chempoundClient).executeDeposit();
+
+        verify(chempoundClient).invokeCommand(any(DepositCommand.class));
     }
 
     @Test
     public void testDepositWithRepositoryShortArg() {
         chempoundClient.runMain("-R", "http://repo.example.com/", "deposit");
-        verify(chempoundClient).executeDeposit();
+
+        verify(chempoundClient).invokeCommand(any(DepositCommand.class));
         assertEquals("http://repo.example.com/", chempoundClient.globalOptions.repository);
     }
 
     @Test
     public void testDepositWithRepositoryLongArg() {
         chempoundClient.runMain("--repository", "http://repo.example.com/", "deposit");
-        verify(chempoundClient).executeDeposit();
+
+        verify(chempoundClient).invokeCommand(any(DepositCommand.class));
         assertEquals("http://repo.example.com/", chempoundClient.globalOptions.repository);
     }
 
     @Test
     public void testDepositFileList() {
         chempoundClient.runMain("deposit", "file1.foo", "file2.bar");
-        verify(chempoundClient).executeDeposit();
-        assertEquals(Arrays.asList("file1.foo", "file2.bar"), chempoundClient.depositOptions.files);
+
+        verify(chempoundClient).invokeCommand(any(DepositCommand.class));
+        DepositCommand depositCommand = (DepositCommand) command;
+        assertEquals(Arrays.asList("file1.foo", "file2.bar"), depositCommand.getOptions().files);
     }
 
     @Test
     public void testDepositWithTitleAndSlug() {
         chempoundClient.runMain("deposit", "-t", "--title--", "-s", "--slug--", "file1.foo", "file2.bar");
-        verify(chempoundClient).executeDeposit();
-        assertEquals("--title--", chempoundClient.depositOptions.title);
-        assertEquals("--slug--", chempoundClient.depositOptions.slug);
-        assertEquals(Arrays.asList("file1.foo", "file2.bar"), chempoundClient.depositOptions.files);
+        verify(chempoundClient).invokeCommand(any(DepositCommand.class));
+        DepositCommand depositCommand = (DepositCommand) command;
+        assertEquals("--title--", depositCommand.getOptions().title);
+        assertEquals("--slug--", depositCommand.getOptions().slug);
+        assertEquals(Arrays.asList("file1.foo", "file2.bar"), depositCommand.getOptions().files);
     }
 
 }