[AAF-21] Initial code import
[aaf/authz.git] / authz-cmd / src / main / java / com / att / cmd / AAFcli.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aai\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * Copyright © 2017 Amdocs\r
7  * * ===========================================================================\r
8  * * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * * you may not use this file except in compliance with the License.\r
10  * * You may obtain a copy of the License at\r
11  * * \r
12  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * * \r
14  *  * Unless required by applicable law or agreed to in writing, software\r
15  * * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * * See the License for the specific language governing permissions and\r
18  * * limitations under the License.\r
19  * * ============LICENSE_END====================================================\r
20  * *\r
21  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
22  * *\r
23  ******************************************************************************/\r
24 package com.att.cmd;\r
25 \r
26 import java.io.BufferedReader;\r
27 import java.io.Console;\r
28 import java.io.File;\r
29 import java.io.FileReader;\r
30 import java.io.IOException;\r
31 import java.io.InputStream;\r
32 import java.io.InputStreamReader;\r
33 import java.io.OutputStreamWriter;\r
34 import java.io.PrintWriter;\r
35 import java.io.Reader;\r
36 import java.io.Writer;\r
37 import java.net.HttpURLConnection;\r
38 import java.util.ArrayList;\r
39 import java.util.List;\r
40 import java.util.Properties;\r
41 \r
42 import org.apache.log4j.PropertyConfigurator;\r
43 \r
44 import com.att.aft.dme2.api.DME2Manager;\r
45 import com.att.authz.env.AuthzEnv;\r
46 import com.att.cadi.Access.Level;\r
47 import com.att.cadi.CadiException;\r
48 import com.att.cadi.Locator;\r
49 import com.att.cadi.SecuritySetter;\r
50 import com.att.cadi.client.PropertyLocator;\r
51 import com.att.cadi.client.Retryable;\r
52 import com.att.cadi.config.Config;\r
53 import com.att.cadi.config.SecurityInfo;\r
54 import com.att.cadi.config.SecurityInfoC;\r
55 import com.att.cadi.dme2.DME2Locator;\r
56 import com.att.cadi.filter.AccessGetter;\r
57 import com.att.cadi.http.HBasicAuthSS;\r
58 import com.att.cadi.http.HMangr;\r
59 import com.att.cmd.mgmt.Mgmt;\r
60 import com.att.cmd.ns.NS;\r
61 import com.att.cmd.perm.Perm;\r
62 import com.att.cmd.role.Role;\r
63 import com.att.cmd.user.User;\r
64 import com.att.inno.env.APIException;\r
65 import com.att.inno.env.Env;\r
66 import com.att.inno.env.impl.Log4JLogTarget;\r
67 import com.att.inno.env.util.Split;\r
68 \r
69 import jline.console.ConsoleReader;\r
70 \r
71 public class AAFcli {\r
72 \r
73         public static final String AAF_DEFAULT_REALM = "aaf_default_realm";\r
74         protected static PrintWriter pw;\r
75         protected HMangr hman;\r
76         // Storage for last reused client. We can do this\r
77         // because we're technically "single" threaded calls.\r
78         public Retryable<?> prevCall;\r
79 \r
80         protected SecuritySetter<HttpURLConnection> ss;\r
81         protected AuthzEnv env;\r
82         private boolean close;\r
83         private List<Cmd> cmds;\r
84 \r
85         // Lex State\r
86         private ArrayList<Integer> expect = new ArrayList<Integer>();\r
87         private boolean verbose = true;\r
88         private int delay;\r
89         private SecurityInfo si;\r
90         private boolean request = false;\r
91         private String force = null;\r
92         private boolean gui = false;\r
93 \r
94         private static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF);\r
95         private static boolean isConsole = false;\r
96         private static boolean isTest = false;\r
97         private static boolean showDetails = false;\r
98         private static boolean ignoreDelay = false;\r
99         private static int globalDelay=0;\r
100         \r
101         public static int timeout() {\r
102                 return TIMEOUT;\r
103         }\r
104 \r
105         public AAFcli(AuthzEnv env, Writer wtr, HMangr hman, SecurityInfo si, SecuritySetter<HttpURLConnection> ss) throws APIException {\r
106                 this.env = env;\r
107                 this.ss = ss;\r
108                 this.hman = hman;\r
109                 this.si = si;\r
110                 if (wtr instanceof PrintWriter) {\r
111                         pw = (PrintWriter) wtr;\r
112                         close = false;\r
113                 } else {\r
114                         pw = new PrintWriter(wtr);\r
115                         close = true;\r
116                 }\r
117 \r
118 \r
119                 // client = new DRcli(new URI(aafurl), new\r
120                 // BasicAuth(user,toPass(pass,true)))\r
121                 // .apiVersion("2.0")\r
122                 // .timeout(TIMEOUT);\r
123 \r
124                 /*\r
125                  * Create Cmd Tree\r
126                  */\r
127                 cmds = new ArrayList<Cmd>();\r
128 \r
129                 Role role = new Role(this);\r
130                 cmds.add(new Help(this, cmds));\r
131                 cmds.add(new Version(this));\r
132                 cmds.add(new Perm(role));\r
133                 cmds.add(role);\r
134                 cmds.add(new User(this));\r
135                 cmds.add(new NS(this));\r
136                 cmds.add(new Mgmt(this));\r
137         }\r
138 \r
139         public void verbose(boolean v) {\r
140                 verbose = v;\r
141         }\r
142 \r
143         public void close() {\r
144                 if (hman != null) {\r
145                         hman.close();\r
146                         hman = null;\r
147                 }\r
148                 if (close) {\r
149                         pw.close();\r
150                 }\r
151         }\r
152 \r
153         public boolean eval(String line) throws Exception {\r
154                 if (line.length() == 0) {\r
155                         return true;\r
156                 } else if (line.startsWith("#")) {\r
157                         pw.println(line);\r
158                         return true;\r
159                 }\r
160 \r
161                 String[] largs = argEval(line);\r
162                 int idx = 0;\r
163 \r
164                 // Variable replacement\r
165                 StringBuilder sb = null;\r
166                 while (idx < largs.length) {\r
167                         int e = 0;\r
168                         for (int v = largs[idx].indexOf("@["); v >= 0; v = largs[idx].indexOf("@[", v + 1)) {\r
169                                 if (sb == null) {\r
170                                         sb = new StringBuilder();\r
171                                 }\r
172                                 sb.append(largs[idx], e, v);\r
173                                 if ((e = largs[idx].indexOf(']', v)) >= 0) {\r
174                                         String p = env.getProperty(largs[idx].substring(v + 2, e++));\r
175                                         if (p != null) {\r
176                                                 sb.append(p);\r
177                                         }\r
178                                 }\r
179                         }\r
180                         if (sb != null && sb.length() > 0) {\r
181                                 sb.append(largs[idx], e, largs[idx].length());\r
182                                 largs[idx] = sb.toString();\r
183                                 sb.setLength(0);\r
184                         }\r
185                         ++idx;\r
186                 }\r
187 \r
188                 idx = 0;\r
189                 boolean rv = true;\r
190                 while (rv && idx < largs.length) {\r
191                         // Allow Script to change Credential\r
192                         if (!gui) {\r
193                                 if("as".equalsIgnoreCase(largs[idx])) {\r
194                                         if (largs.length > ++idx) {\r
195                                                 // get Password from Props with ID as Key\r
196                                                 String user = largs[idx++];\r
197                                                 int colon = user.indexOf(':');\r
198                                                 String pass;\r
199                                                 if (colon > 0) {\r
200                                                         pass = user.substring(colon + 1);\r
201                                                         user = user.substring(0, colon);\r
202                                                 } else {\r
203                                                         pass = env.getProperty(user);\r
204                                                 }\r
205                                                 \r
206                                                 if (pass != null) {\r
207                                                         pass = env.decrypt(pass, false);\r
208                                                         env.setProperty(user, pass);\r
209                                                         ss = new HBasicAuthSS(user, pass,(SecurityInfoC<HttpURLConnection>) si);\r
210                                                         pw.println("as " + user);\r
211                                                 } else { // get Pass from System Properties, under name of\r
212                                                         // Tag\r
213                                                         pw.println("ERROR: No password set for " + user);\r
214                                                         rv = false;\r
215                                                 }\r
216                                                 continue;\r
217                                         }\r
218                                 } else if ("expect".equalsIgnoreCase(largs[idx])) {\r
219                                         expect.clear();\r
220                                         if (largs.length > idx++) {\r
221                                                 if (!"nothing".equals(largs[idx])) {\r
222                                                         for (String str : largs[idx].split(",")) {\r
223                                                                 try {\r
224                                                                         if ("Exception".equalsIgnoreCase(str)) {\r
225                                                                                 expect.add(-1);\r
226                                                                         } else {\r
227                                                                                 expect.add(Integer.parseInt(str));\r
228                                                                         }\r
229                                                                 } catch (NumberFormatException e) {\r
230                                                                         throw new CadiException("\"expect\" should be followed by Number");\r
231                                                                 }\r
232                                                         }\r
233                                                 ++idx;\r
234                                                 }\r
235                                         }\r
236                                         continue;\r
237                                         // Sleep, typically for reports, to allow DB to update\r
238                                         // Milliseconds\r
239                                         \r
240                                 } else if ("sleep".equalsIgnoreCase(largs[idx])) {\r
241                                         Integer t = Integer.parseInt(largs[++idx]);\r
242                                         pw.println("sleep " + t);\r
243                                         Thread.sleep(t);\r
244                                         ++idx;\r
245                                         continue;\r
246                                 } else if ("delay".equalsIgnoreCase(largs[idx])) {\r
247                                         delay = Integer.parseInt(largs[++idx]);\r
248                                         pw.println("delay " + delay);\r
249                                         ++idx;\r
250                                         continue;\r
251                                 } else if ("pause".equalsIgnoreCase(largs[idx])) {\r
252                                         pw.println("Press <Return> to continue...");\r
253                                         ++idx;\r
254                                         new BufferedReader(new InputStreamReader(System.in)).readLine();\r
255                                         continue;\r
256                                 } else if ("exit".equalsIgnoreCase(largs[idx])) {\r
257                                         pw.println("Exiting...");\r
258                                         return false;\r
259                                 }\r
260 \r
261                         } \r
262                         \r
263                         if("REQUEST".equalsIgnoreCase(largs[idx])) {\r
264                                 request=true;\r
265                                 ++idx;\r
266                         } else if("FORCE".equalsIgnoreCase(largs[idx])) {\r
267                                 force="true";\r
268                                 ++idx;\r
269                         } else if ("set".equalsIgnoreCase(largs[idx])) {\r
270                                 while (largs.length > ++idx) {\r
271                                         int equals = largs[idx].indexOf('=');\r
272                                         if (equals < 0) {\r
273                                                 break;\r
274                                         }\r
275                                         String tag = largs[idx].substring(0, equals);\r
276                                         String value = largs[idx].substring(++equals);\r
277                                         pw.println("set " + tag + ' ' + value);\r
278                                         boolean isTrue = "TRUE".equalsIgnoreCase(value);\r
279                                         if("FORCE".equalsIgnoreCase(tag)) {\r
280                                                 force = value;\r
281                                         } else if("REQUEST".equalsIgnoreCase(tag)) {\r
282                                                 request = isTrue;\r
283                                         } else if("DETAILS".equalsIgnoreCase(tag)) {\r
284                                                 showDetails = isTrue;\r
285                                         } else {\r
286                                                 env.setProperty(tag, value);\r
287                                         }\r
288                                 }\r
289                                 continue;\r
290                                 // Allow Script to indicate if Failure is what is expected\r
291                         }\r
292 \r
293                         int ret = 0;\r
294                         for (Cmd c : cmds) {\r
295                                 if (largs[idx].equalsIgnoreCase(c.getName())) {\r
296                                         if (verbose) {\r
297                                                 pw.println(line);\r
298                                                 if (expect.size() > 0) {\r
299                                                         pw.print("** Expect ");\r
300                                                         boolean first = true;\r
301                                                         for (Integer i : expect) {\r
302                                                                 if (first) {\r
303                                                                         first = false;\r
304                                                                 } else {\r
305                                                                         pw.print(',');\r
306                                                                 }\r
307                                                                 pw.print(i);\r
308                                                         }\r
309                                                         pw.println(" **");\r
310                                                 }\r
311                                         }\r
312                                         try {\r
313                                                 ret = c.exec(++idx, largs);\r
314                                                 if (delay+globalDelay > 0) {\r
315                                                         Thread.sleep(delay+globalDelay);\r
316                                                 }\r
317                                         } catch (Exception e) {\r
318                                                 if (expect.contains(-1)) {\r
319                                                         pw.println(e.getMessage());\r
320                                                         ret = -1;\r
321                                                 } else {\r
322                                                         throw e;\r
323                                                 }\r
324                                         } finally {\r
325                                                 clearSingleLineProperties();\r
326                                         }\r
327                                         rv = expect.isEmpty() ? true : expect.contains(ret);\r
328                                         if (verbose) {\r
329                                                 if (rv) {\r
330                                                         pw.println();\r
331                                                 } else {\r
332                                                         pw.print("!!! Unexpected Return Code: ");\r
333                                                         pw.print(ret);\r
334                                                         pw.println(", VALIDATE OUTPUT!!!");\r
335                                                 }\r
336                                         }\r
337                                         return rv;\r
338                                 }\r
339                         }\r
340                         pw.write("Unknown Instruction \"");\r
341                         pw.write(largs[idx]);\r
342                         pw.write("\"\n");\r
343                         idx = largs.length;// always end after one command\r
344                 }\r
345                 return rv;\r
346         }\r
347 \r
348         private String[] argEval(String line) {\r
349                 StringBuilder sb = new StringBuilder();\r
350                 ArrayList<String> arr = new ArrayList<String>();\r
351                 boolean start = true;\r
352                 char quote = 0;\r
353                 for (int i = 0; i < line.length(); ++i) {\r
354                         char ch;\r
355                         if (Character.isWhitespace(ch = line.charAt(i))) {\r
356                                 if (start) {\r
357                                         continue; // trim\r
358                                 } else if (quote != 0) {\r
359                                         sb.append(ch);\r
360                                 } else {\r
361                                         arr.add(sb.toString());\r
362                                         sb.setLength(0);\r
363                                         start = true;\r
364                                 }\r
365                         } else if (ch == '\'' || ch == '"') { // toggle\r
366                                 if (quote == ch) {\r
367                                         quote = 0;\r
368                                 } else {\r
369                                         quote = ch;\r
370                                 }\r
371                         } else {\r
372                                 start = false;\r
373                                 sb.append(ch);\r
374                         }\r
375                 }\r
376                 if (sb.length() > 0) {\r
377                         arr.add(sb.toString());\r
378                 }\r
379 \r
380                 String[] rv = new String[arr.size()];\r
381                 arr.toArray(rv);\r
382                 return rv;\r
383         }\r
384 \r
385         public static void keyboardHelp() {\r
386                 System.out.println("'C-' means hold the ctrl key down while pressing the next key.");\r
387                 System.out.println("'M-' means hold the alt key down while pressing the next key.");\r
388                 System.out.println("For instance, C-b means hold ctrl key and press b, M-b means hold alt and press b\n");\r
389 \r
390                 System.out.println("Basic Keybindings:");\r
391                 System.out.println("\tC-l - clear screen");        \r
392                 System.out.println("\tC-a - beginning of line");\r
393                 System.out.println("\tC-e - end of line");\r
394                 System.out.println("\tC-b - backward character (left arrow also works)");\r
395                 System.out.println("\tM-b - backward word");\r
396                 System.out.println("\tC-f - forward character (right arrow also works)");\r
397                 System.out.println("\tM-f - forward word");\r
398                 System.out.println("\tC-d - delete character under cursor");\r
399                 System.out.println("\tM-d - delete word forward");\r
400                 System.out.println("\tM-backspace - delete word backward");\r
401                 System.out.println("\tC-k - delete from cursor to end of line");\r
402                 System.out.println("\tC-u - delete entire line, regardless of cursor position\n");\r
403 \r
404                 System.out.println("Command History:");\r
405                 System.out.println("\tC-r - search backward in history (repeating C-r continues the search)");\r
406                 System.out.println("\tC-p - move backwards through history (up arrow also works)");\r
407                 System.out.println("\tC-n - move forwards through history (down arrow also works)\n");\r
408 \r
409         }\r
410 \r
411         /**\r
412          * @param args\r
413          */\r
414         public static void main(String[] args) {\r
415                 int rv = 0;\r
416                 // Cover for bash's need to escape *... (\\*)\r
417                 for (int i = 0; i < args.length; ++i) {\r
418                         if ("\\*".equals(args[i])) {\r
419                                 args[i] = "*";\r
420                         }\r
421                 }\r
422                 \r
423                 System.setProperty("java.util.logging.config.file", "etc/logging.props");\r
424                 final AuthzEnv env = new AuthzEnv(System.getProperties());\r
425                 \r
426                 // Stop the (exceedingly annoying) DME2/other logs from printing console\r
427                 InputStream is;\r
428 \r
429                 // Load Log4j too... sigh\r
430                 is = ClassLoader.getSystemResourceAsStream("log4j.properties");\r
431                 if(is==null) {\r
432                         env.log(Level.WARN, "Cannot find 'log4j.properties' in Classpath.  Best option: add 'etc' directory to classpath");\r
433                 } else {\r
434                         try {\r
435                                 Properties props = new Properties();\r
436                                 props.load(is);\r
437                                 PropertyConfigurator.configure(props);\r
438                         } catch (Exception e) {\r
439                                 e.printStackTrace();\r
440                         } finally {\r
441                                 try {\r
442                                         is.close();\r
443                                 } catch (IOException e) {\r
444                                         env.debug().log(e); // only logging to avoid Sonar False positives.\r
445                                 }\r
446                         }\r
447                 }\r
448 \r
449                 env.loadFromSystemPropsStartsWith("AFT", "DME2", "aaf", "keyfile");\r
450                 try {\r
451                         Log4JLogTarget.setLog4JEnv("aaf", env);\r
452                         GetProp gp = new GetProp(env);\r
453                         String user = gp.get(false,Config.AAF_MECHID,"fully qualified id");\r
454                         String pass = gp.get(true, Config.AAF_MECHPASS, "password is hidden");\r
455                         if(env.getProperty(Config.AAF_URL)==null) {\r
456                                 String p = env.getProperty("DMEServiceName");\r
457                                 if(p!=null) {\r
458                                         boolean https = "true".equalsIgnoreCase(env.getProperty("AFT_DME2_SSL_ENABLE"));\r
459                                         env.setProperty(Config.AAF_URL, "http"+(https?"s":"")+"://DME2RESOLVE/"+p);\r
460                                 }\r
461                         }\r
462                         String aafUrl = gp.get(false, Config.AAF_URL, "https://DME2RESOLVE or Direct URL:port");\r
463 \r
464                         if(aafUrl!=null && aafUrl.contains("//DME2")) {\r
465                                 //gp.set(Config.AFT_LATITUDE,"Lookup from a Map App or table");\r
466                                 //gp.set(Config.AFT_LONGITUDE,"Lookup from a Map App or table");\r
467                                 //gp.set(Config.AFT_ENVIRONMENT,"Check DME2 Installations");\r
468                         }\r
469 \r
470                         if (gp.err() != null) {\r
471                                 gp.err().append("to continue...");\r
472                                 System.err.println(gp.err());\r
473                                 System.exit(1);\r
474                         }\r
475                         \r
476 \r
477                         Reader rdr = null;\r
478                         boolean exitOnFailure = true;\r
479                         /*\r
480                          * Check for "-" options anywhere in command line\r
481                          */\r
482                         StringBuilder sb = new StringBuilder();\r
483                         for (int i = 0; i < args.length; ++i) {\r
484                                 if ("-i".equalsIgnoreCase(args[i])) {\r
485                                         rdr = new InputStreamReader(System.in);\r
486                                         // } else if("-o".equalsIgnoreCase(args[i])) {\r
487                                         // // shall we do something different? Output stream is\r
488                                         // already done...\r
489                                 } else if ("-f".equalsIgnoreCase(args[i])) {\r
490                                         if (args.length > i + 1) {\r
491                                                 rdr = new FileReader(args[++i]);\r
492                                         }\r
493                                 } else if ("-a".equalsIgnoreCase(args[i])) {\r
494                                         exitOnFailure = false;\r
495                                 } else if ("-c".equalsIgnoreCase(args[i])) {\r
496                                         isConsole = true;\r
497                                 } else if ("-s".equalsIgnoreCase(args[i]) && args.length > i + 1) {\r
498                                         env.setProperty(Cmd.STARTDATE, args[++i]);\r
499                                 } else if ("-e".equalsIgnoreCase(args[i]) && args.length > i + 1) {\r
500                                         env.setProperty(Cmd.ENDDATE, args[++i]);\r
501                                 } else if ("-t".equalsIgnoreCase(args[i])) {\r
502                                         isTest = true;\r
503                                 } else if ("-d".equalsIgnoreCase(args[i])) {\r
504                                         showDetails = true;\r
505                                 } else if ("-n".equalsIgnoreCase(args[i])) {\r
506                                         ignoreDelay = true;\r
507                                 } else {\r
508                                         if (sb.length() > 0) {\r
509                                                 sb.append(' ');\r
510                                         }\r
511                                         sb.append(args[i]);\r
512                                 }\r
513                         }\r
514 \r
515                         SecurityInfo si = new SecurityInfo(env);\r
516                         env.loadToSystemPropsStartsWith("AAF", "DME2");\r
517                         Locator loc;\r
518                         if(aafUrl.contains("//DME2RESOLVE")) {\r
519                                 DME2Manager dm = new DME2Manager("AAFcli DME2Manager", System.getProperties());\r
520                                 loc = new DME2Locator(env, dm, aafUrl);\r
521                         } else {\r
522                                 loc = new PropertyLocator(aafUrl);\r
523                         }\r
524 \r
525                         //Config.configPropFiles(new AccessGetter(env), env);\r
526                         \r
527                         TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF));\r
528                         HMangr hman = new HMangr(env, loc).readTimeout(TIMEOUT).apiVersion("2.0");\r
529                         \r
530                         //TODO: Consider requiring a default in properties\r
531                         env.setProperty(Config.AAF_DEFAULT_REALM, System.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));\r
532 \r
533                         AAFcli aafcli = new AAFcli(env, new OutputStreamWriter(System.out), hman, si, \r
534                                 new HBasicAuthSS(user, env.decrypt(pass,false), (SecurityInfoC<HttpURLConnection>) si));\r
535                         if(!ignoreDelay) {\r
536                                 File delay = new File("aafcli.delay");\r
537                                 if(delay.exists()) {\r
538                                         BufferedReader br = new BufferedReader(new FileReader(delay));\r
539                                         try {\r
540                                                 globalDelay = Integer.parseInt(br.readLine());\r
541                                         } catch(Exception e) {\r
542                                                 env.debug().log(e);\r
543                                         } finally {\r
544                                                 br.close();\r
545                                         }\r
546                                 }\r
547                         }\r
548                         try {\r
549                                 if (isConsole) {\r
550                                         System.out.println("Type 'help' for short help or 'help -d' for detailed help with aafcli commands");\r
551                                         System.out.println("Type '?' for help with command line editing");\r
552                                         System.out.println("Type 'q', 'quit', or 'exit' to quit aafcli\n");\r
553 \r
554                                         ConsoleReader reader = new ConsoleReader();\r
555                                         try {\r
556                                                 reader.setPrompt("aafcli > ");\r
557         \r
558                                                 String line;\r
559                                                 while ((line = reader.readLine()) != null) {\r
560                                                         showDetails = (line.contains("-d"))?true:false;\r
561         \r
562                                                         if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("q") || line.equalsIgnoreCase("exit")) {\r
563                                                                 break;\r
564                                                         } else if (line.equalsIgnoreCase("--help -d") || line.equalsIgnoreCase("help -d") \r
565                                                                         || line.equalsIgnoreCase("help")) {\r
566                                                                 line = "--help";\r
567                                                         } else if (line.equalsIgnoreCase("cls")) {\r
568                                                                 reader.clearScreen();\r
569                                                                 continue;\r
570                                                         } else if (line.equalsIgnoreCase("?")) {\r
571                                                                 keyboardHelp();\r
572                                                                 continue;\r
573                                                         }\r
574                                                         try {\r
575                                                                 aafcli.eval(line);\r
576                                                                 pw.flush();\r
577                                                         } catch (Exception e) {\r
578                                                                 pw.println(e.getMessage());\r
579                                                                 pw.flush();\r
580                                                         }\r
581                                                 }\r
582                                         } finally {\r
583                                                 reader.close();\r
584                                         }\r
585                                 } else if (rdr != null) {\r
586                                         BufferedReader br = new BufferedReader(rdr);\r
587                                         String line;\r
588                                         while ((line = br.readLine()) != null) {\r
589                                                 if (!aafcli.eval(line) && exitOnFailure) {\r
590                                                         rv = 1;\r
591                                                         break;\r
592                                                 }\r
593                                         }\r
594                                 } else { // just run the command line\r
595                                         aafcli.verbose(false);\r
596                                         if (sb.length() == 0) {\r
597                                                 sb.append("--help");\r
598                                         }\r
599                                         rv = aafcli.eval(sb.toString()) ? 0 : 1;\r
600                                 }\r
601                         } finally {\r
602                                 aafcli.close();\r
603 \r
604                                 // Don't close if No Reader, or it's a Reader of Standard In\r
605                                 if (rdr != null && !(rdr instanceof InputStreamReader)) {\r
606                                         rdr.close();\r
607                                 }\r
608                         }\r
609                 } catch (MessageException e) {\r
610                         System.out.println("MessageException caught");\r
611 \r
612                         System.err.println(e.getMessage());\r
613                 } catch (Exception e) {\r
614                         e.printStackTrace(System.err);\r
615                 }\r
616                 System.exit(rv);\r
617 \r
618         }\r
619 \r
620         private static class GetProp {\r
621                 private Console cons = System.console();\r
622                 private StringBuilder err = null;\r
623                 private AuthzEnv env;\r
624                 \r
625                 public GetProp(AuthzEnv env) {\r
626                         this.env = env;\r
627                 }\r
628 \r
629                 public String get(final boolean pass, final String tag, final String other)  {\r
630                         String data = env.getProperty(tag,null);\r
631                         if (data == null) {\r
632                                 if(cons!=null) {\r
633                                         if(pass) {\r
634                                                 char[] cp = System.console().readPassword("%s: ",tag);\r
635                                                 if(cp!=null) {\r
636                                                         data=String.valueOf(cp);\r
637                                                 }\r
638                                         } else {\r
639                                                 cons.writer().format("%s: ", tag);\r
640                                                 cons.flush();\r
641                                                 data = cons.readLine();\r
642                                         }\r
643                                 }\r
644                                 if(data==null) {\r
645                                         if(err == null) {\r
646                                                 err  = new StringBuilder("Add -D");\r
647                                         } else {\r
648                                                 err.append(", -D");\r
649                                         }\r
650                                         err.append(tag);\r
651                                         if(other!=null) {\r
652                                                 err.append("=<");\r
653                                                 err.append(other);\r
654                                                 err.append('>');\r
655                                         }\r
656                                 }\r
657                         }\r
658                         return data;\r
659                 }\r
660                 \r
661                 public void set(final String tag, final String other)  {\r
662                         String data = env.getProperty(tag,null);\r
663                         if (data == null) {\r
664                                 if(cons!=null) {\r
665                                         cons.writer().format("%s: ", tag);\r
666                                         cons.flush();\r
667                                         data = cons.readLine();\r
668                                 }\r
669                                 if(data==null) {\r
670                                         if(err == null) {\r
671                                                 err  = new StringBuilder("Add -D");\r
672                                         } else {\r
673                                                 err.append(", -D");\r
674                                         }\r
675                                         err.append(tag);\r
676                                         if(other!=null) {\r
677                                                 err.append("=<");\r
678                                                 err.append(other);\r
679                                                 err.append('>');\r
680                                         }\r
681                                 }\r
682                         }\r
683                         if(data!=null) {\r
684                                 System.setProperty(tag, data);\r
685                         }\r
686                 }\r
687 \r
688                 public StringBuilder err() {\r
689                         return err;\r
690                 }\r
691         }\r
692 \r
693         public boolean isTest() {\r
694                 return AAFcli.isTest;\r
695         }\r
696         \r
697         public boolean isDetailed() {\r
698                 return AAFcli.showDetails;\r
699         }\r
700 \r
701         public String typeString(Class<?> cls, boolean json) {\r
702                 return "application/" + cls.getSimpleName() + "+" + (json ? "json" : "xml") + ";version=" + hman.apiVersion();\r
703         }\r
704 \r
705         public String forceString() {\r
706                 return force;\r
707         }\r
708 \r
709         public boolean addRequest() {\r
710                 return request;\r
711         }\r
712 \r
713         public void clearSingleLineProperties() {\r
714                 force  = null;\r
715                 request = false;\r
716                 showDetails = false;\r
717         }\r
718 \r
719         public void gui(boolean b) {\r
720                 gui  = b;\r
721         }\r
722 \r
723 }\r