1 /*
   2  * Copyright (c) 2002-2012, the original author or authors.
   3  *
   4  * This software is distributable under the BSD license. See the terms of the
   5  * BSD license in the documentation provided with this software.
   6  *
   7  * http://www.opensource.org/licenses/bsd-license.php
   8  */
   9 package jdk.internal.jline.console.internal;
  10 
  11 import jdk.internal.jline.console.ConsoleReader;
  12 import jdk.internal.jline.console.completer.ArgumentCompleter;
  13 import jdk.internal.jline.console.completer.Completer;
  14 import jdk.internal.jline.console.history.FileHistory;
  15 import jdk.internal.jline.internal.Configuration;
  16 
  17 import java.io.File;
  18 import java.lang.reflect.Method;
  19 import java.util.ArrayList;
  20 import java.util.Arrays;
  21 import java.util.List;
  22 import java.util.StringTokenizer;
  23 
  24 // FIXME: Clean up API and move to jline.console.runner package
  25 
  26 /**
  27  * A pass-through application that sets the system input stream to a
  28  * {@link ConsoleReader} and invokes the specified main method.
  29  *
  30  * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
  31  * @since 2.7
  32  */
  33 public class ConsoleRunner
  34 {
  35     public static final String property = "jline.history";
  36 
  37     // FIXME: This is really ugly... re-write this
  38 
  39     public static void main(final String[] args) throws Exception {
  40         List<String> argList = new ArrayList<String>(Arrays.asList(args));
  41         if (argList.size() == 0) {
  42             usage();
  43             return;
  44         }
  45 
  46         String historyFileName = System.getProperty(ConsoleRunner.property, null);
  47 
  48         String mainClass = argList.remove(0);
  49         ConsoleReader reader = new ConsoleReader();
  50 
  51         if (historyFileName != null) {
  52             reader.setHistory(new FileHistory(new File(Configuration.getUserHome(),
  53                 String.format(".jline-%s.%s.history", mainClass, historyFileName))));
  54         }
  55         else {
  56             reader.setHistory(new FileHistory(new File(Configuration.getUserHome(),
  57                 String.format(".jline-%s.history", mainClass))));
  58         }
  59 
  60         String completors = System.getProperty(ConsoleRunner.class.getName() + ".completers", "");
  61         List<Completer> completorList = new ArrayList<Completer>();
  62 
  63         for (StringTokenizer tok = new StringTokenizer(completors, ","); tok.hasMoreTokens();) {
  64             Object obj = Class.forName(tok.nextToken()).newInstance();
  65             completorList.add((Completer) obj);
  66         }
  67 
  68         if (completorList.size() > 0) {
  69             reader.addCompleter(new ArgumentCompleter(completorList));
  70         }
  71 
  72         ConsoleReaderInputStream.setIn(reader);
  73 
  74         try {
  75             Class<?> type = Class.forName(mainClass);
  76             Method method = type.getMethod("main", String[].class);
  77             method.invoke(null);
  78         }
  79         finally {
  80             // just in case this main method is called from another program
  81             ConsoleReaderInputStream.restoreIn();
  82         }
  83     }
  84 
  85     private static void usage() {
  86         System.out.println("Usage: \n   java " + "[-Djline.history='name'] "
  87             + ConsoleRunner.class.getName()
  88             + " <target class name> [args]"
  89             + "\n\nThe -Djline.history option will avoid history"
  90             + "\nmangling when running ConsoleRunner on the same application."
  91             + "\n\nargs will be passed directly to the target class name.");
  92     }
  93 }