Update project structure to org.onap.aaf
[aaf/authz.git] / authz-cmd / src / main / java / org / onap / aaf / cmd / AAFcli.java
diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/AAFcli.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/AAFcli.java
new file mode 100644 (file)
index 0000000..5e0c802
--- /dev/null
@@ -0,0 +1,722 @@
+/*******************************************************************************\r
+ * ============LICENSE_START====================================================\r
+ * * org.onap.aaf\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.onap.aaf.cmd;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.Console;\r
+import java.io.File;\r
+import java.io.FileReader;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.OutputStreamWriter;\r
+import java.io.PrintWriter;\r
+import java.io.Reader;\r
+import java.io.Writer;\r
+import java.net.HttpURLConnection;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Properties;\r
+\r
+import org.apache.log4j.PropertyConfigurator;\r
+import org.onap.aaf.authz.env.AuthzEnv;\r
+import org.onap.aaf.cmd.mgmt.Mgmt;\r
+import org.onap.aaf.cmd.ns.NS;\r
+import org.onap.aaf.cmd.perm.Perm;\r
+import org.onap.aaf.cmd.role.Role;\r
+import org.onap.aaf.cmd.user.User;\r
+\r
+import com.att.aft.dme2.api.DME2Manager;\r
+import org.onap.aaf.cadi.Access.Level;\r
+import org.onap.aaf.cadi.CadiException;\r
+import org.onap.aaf.cadi.Locator;\r
+import org.onap.aaf.cadi.SecuritySetter;\r
+import org.onap.aaf.cadi.client.PropertyLocator;\r
+import org.onap.aaf.cadi.client.Retryable;\r
+import org.onap.aaf.cadi.config.Config;\r
+import org.onap.aaf.cadi.config.SecurityInfo;\r
+import org.onap.aaf.cadi.config.SecurityInfoC;\r
+import org.onap.aaf.cadi.dme2.DME2Locator;\r
+import org.onap.aaf.cadi.filter.AccessGetter;\r
+import org.onap.aaf.cadi.http.HBasicAuthSS;\r
+import org.onap.aaf.cadi.http.HMangr;\r
+import org.onap.aaf.inno.env.APIException;\r
+import org.onap.aaf.inno.env.Env;\r
+import org.onap.aaf.inno.env.impl.Log4JLogTarget;\r
+import org.onap.aaf.inno.env.util.Split;\r
+\r
+import jline.console.ConsoleReader;\r
+\r
+public class AAFcli {\r
+\r
+       public static final String AAF_DEFAULT_REALM = "aaf_default_realm";\r
+       protected static PrintWriter pw;\r
+       protected HMangr hman;\r
+       // Storage for last reused client. We can do this\r
+       // because we're technically "single" threaded calls.\r
+       public Retryable<?> prevCall;\r
+\r
+       protected SecuritySetter<HttpURLConnection> ss;\r
+       protected AuthzEnv env;\r
+       private boolean close;\r
+       private List<Cmd> cmds;\r
+\r
+       // Lex State\r
+       private ArrayList<Integer> expect = new ArrayList<Integer>();\r
+       private boolean verbose = true;\r
+       private int delay;\r
+       private SecurityInfo si;\r
+       private boolean request = false;\r
+       private String force = null;\r
+       private boolean gui = false;\r
+\r
+       private static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF);\r
+       private static boolean isConsole = false;\r
+       private static boolean isTest = false;\r
+       private static boolean showDetails = false;\r
+       private static boolean ignoreDelay = false;\r
+       private static int globalDelay=0;\r
+       \r
+       public static int timeout() {\r
+               return TIMEOUT;\r
+       }\r
+\r
+       public AAFcli(AuthzEnv env, Writer wtr, HMangr hman, SecurityInfo si, SecuritySetter<HttpURLConnection> ss) throws APIException {\r
+               this.env = env;\r
+               this.ss = ss;\r
+               this.hman = hman;\r
+               this.si = si;\r
+               if (wtr instanceof PrintWriter) {\r
+                       pw = (PrintWriter) wtr;\r
+                       close = false;\r
+               } else {\r
+                       pw = new PrintWriter(wtr);\r
+                       close = true;\r
+               }\r
+\r
+\r
+               // client = new DRcli(new URI(aafurl), new\r
+               // BasicAuth(user,toPass(pass,true)))\r
+               // .apiVersion("2.0")\r
+               // .timeout(TIMEOUT);\r
+\r
+               /*\r
+                * Create Cmd Tree\r
+                */\r
+               cmds = new ArrayList<Cmd>();\r
+\r
+               Role role = new Role(this);\r
+               cmds.add(new Help(this, cmds));\r
+               cmds.add(new Version(this));\r
+               cmds.add(new Perm(role));\r
+               cmds.add(role);\r
+               cmds.add(new User(this));\r
+               cmds.add(new NS(this));\r
+               cmds.add(new Mgmt(this));\r
+       }\r
+\r
+       public void verbose(boolean v) {\r
+               verbose = v;\r
+       }\r
+\r
+       public void close() {\r
+               if (hman != null) {\r
+                       hman.close();\r
+                       hman = null;\r
+               }\r
+               if (close) {\r
+                       pw.close();\r
+               }\r
+       }\r
+\r
+       public boolean eval(String line) throws Exception {\r
+               if (line.length() == 0) {\r
+                       return true;\r
+               } else if (line.startsWith("#")) {\r
+                       pw.println(line);\r
+                       return true;\r
+               }\r
+\r
+               String[] largs = argEval(line);\r
+               int idx = 0;\r
+\r
+               // Variable replacement\r
+               StringBuilder sb = null;\r
+               while (idx < largs.length) {\r
+                       int e = 0;\r
+                       for (int v = largs[idx].indexOf("@["); v >= 0; v = largs[idx].indexOf("@[", v + 1)) {\r
+                               if (sb == null) {\r
+                                       sb = new StringBuilder();\r
+                               }\r
+                               sb.append(largs[idx], e, v);\r
+                               if ((e = largs[idx].indexOf(']', v)) >= 0) {\r
+                                       String p = env.getProperty(largs[idx].substring(v + 2, e++));\r
+                                       if (p != null) {\r
+                                               sb.append(p);\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (sb != null && sb.length() > 0) {\r
+                               sb.append(largs[idx], e, largs[idx].length());\r
+                               largs[idx] = sb.toString();\r
+                               sb.setLength(0);\r
+                       }\r
+                       ++idx;\r
+               }\r
+\r
+               idx = 0;\r
+               boolean rv = true;\r
+               while (rv && idx < largs.length) {\r
+                       // Allow Script to change Credential\r
+                       if (!gui) {\r
+                               if("as".equalsIgnoreCase(largs[idx])) {\r
+                                       if (largs.length > ++idx) {\r
+                                               // get Password from Props with ID as Key\r
+                                               String user = largs[idx++];\r
+                                               int colon = user.indexOf(':');\r
+                                               String pass;\r
+                                               if (colon > 0) {\r
+                                                       pass = user.substring(colon + 1);\r
+                                                       user = user.substring(0, colon);\r
+                                               } else {\r
+                                                       pass = env.getProperty(user);\r
+                                               }\r
+                                               \r
+                                               if (pass != null) {\r
+                                                       pass = env.decrypt(pass, false);\r
+                                                       env.setProperty(user, pass);\r
+                                                       ss = new HBasicAuthSS(user, pass,(SecurityInfoC<HttpURLConnection>) si);\r
+                                                       pw.println("as " + user);\r
+                                               } else { // get Pass from System Properties, under name of\r
+                                                       // Tag\r
+                                                       pw.println("ERROR: No password set for " + user);\r
+                                                       rv = false;\r
+                                               }\r
+                                               continue;\r
+                                       }\r
+                               } else if ("expect".equalsIgnoreCase(largs[idx])) {\r
+                                       expect.clear();\r
+                                       if (largs.length > idx++) {\r
+                                               if (!"nothing".equals(largs[idx])) {\r
+                                                       for (String str : largs[idx].split(",")) {\r
+                                                               try {\r
+                                                                       if ("Exception".equalsIgnoreCase(str)) {\r
+                                                                               expect.add(-1);\r
+                                                                       } else {\r
+                                                                               expect.add(Integer.parseInt(str));\r
+                                                                       }\r
+                                                               } catch (NumberFormatException e) {\r
+                                                                       throw new CadiException("\"expect\" should be followed by Number");\r
+                                                               }\r
+                                                       }\r
+                                               ++idx;\r
+                                               }\r
+                                       }\r
+                                       continue;\r
+                                       // Sleep, typically for reports, to allow DB to update\r
+                                       // Milliseconds\r
+                                       \r
+                               } else if ("sleep".equalsIgnoreCase(largs[idx])) {\r
+                                       Integer t = Integer.parseInt(largs[++idx]);\r
+                                       pw.println("sleep " + t);\r
+                                       Thread.sleep(t);\r
+                                       ++idx;\r
+                                       continue;\r
+                               } else if ("delay".equalsIgnoreCase(largs[idx])) {\r
+                                       delay = Integer.parseInt(largs[++idx]);\r
+                                       pw.println("delay " + delay);\r
+                                       ++idx;\r
+                                       continue;\r
+                               } else if ("pause".equalsIgnoreCase(largs[idx])) {\r
+                                       pw.println("Press <Return> to continue...");\r
+                                       ++idx;\r
+                                       new BufferedReader(new InputStreamReader(System.in)).readLine();\r
+                                       continue;\r
+                               } else if ("exit".equalsIgnoreCase(largs[idx])) {\r
+                                       pw.println("Exiting...");\r
+                                       return false;\r
+                               }\r
+\r
+                       } \r
+                       \r
+                       if("REQUEST".equalsIgnoreCase(largs[idx])) {\r
+                               request=true;\r
+                               ++idx;\r
+                       } else if("FORCE".equalsIgnoreCase(largs[idx])) {\r
+                               force="true";\r
+                               ++idx;\r
+                       } else if ("set".equalsIgnoreCase(largs[idx])) {\r
+                               while (largs.length > ++idx) {\r
+                                       int equals = largs[idx].indexOf('=');\r
+                                       if (equals < 0) {\r
+                                               break;\r
+                                       }\r
+                                       String tag = largs[idx].substring(0, equals);\r
+                                       String value = largs[idx].substring(++equals);\r
+                                       pw.println("set " + tag + ' ' + value);\r
+                                       boolean isTrue = "TRUE".equalsIgnoreCase(value);\r
+                                       if("FORCE".equalsIgnoreCase(tag)) {\r
+                                               force = value;\r
+                                       } else if("REQUEST".equalsIgnoreCase(tag)) {\r
+                                               request = isTrue;\r
+                                       } else if("DETAILS".equalsIgnoreCase(tag)) {\r
+                                               showDetails = isTrue;\r
+                                       } else {\r
+                                               env.setProperty(tag, value);\r
+                                       }\r
+                               }\r
+                               continue;\r
+                               // Allow Script to indicate if Failure is what is expected\r
+                       }\r
+\r
+                       int ret = 0;\r
+                       for (Cmd c : cmds) {\r
+                               if (largs[idx].equalsIgnoreCase(c.getName())) {\r
+                                       if (verbose) {\r
+                                               pw.println(line);\r
+                                               if (expect.size() > 0) {\r
+                                                       pw.print("** Expect ");\r
+                                                       boolean first = true;\r
+                                                       for (Integer i : expect) {\r
+                                                               if (first) {\r
+                                                                       first = false;\r
+                                                               } else {\r
+                                                                       pw.print(',');\r
+                                                               }\r
+                                                               pw.print(i);\r
+                                                       }\r
+                                                       pw.println(" **");\r
+                                               }\r
+                                       }\r
+                                       try {\r
+                                               ret = c.exec(++idx, largs);\r
+                                               if (delay+globalDelay > 0) {\r
+                                                       Thread.sleep(delay+globalDelay);\r
+                                               }\r
+                                       } catch (Exception e) {\r
+                                               if (expect.contains(-1)) {\r
+                                                       pw.println(e.getMessage());\r
+                                                       ret = -1;\r
+                                               } else {\r
+                                                       throw e;\r
+                                               }\r
+                                       } finally {\r
+                                               clearSingleLineProperties();\r
+                                       }\r
+                                       rv = expect.isEmpty() ? true : expect.contains(ret);\r
+                                       if (verbose) {\r
+                                               if (rv) {\r
+                                                       pw.println();\r
+                                               } else {\r
+                                                       pw.print("!!! Unexpected Return Code: ");\r
+                                                       pw.print(ret);\r
+                                                       pw.println(", VALIDATE OUTPUT!!!");\r
+                                               }\r
+                                       }\r
+                                       return rv;\r
+                               }\r
+                       }\r
+                       pw.write("Unknown Instruction \"");\r
+                       pw.write(largs[idx]);\r
+                       pw.write("\"\n");\r
+                       idx = largs.length;// always end after one command\r
+               }\r
+               return rv;\r
+       }\r
+\r
+       private String[] argEval(String line) {\r
+               StringBuilder sb = new StringBuilder();\r
+               ArrayList<String> arr = new ArrayList<String>();\r
+               boolean start = true;\r
+               char quote = 0;\r
+               for (int i = 0; i < line.length(); ++i) {\r
+                       char ch;\r
+                       if (Character.isWhitespace(ch = line.charAt(i))) {\r
+                               if (start) {\r
+                                       continue; // trim\r
+                               } else if (quote != 0) {\r
+                                       sb.append(ch);\r
+                               } else {\r
+                                       arr.add(sb.toString());\r
+                                       sb.setLength(0);\r
+                                       start = true;\r
+                               }\r
+                       } else if (ch == '\'' || ch == '"') { // toggle\r
+                               if (quote == ch) {\r
+                                       quote = 0;\r
+                               } else {\r
+                                       quote = ch;\r
+                               }\r
+                       } else {\r
+                               start = false;\r
+                               sb.append(ch);\r
+                       }\r
+               }\r
+               if (sb.length() > 0) {\r
+                       arr.add(sb.toString());\r
+               }\r
+\r
+               String[] rv = new String[arr.size()];\r
+               arr.toArray(rv);\r
+               return rv;\r
+       }\r
+\r
+       public static void keyboardHelp() {\r
+               System.out.println("'C-' means hold the ctrl key down while pressing the next key.");\r
+               System.out.println("'M-' means hold the alt key down while pressing the next key.");\r
+               System.out.println("For instance, C-b means hold ctrl key and press b, M-b means hold alt and press b\n");\r
+\r
+               System.out.println("Basic Keybindings:");\r
+               System.out.println("\tC-l - clear screen");        \r
+               System.out.println("\tC-a - beginning of line");\r
+               System.out.println("\tC-e - end of line");\r
+               System.out.println("\tC-b - backward character (left arrow also works)");\r
+               System.out.println("\tM-b - backward word");\r
+               System.out.println("\tC-f - forward character (right arrow also works)");\r
+               System.out.println("\tM-f - forward word");\r
+               System.out.println("\tC-d - delete character under cursor");\r
+               System.out.println("\tM-d - delete word forward");\r
+               System.out.println("\tM-backspace - delete word backward");\r
+               System.out.println("\tC-k - delete from cursor to end of line");\r
+               System.out.println("\tC-u - delete entire line, regardless of cursor position\n");\r
+\r
+               System.out.println("Command History:");\r
+               System.out.println("\tC-r - search backward in history (repeating C-r continues the search)");\r
+               System.out.println("\tC-p - move backwards through history (up arrow also works)");\r
+               System.out.println("\tC-n - move forwards through history (down arrow also works)\n");\r
+\r
+       }\r
+\r
+       /**\r
+        * @param args\r
+        */\r
+       public static void main(String[] args) {\r
+               int rv = 0;\r
+               // Cover for bash's need to escape *... (\\*)\r
+               for (int i = 0; i < args.length; ++i) {\r
+                       if ("\\*".equals(args[i])) {\r
+                               args[i] = "*";\r
+                       }\r
+               }\r
+               \r
+               System.setProperty("java.util.logging.config.file", "etc/logging.props");\r
+               final AuthzEnv env = new AuthzEnv(System.getProperties());\r
+               \r
+               // Stop the (exceedingly annoying) DME2/other logs from printing console\r
+               InputStream is;\r
+\r
+               // Load Log4j too... sigh\r
+               is = ClassLoader.getSystemResourceAsStream("log4j.properties");\r
+               if(is==null) {\r
+                       env.log(Level.WARN, "Cannot find 'log4j.properties' in Classpath.  Best option: add 'etc' directory to classpath");\r
+               } else {\r
+                       try {\r
+                               Properties props = new Properties();\r
+                               props.load(is);\r
+                               PropertyConfigurator.configure(props);\r
+                       } catch (Exception e) {\r
+                               e.printStackTrace();\r
+                       } finally {\r
+                               try {\r
+                                       is.close();\r
+                               } catch (IOException e) {\r
+                                       env.debug().log(e); // only logging to avoid Sonar False positives.\r
+                               }\r
+                       }\r
+               }\r
+\r
+               env.loadFromSystemPropsStartsWith("AFT", "DME2", "aaf", "keyfile");\r
+               try {\r
+                       Log4JLogTarget.setLog4JEnv("aaf", env);\r
+                       GetProp gp = new GetProp(env);\r
+                       String user = gp.get(false,Config.AAF_MECHID,"fully qualified id");\r
+                       String pass = gp.get(true, Config.AAF_MECHPASS, "password is hidden");\r
+                       if(env.getProperty(Config.AAF_URL)==null) {\r
+                               String p = env.getProperty("DMEServiceName");\r
+                               if(p!=null) {\r
+                                       boolean https = "true".equalsIgnoreCase(env.getProperty("AFT_DME2_SSL_ENABLE"));\r
+                                       env.setProperty(Config.AAF_URL, "http"+(https?"s":"")+"://DME2RESOLVE/"+p);\r
+                               }\r
+                       }\r
+                       String aafUrl = gp.get(false, Config.AAF_URL, "https://DME2RESOLVE or Direct URL:port");\r
+\r
+                       if(aafUrl!=null && aafUrl.contains("//DME2")) {\r
+                               //gp.set(Config.AFT_LATITUDE,"Lookup from a Map App or table");\r
+                               //gp.set(Config.AFT_LONGITUDE,"Lookup from a Map App or table");\r
+                               //gp.set(Config.AFT_ENVIRONMENT,"Check DME2 Installations");\r
+                       }\r
+\r
+                       if (gp.err() != null) {\r
+                               gp.err().append("to continue...");\r
+                               System.err.println(gp.err());\r
+                               System.exit(1);\r
+                       }\r
+                       \r
+\r
+                       Reader rdr = null;\r
+                       boolean exitOnFailure = true;\r
+                       /*\r
+                        * Check for "-" options anywhere in command line\r
+                        */\r
+                       StringBuilder sb = new StringBuilder();\r
+                       for (int i = 0; i < args.length; ++i) {\r
+                               if ("-i".equalsIgnoreCase(args[i])) {\r
+                                       rdr = new InputStreamReader(System.in);\r
+                                       // } else if("-o".equalsIgnoreCase(args[i])) {\r
+                                       // // shall we do something different? Output stream is\r
+                                       // already done...\r
+                               } else if ("-f".equalsIgnoreCase(args[i])) {\r
+                                       if (args.length > i + 1) {\r
+                                               rdr = new FileReader(args[++i]);\r
+                                       }\r
+                               } else if ("-a".equalsIgnoreCase(args[i])) {\r
+                                       exitOnFailure = false;\r
+                               } else if ("-c".equalsIgnoreCase(args[i])) {\r
+                                       isConsole = true;\r
+                               } else if ("-s".equalsIgnoreCase(args[i]) && args.length > i + 1) {\r
+                                       env.setProperty(Cmd.STARTDATE, args[++i]);\r
+                               } else if ("-e".equalsIgnoreCase(args[i]) && args.length > i + 1) {\r
+                                       env.setProperty(Cmd.ENDDATE, args[++i]);\r
+                               } else if ("-t".equalsIgnoreCase(args[i])) {\r
+                                       isTest = true;\r
+                               } else if ("-d".equalsIgnoreCase(args[i])) {\r
+                                       showDetails = true;\r
+                               } else if ("-n".equalsIgnoreCase(args[i])) {\r
+                                       ignoreDelay = true;\r
+                               } else {\r
+                                       if (sb.length() > 0) {\r
+                                               sb.append(' ');\r
+                                       }\r
+                                       sb.append(args[i]);\r
+                               }\r
+                       }\r
+\r
+                       SecurityInfo si = new SecurityInfo(env);\r
+                       env.loadToSystemPropsStartsWith("AAF", "DME2");\r
+                       Locator loc;\r
+                       if(aafUrl.contains("//DME2RESOLVE")) {\r
+                               DME2Manager dm = new DME2Manager("AAFcli DME2Manager", System.getProperties());\r
+                               loc = new DME2Locator(env, dm, aafUrl);\r
+                       } else {\r
+                               loc = new PropertyLocator(aafUrl);\r
+                       }\r
+\r
+                       //Config.configPropFiles(new AccessGetter(env), env);\r
+                       \r
+                       TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF));\r
+                       HMangr hman = new HMangr(env, loc).readTimeout(TIMEOUT).apiVersion("2.0");\r
+                       \r
+                       //TODO: Consider requiring a default in properties\r
+                       env.setProperty(Config.AAF_DEFAULT_REALM, System.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));\r
+\r
+                       AAFcli aafcli = new AAFcli(env, new OutputStreamWriter(System.out), hman, si, \r
+                               new HBasicAuthSS(user, env.decrypt(pass,false), (SecurityInfoC<HttpURLConnection>) si));\r
+                       if(!ignoreDelay) {\r
+                               File delay = new File("aafcli.delay");\r
+                               if(delay.exists()) {\r
+                                       BufferedReader br = new BufferedReader(new FileReader(delay));\r
+                                       try {\r
+                                               globalDelay = Integer.parseInt(br.readLine());\r
+                                       } catch(Exception e) {\r
+                                               env.debug().log(e);\r
+                                       } finally {\r
+                                               br.close();\r
+                                       }\r
+                               }\r
+                       }\r
+                       try {\r
+                               if (isConsole) {\r
+                                       System.out.println("Type 'help' for short help or 'help -d' for detailed help with aafcli commands");\r
+                                       System.out.println("Type '?' for help with command line editing");\r
+                                       System.out.println("Type 'q', 'quit', or 'exit' to quit aafcli\n");\r
+\r
+                                       ConsoleReader reader = new ConsoleReader();\r
+                                       try {\r
+                                               reader.setPrompt("aafcli > ");\r
+       \r
+                                               String line;\r
+                                               while ((line = reader.readLine()) != null) {\r
+                                                       showDetails = (line.contains("-d"))?true:false;\r
+       \r
+                                                       if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("q") || line.equalsIgnoreCase("exit")) {\r
+                                                               break;\r
+                                                       } else if (line.equalsIgnoreCase("--help -d") || line.equalsIgnoreCase("help -d") \r
+                                                                       || line.equalsIgnoreCase("help")) {\r
+                                                               line = "--help";\r
+                                                       } else if (line.equalsIgnoreCase("cls")) {\r
+                                                               reader.clearScreen();\r
+                                                               continue;\r
+                                                       } else if (line.equalsIgnoreCase("?")) {\r
+                                                               keyboardHelp();\r
+                                                               continue;\r
+                                                       }\r
+                                                       try {\r
+                                                               aafcli.eval(line);\r
+                                                               pw.flush();\r
+                                                       } catch (Exception e) {\r
+                                                               pw.println(e.getMessage());\r
+                                                               pw.flush();\r
+                                                       }\r
+                                               }\r
+                                       } finally {\r
+                                               reader.close();\r
+                                       }\r
+                               } else if (rdr != null) {\r
+                                       BufferedReader br = new BufferedReader(rdr);\r
+                                       String line;\r
+                                       while ((line = br.readLine()) != null) {\r
+                                               if (!aafcli.eval(line) && exitOnFailure) {\r
+                                                       rv = 1;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               } else { // just run the command line\r
+                                       aafcli.verbose(false);\r
+                                       if (sb.length() == 0) {\r
+                                               sb.append("--help");\r
+                                       }\r
+                                       rv = aafcli.eval(sb.toString()) ? 0 : 1;\r
+                               }\r
+                       } finally {\r
+                               aafcli.close();\r
+\r
+                               // Don't close if No Reader, or it's a Reader of Standard In\r
+                               if (rdr != null && !(rdr instanceof InputStreamReader)) {\r
+                                       rdr.close();\r
+                               }\r
+                       }\r
+               } catch (MessageException e) {\r
+                       System.out.println("MessageException caught");\r
+\r
+                       System.err.println(e.getMessage());\r
+               } catch (Exception e) {\r
+                       e.printStackTrace(System.err);\r
+               }\r
+               System.exit(rv);\r
+\r
+       }\r
+\r
+       private static class GetProp {\r
+               private Console cons = System.console();\r
+               private StringBuilder err = null;\r
+               private AuthzEnv env;\r
+               \r
+               public GetProp(AuthzEnv env) {\r
+                       this.env = env;\r
+               }\r
+\r
+               public String get(final boolean pass, final String tag, final String other)  {\r
+                       String data = env.getProperty(tag,null);\r
+                       if (data == null) {\r
+                               if(cons!=null) {\r
+                                       if(pass) {\r
+                                               char[] cp = System.console().readPassword("%s: ",tag);\r
+                                               if(cp!=null) {\r
+                                                       data=String.valueOf(cp);\r
+                                               }\r
+                                       } else {\r
+                                               cons.writer().format("%s: ", tag);\r
+                                               cons.flush();\r
+                                               data = cons.readLine();\r
+                                       }\r
+                               }\r
+                               if(data==null) {\r
+                                       if(err == null) {\r
+                                               err  = new StringBuilder("Add -D");\r
+                                       } else {\r
+                                               err.append(", -D");\r
+                                       }\r
+                                       err.append(tag);\r
+                                       if(other!=null) {\r
+                                               err.append("=<");\r
+                                               err.append(other);\r
+                                               err.append('>');\r
+                                       }\r
+                               }\r
+                       }\r
+                       return data;\r
+               }\r
+               \r
+               public void set(final String tag, final String other)  {\r
+                       String data = env.getProperty(tag,null);\r
+                       if (data == null) {\r
+                               if(cons!=null) {\r
+                                       cons.writer().format("%s: ", tag);\r
+                                       cons.flush();\r
+                                       data = cons.readLine();\r
+                               }\r
+                               if(data==null) {\r
+                                       if(err == null) {\r
+                                               err  = new StringBuilder("Add -D");\r
+                                       } else {\r
+                                               err.append(", -D");\r
+                                       }\r
+                                       err.append(tag);\r
+                                       if(other!=null) {\r
+                                               err.append("=<");\r
+                                               err.append(other);\r
+                                               err.append('>');\r
+                                       }\r
+                               }\r
+                       }\r
+                       if(data!=null) {\r
+                               System.setProperty(tag, data);\r
+                       }\r
+               }\r
+\r
+               public StringBuilder err() {\r
+                       return err;\r
+               }\r
+       }\r
+\r
+       public boolean isTest() {\r
+               return AAFcli.isTest;\r
+       }\r
+       \r
+       public boolean isDetailed() {\r
+               return AAFcli.showDetails;\r
+       }\r
+\r
+       public String typeString(Class<?> cls, boolean json) {\r
+               return "application/" + cls.getSimpleName() + "+" + (json ? "json" : "xml") + ";version=" + hman.apiVersion();\r
+       }\r
+\r
+       public String forceString() {\r
+               return force;\r
+       }\r
+\r
+       public boolean addRequest() {\r
+               return request;\r
+       }\r
+\r
+       public void clearSingleLineProperties() {\r
+               force  = null;\r
+               request = false;\r
+               showDetails = false;\r
+       }\r
+\r
+       public void gui(boolean b) {\r
+               gui  = b;\r
+       }\r
+\r
+}\r