package com.sas.unravl; import com.sas.unravl.ui.UnRAVLFrame; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Properties; /** * The main command-line interface for running {@link UnRAVL} scripts. You can * run via <code>bin/unravl.sh</code> (Linux, Mac OS X) or * <code>bin\\unravl.bat</code> (Windows) Below, <code>unravl</code> refers to * the correct script for you environment * * <pre> * unravl script-file [... script-file] * </pre> * * Each argument on the command line names an UnRAVL script file Each such file * may contain the JSON representation of a script, or a script suite, which is * a JSON array of UnRAVL scripts. * <p> * By default, unravl has a built-in Log4j configuration file, which has tracing * enabled for the com.sas.unravl package, but you can pass your own by setting * UNRAVL_OPT: * * <pre> * UNRAVL_OPT="-Djog4j.configuration=mylog4j.properties" unravl script-file * </pre> * * You can also use this UNRAVL_OPT if you want to pass initial variable * bindings for the {@link UnRAVLRuntime} environment. See the unravl.sh * * <pre> * UNRAVL_OPT="-Dvar1=value1 -Dvar2=value2" unravl script.json * </pre> * * @author David.Biesack@sas.com */ public final class Main { /** * Man entry point. Each command line argument <em>script-file</em> is the * name of an UnRAVL script file or URL. All scripts will run in the same * shared UnRAVLRuntime and thus share a common environment and set of * variables. * * @param argv * commmand line arguments */ public static void main(String argv[]) { argv = preProcessArgs(argv); rerouteStdoutStderr(); // do this before starting Log4J! configureLog4j(); UnRAVLRuntime.configure(); if (ui) { javax.swing.JFrame frame = UnRAVLFrame.main(redirectOutput); frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); } else { int rc = new Main().run(argv); System.exit(rc); } } static boolean ui = false; static boolean redirectOutput = true; // Scan for --v | -verbose | -q | --quiet | --stdout and set the log4j configuration // remove those args from the arg list and return the remainder // Print help and exit on -h | --help options. private static String[] preProcessArgs(String[] argv) { ArrayList<String> args = new ArrayList<String>(); String log4j = null; ui = true; for (String arg : argv) { if (arg.trim().length() == 0) // Ignore "" on command line continue; else if (arg.matches("^--?h(elp)?")) usage(); else if (arg.matches("^--?q(uiet)?")) log4j = "log4j-quiet.properties"; else if (arg.matches("^--?v(erbose)?")) log4j = "log4j-trace.properties"; else if (arg.matches("^--?stdout")) redirectOutput = false; else { args.add(arg); ui = false; } } if (log4j != null) System.setProperty("log4j.configuration", log4j); return args.toArray(new String[args.size()]); } private static void usage() { System.out.println("UnRAVL - Uniform REST API Validation Language"); System.out.println("Runs one or more UnRAVL script files, which are JSON executable REST API validation specifications."); System.out.println(""); System.out.println("Synopsis:"); System.out.println(""); System.out.println(" unravl.sh [-q|--quiet|-v|--verbose|-h|--help] <script-file>"); System.out.println(""); System.out.println("Examples:"); System.out.println(""); System.out.println(" unravl.sh --verbose hello.json"); System.out.println(" unravl.sh -q hello.json"); System.out.println(""); System.out.println("Options:"); System.out.println(" -q | --quiet : decrease the logging level."); System.out.println(" -v | --verbose : increase the logging level."); System.out.println(" -h | --help : Display this message and exit."); System.out.println(" --stdout : In interactive mode, write output to the standard output, not the Output panel."); System.out.println(""); System.out.println("If you do not specify any <script-file> options, start UnRAVL in"); System.out.println("interactive mode, from which you can edit and execute scripts."); System.out.println("This requires a window system."); System.out.println(""); System.out.println("See http://www.github.com/sassoftware/unravl"); System.exit(1); } // Manage stdout/stderr which UnRAVLFrame can redirect to a UI text component // such that we can route Log4j console output to the text component private static RedirectedOutputStream out; private static RedirectedOutputStream err; /** * An OutputStream that proxies to a PrintStream, allowing dynamic redirection */ public static class RedirectedOutputStream extends OutputStream { private PrintStream original; public void redirect(PrintStream ps) { original = ps; } public RedirectedOutputStream(PrintStream original) { this.original = original; } @Override public void write(int byt) throws IOException { original.write(byt); } } private static void rerouteStdoutStderr() { out = new RedirectedOutputStream(System.out); System.setOut(new PrintStream(out)); err = new RedirectedOutputStream(System.err); System.setErr(new PrintStream(err)); } public static void setOut(PrintStream os) { out.redirect(os); } public static void setErr(PrintStream os) { err.redirect(os); } private static void configureLog4j() { if (System.getProperty("log4j.configuration") == null) { try { Properties properties = new Properties(); properties.load(Main.class .getResourceAsStream("/log4j.properties")); org.apache.log4j.PropertyConfigurator.configure(properties); } catch (IOException e) { System.err.println("Could not load log4j config"); System.exit(1); } } else { org.apache.log4j.BasicConfigurator.configure(); } } public int run(String argv[]) { UnRAVLRuntime runtime = new UnRAVLRuntime(); try { return runtime.execute(argv).report(); } catch (UnRAVLException e) { int rc = runtime.report(); return rc != 0 ? rc : 1; } catch (Throwable t) { System.err.println(t.getMessage()); int rc = runtime.report(); t.printStackTrace(System.err); return rc != 0 ? rc : 1; } } }