From 0f3118dd5bb2620b7b18eb2a3736a8820d7fbf06 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 6 Aug 2013 02:29:50 -0400
Subject: [PATCH] Refactored CLI framework.

A new SubsystemCLI class was added as the base for subsystem CLI modules.
The MainCLI was modified such that it will only perform authentication if
the subsystem is specified in the server URI. If no subsystem is specified
in the URI, the authentication will be done by the subsystem CLI module.

Ticket #701
---
 .../src/com/netscape/cmstools/cli/CLI.java         | 79 +++++++++++++++++++++-
 .../src/com/netscape/cmstools/cli/MainCLI.java     | 17 +++--
 .../com/netscape/cmstools/cli/SubsystemCLI.java    | 66 ++++++++++++++++++
 .../src/com/netscape/cmstools/cli/TPSCLI.java      | 78 +++------------------
 .../src/com/netscape/cmstools/token/TokenCLI.java  | 37 ++--------
 5 files changed, 167 insertions(+), 110 deletions(-)
 create mode 100644 base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java

diff --git a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
index 40ac517af761e90789fe624598e466f5a9aa7b14..ecece0a09203b477e829d745da41f39a12c52509 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
@@ -25,6 +25,9 @@ import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.PosixParser;
+import org.apache.commons.lang.StringUtils;
+
+import com.netscape.certsrv.client.PKIClient;
 
 
 /**
@@ -37,14 +40,15 @@ public class CLI {
     public static CommandLineParser parser = new PosixParser();
     public static HelpFormatter formatter = new HelpFormatter();
 
-    public CLI parent;
-
     public String name;
     public String description;
+    public CLI parent;
 
     public Options options = new Options();
     public Map<String, CLI> modules = new LinkedHashMap<String, CLI>();
 
+    public PKIClient client;
+
     public CLI(String name, String description) {
         this(name, description, null);
     }
@@ -87,10 +91,79 @@ public class CLI {
         return modules.get(name);
     }
 
-    public void execute(String[] args) throws Exception {
+    public PKIClient getClient() {
+        return client;
+    }
+
+    public Object getClient(String name) {
+        return null;
     }
 
     public void printHelp() {
+
+        System.out.println("Commands:");
+
+        int leftPadding = 1;
+        int rightPadding = 25;
+
+        for (CLI module : modules.values()) {
+            String label = getFullName() + "-" + module.getName();
+
+            int padding = rightPadding - leftPadding - label.length();
+            if (padding < 1)
+                padding = 1;
+
+            System.out.print(StringUtils.repeat(" ", leftPadding));
+            System.out.print(label);
+            System.out.print(StringUtils.repeat(" ", padding));
+            System.out.println(module.getDescription());
+        }
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        if (args.length == 0) {
+            printHelp();
+            System.exit(1);
+        }
+
+        String command = args[0];
+        String moduleName;
+        String moduleCommand;
+
+        // If a command contains a '-' sign it will be
+        // split into module name and module command.
+        // Otherwise it's a single command.
+        int i = command.indexOf('-');
+        if (i >= 0) { // <module name>-<module command>
+            moduleName = command.substring(0, i);
+            moduleCommand = command.substring(i+1);
+
+        } else { // <command>
+            moduleName = command;
+            moduleCommand = null;
+        }
+
+        // get command module
+        if (verbose) System.out.println("Module: " + moduleName);
+        CLI module = getModule(moduleName);
+        if (module == null) {
+            throw new Error("Invalid module \"" + moduleName + "\".");
+        }
+
+        // prepare module arguments
+        String[] moduleArgs;
+        if (moduleCommand != null) {
+            moduleArgs = new String[args.length];
+            moduleArgs[0] = moduleCommand;
+            System.arraycopy(args, 1, moduleArgs, 1, args.length-1);
+
+        } else {
+            moduleArgs = new String[args.length-1];
+            System.arraycopy(args, 1, moduleArgs, 0, args.length-1);
+        }
+
+        module.execute(moduleArgs);
     }
 
     public static boolean isVerbose() {
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index 257f0bcfbd5418c2cc8332c13ce287fb7748817c..35d7d9e181cafd5db49225fb1a2f4d893c4f7d75 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -285,7 +285,13 @@ public class MainCLI extends CLI {
             connection.setOutput(file);
         }
 
-        accountClient = new AccountClient(client);
+        String path = config.getServerURI().getPath();
+        if (path.length() > 1) {
+            // if server URI includes subsystem, perform authentication
+            // against that subsystem
+            String subsystem = path.substring(1);
+            accountClient = new AccountClient(client, subsystem);
+        }
     }
 
     public void execute(String[] args) throws Exception {
@@ -374,14 +380,13 @@ public class MainCLI extends CLI {
         if (verbose) System.out.println("Server URI: "+config.getServerURI());
 
         // execute command
-        boolean loggedIn = false;
         try {
             init();
 
-            // login if username or nickname is specified
-            if (config.getUsername() != null || config.getCertNickname() != null) {
+            // login if subsystem is specified, and username or nickname is specified
+            if (accountClient != null &&
+                    (config.getUsername() != null || config.getCertNickname() != null)) {
                 accountClient.login();
-                loggedIn = true;
             }
 
             // execute module command
@@ -396,7 +401,7 @@ public class MainCLI extends CLI {
             System.exit(1);
 
         } finally {
-            if (loggedIn) accountClient.logout();
+            if (accountClient != null) accountClient.logout();
         }
     }
 
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b92c611a9232649e29ca50a0ae2475b0ba4753a
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/cli/SubsystemCLI.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.cli;
+
+import com.netscape.certsrv.client.ClientConfig;
+
+
+/**
+ * @author Endi S. Dewata
+ */
+public class SubsystemCLI extends CLI {
+
+    public MainCLI mainCLI;
+
+    public SubsystemCLI(String name, String description, MainCLI mainCLI) {
+        super(
+                name,
+                description,
+                null /* subsystem module has no parent module */);
+
+        this.mainCLI = mainCLI;
+    }
+
+    public void init() throws Exception {
+    }
+
+    public void login() throws Exception {
+    }
+
+    public void logout() throws Exception {
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        init();
+
+        try {
+            // login if username or nickname is specified
+            ClientConfig config = getClient().getConfig();
+            if (config.getUsername() != null || config.getCertNickname() != null) {
+                login();
+            }
+
+            super.execute(args);
+
+        } finally {
+            logout();
+        }
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/TPSCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/TPSCLI.java
index 4dd7e208cd73894f7abecf487baeafb863c32f4c..a68981ddbd08f878b0660577d2a15ded065a956f 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/TPSCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/TPSCLI.java
@@ -18,92 +18,32 @@
 
 package com.netscape.cmstools.cli;
 
-import org.apache.commons.lang.StringUtils;
-
 import com.netscape.certsrv.tps.TPSClient;
 import com.netscape.cmstools.token.TokenCLI;
 
 /**
  * @author Endi S. Dewata
  */
-public class TPSCLI extends CLI {
+public class TPSCLI extends SubsystemCLI {
 
-    public MainCLI mainCLI;
     public TPSClient tpsClient;
 
     public TPSCLI(MainCLI mainCLI) {
         super("tps", "TPS management commands", mainCLI);
-        this.mainCLI = mainCLI;
 
         addModule(new TokenCLI(this));
     }
 
-    public void printHelp() {
-
-        System.out.println("Commands:");
-
-        int leftPadding = 1;
-        int rightPadding = 25;
-
-        for (CLI module : modules.values()) {
-            String label = name + "-" + module.getName();
-
-            int padding = rightPadding - leftPadding - label.length();
-            if (padding < 1)
-                padding = 1;
-
-            System.out.print(StringUtils.repeat(" ", leftPadding));
-            System.out.print(label);
-            System.out.print(StringUtils.repeat(" ", padding));
-            System.out.println(module.getDescription());
-        }
+    public void init() throws Exception {
+        client = mainCLI.client;
+        tpsClient = new TPSClient(client);
     }
 
-    public void execute(String[] args) throws Exception {
-
-        tpsClient = new TPSClient(mainCLI.client);
-
-        if (args.length == 0) {
-            printHelp();
-            System.exit(1);
-        }
-
-        String command = args[0];
-        String moduleName;
-        String moduleCommand;
-
-        // If a command contains a '-' sign it will be
-        // split into module name and module command.
-        // Otherwise it's a single command.
-        int i = command.indexOf('-');
-        if (i >= 0) { // <module name>-<module command>
-            moduleName = command.substring(0, i);
-            moduleCommand = command.substring(i+1);
-
-        } else { // <command>
-            moduleName = command;
-            moduleCommand = null;
-        }
-
-        // get command module
-        if (verbose) System.out.println("Module: " + moduleName);
-        CLI module = getModule(moduleName);
-        if (module == null) {
-            throw new Error("Invalid module \"" + moduleName + "\".");
-        }
-
-        // prepare module arguments
-        String[] moduleArgs;
-        if (moduleCommand != null) {
-            moduleArgs = new String[args.length];
-            moduleArgs[0] = moduleCommand;
-            System.arraycopy(args, 1, moduleArgs, 1, args.length-1);
-
-        } else {
-            moduleArgs = new String[args.length-1];
-            System.arraycopy(args, 1, moduleArgs, 0, args.length-1);
-        }
+    public void login() {
+        tpsClient.login();
+    }
 
-        module.execute(moduleArgs);
+    public void logout() {
+        tpsClient.logout();
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/token/TokenCLI.java b/base/java-tools/src/com/netscape/cmstools/token/TokenCLI.java
index 539ce7bae01dc8cd9a8a91583a09d348e1fba8fb..9fb7cfe2d46dcf0d05b8e581491d8565e013622d 100644
--- a/base/java-tools/src/com/netscape/cmstools/token/TokenCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/token/TokenCLI.java
@@ -18,25 +18,22 @@
 
 package com.netscape.cmstools.token;
 
-import org.apache.commons.lang.StringUtils;
 import org.jboss.resteasy.plugins.providers.atom.Link;
 
 import com.netscape.certsrv.token.TokenClient;
 import com.netscape.certsrv.token.TokenData;
 import com.netscape.cmstools.cli.CLI;
-import com.netscape.cmstools.cli.TPSCLI;
+import com.netscape.cmstools.cli.SubsystemCLI;
 
 /**
  * @author Endi S. Dewata
  */
 public class TokenCLI extends CLI {
 
-    public TPSCLI tpsCLI;
     public TokenClient tokenClient;
 
-    public TokenCLI(TPSCLI tpsCLI) {
-        super("token", "Token management commands", tpsCLI);
-        this.tpsCLI = tpsCLI;
+    public TokenCLI(SubsystemCLI subsystemCLI) {
+        super("token", "Token management commands", subsystemCLI);
 
         addModule(new TokenAddCLI(this));
         addModule(new TokenFindCLI(this));
@@ -45,34 +42,10 @@ public class TokenCLI extends CLI {
         addModule(new TokenShowCLI(this));
     }
 
-    public String getFullName() {
-        return parent.getName() + "-" + name;
-    }
-
-    public void printHelp() {
-
-        System.out.println("Commands:");
-
-        int leftPadding = 1;
-        int rightPadding = 25;
-
-        for (CLI module : modules.values()) {
-            String label = getFullName() + "-" + module.getName();
-
-            int padding = rightPadding - leftPadding - label.length();
-            if (padding < 1)
-                padding = 1;
-
-            System.out.print(StringUtils.repeat(" ", leftPadding));
-            System.out.print(label);
-            System.out.print(StringUtils.repeat(" ", padding));
-            System.out.println(module.getDescription());
-        }
-    }
-
     public void execute(String[] args) throws Exception {
 
-        tokenClient = new TokenClient(tpsCLI.mainCLI.client);
+        client = parent.client;
+        tokenClient = (TokenClient)parent.getClient("token");
 
         if (args.length == 0) {
             printHelp();
-- 
1.8.1.4

