1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.jshell.tool;
  27 
  28 import java.io.InputStream;
  29 import java.io.PrintStream;
  30 import java.util.Locale;
  31 import java.util.Map;
  32 import java.util.prefs.Preferences;
  33 import jdk.internal.jshell.tool.JShellToolBuilder;
  34 
  35 /**
  36  * Interface to configure and run a Java shell tool instance. An instance of the
  37  * builder is created with the static {@link #builder} method. This builder can,
  38  * optionally, be configured with the configuration methods. All configuration
  39  * methods return the builder instance for use in chained initialization. All
  40  * configuration methods have sensible defaults which will be used if they are
  41  * not called.. After zero or more calls to configuration methods, the tool is
  42  * launched with a call to {@link #run(java.lang.String...) }.
  43  *
  44  * @since 9
  45  */
  46 public interface JavaShellToolBuilder {
  47 
  48     /**
  49      * Create a builder for launching the JDK jshell tool.
  50      *
  51      * @return a builder which can be used to configure and launch the jshell
  52      * tool
  53      */
  54     static JavaShellToolBuilder builder() {
  55         return new JShellToolBuilder();
  56     }
  57 
  58     /**
  59      * Set the input channels.
  60      *
  61      * @implSpec If this method is not called, the behavior should be
  62      * equivalent to calling {@code in(System.in, null)}.
  63      *
  64      * @param cmdIn source of command input
  65      * @param userIn source of input for running user code, or {@code null} to
  66      * extract user input from cmdIn
  67      * @return the {@code JavaShellToolBuilder} instance
  68      */
  69     JavaShellToolBuilder in(InputStream cmdIn, InputStream userIn);
  70 
  71     /**
  72      * Set the output channels. Same as {@code out(output, output, output)}.
  73      *
  74      * @implSpec If neither {@code out} method is called, the behavior should be
  75      * equivalent to calling {@code out(System.out)}.
  76      *
  77      * @param output destination of command feedback, console interaction, and
  78      * user code output
  79      * @return the {@code JavaShellToolBuilder} instance
  80      */
  81     JavaShellToolBuilder out(PrintStream output);
  82 
  83     /**
  84      * Set the output channels.
  85      *
  86      * @implSpec If neither {@code out} method is called, the behavior should be
  87      * equivalent to calling {@code out(System.out, System.out, System.out)}.
  88      *
  89      * @param cmdOut destination of command feedback including error messages
  90      * for users
  91      * @param console destination of console interaction
  92      * @param userOut destination of user code output.  For example, user snippet
  93      * {@code System.out.println("Hello")} when executed {@code Hello} goes to
  94      * userOut.
  95      * @return the {@code JavaShellToolBuilder} instance
  96      */
  97     JavaShellToolBuilder out(PrintStream cmdOut, PrintStream console, PrintStream userOut);
  98 
  99     /**
 100      * Set the error channels. Same as {@code err(error, error)}.
 101      *
 102      * @implSpec If neither {@code err} method is called, the behavior should be
 103      * equivalent to calling {@code err(System.err)}.
 104      *
 105      * @param error destination of tool errors, and
 106      * user code errors
 107      * @return the {@code JavaShellToolBuilder} instance
 108      */
 109     JavaShellToolBuilder err(PrintStream error);
 110 
 111     /**
 112      * Set the error channels.
 113      *
 114      * @implSpec If neither {@code err} method is called, the behavior should be
 115      * equivalent to calling {@code err(System.err, System.err, System.err)}.
 116      *
 117      * @param cmdErr destination of tool start-up and fatal errors
 118      * @param userErr destination of user code error output.
 119      * For example, user snippet  {@code System.err.println("Oops")}
 120      * when executed {@code Oops} goes to userErr.
 121      * @return the {@code JavaShellToolBuilder} instance
 122      */
 123     JavaShellToolBuilder err(PrintStream cmdErr, PrintStream userErr);
 124 
 125     /**
 126      * Set the storage mechanism for persistent information which includes
 127      * input history and retained settings.
 128      *
 129      * @implSpec If neither {@code persistence} method is called, the behavior
 130      * should be to use the tool's standard persistence mechanism.
 131      *
 132      * @param prefs an instance of {@link java.util.prefs.Preferences} that
 133      * is used to retrieve and store persistent information
 134      * @return the {@code JavaShellToolBuilder} instance
 135      */
 136     JavaShellToolBuilder persistence(Preferences prefs);
 137 
 138     /**
 139      * Set the storage mechanism for persistent information which includes
 140      * input history and retained settings.
 141      *
 142      * @implSpec If neither {@code persistence} method is called, the behavior
 143      * should be to use the tool's standard persistence mechanism.
 144      *
 145      * @param prefsMap  an instance of {@link java.util.Map} that
 146      * is used to retrieve and store persistent information
 147      * @return the {@code JavaShellToolBuilder} instance
 148      */
 149     JavaShellToolBuilder persistence(Map<String,String> prefsMap);
 150 
 151     /**
 152      * Set the source for environment variables.
 153      *
 154      * @implSpec If this method is not called, the behavior should be
 155      * equivalent to calling {@code env(System.getenv())}.
 156      *
 157      * @param vars the Map of environment variable names to values
 158      * @return the {@code JavaShellToolBuilder} instance
 159      */
 160     JavaShellToolBuilder env(Map<String,String> vars);
 161 
 162     /**
 163      * Set the locale.
 164      *
 165      * @implSpec If this method is not called, the behavior should be
 166      * equivalent to calling {@code locale(Locale.getDefault())}.
 167      *
 168      * @param locale the locale
 169      * @return the {@code JavaShellToolBuilder} instance
 170      */
 171     JavaShellToolBuilder locale(Locale locale);
 172 
 173     /**
 174      * Set to enable a command capturing prompt override.
 175      *
 176      * @implSpec If this method is not called, the behavior should be
 177      * equivalent to calling {@code promptCapture(false)}.
 178      *
 179      * @param capture if {@code true}, basic prompt is the {@code ENQ}
 180      * character and continuation prompt is the {@code ACK} character.
 181      * If false, prompts are as set with set-up or user {@code /set} commands.
 182      * @return the {@code JavaShellToolBuilder} instance
 183      */
 184     JavaShellToolBuilder promptCapture(boolean capture);
 185 
 186     /**
 187      * Run an instance of the Java shell tool as configured by the other methods
 188      * in this interface.  This call is not destructive, more than one call of
 189      * this method may be made from a configured builder. The  exit code from
 190      * the Java shell tool is ignored.
 191      *
 192      * @param arguments the command-line arguments (including options), if any
 193      * @throws Exception an unexpected fatal exception
 194      */
 195     void run(String... arguments) throws Exception;
 196     
 197     
 198     /**
 199      * Run an instance of the Java shell tool as configured by the other methods
 200      * in this interface.  This call is not destructive, more than one call of
 201      * this method may be made from a configured builder.
 202      * 
 203      * @implSpec The default implementation always returns zero. Implementations
 204      * of this interface should override this method, returning the exit status.
 205      *
 206      * @param arguments the command-line arguments (including options), if any
 207      * @throws Exception an unexpected fatal exception
 208      * @return the exit status with which the tool explicitly exited (if any),
 209      * otherwise 0 for success or 1 for failure
 210      */
 211     default int start(String... arguments) throws Exception {
 212         run(arguments);
 213         return 0;
 214     }
 215 }