// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package net.sourceforge.eclipsejetty.starter.console; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import net.sourceforge.eclipsejetty.starter.console.util.Arguments; /** * Each {@link Command} or list of {@link Command}s will be executed within a process. The process holds the in/out * streams, the arguments and so on. * * @author Manfred Hantschel */ public class Process { private final ConsoleAdapter consoleAdapter; public final Process parent; public final Arguments args; public final InputStream in; public final PrintStream out; public final PrintStream err; private final int result = 0; public Process(ConsoleAdapter consoleAdapter, Process parent, Arguments args, InputStream in, PrintStream out, PrintStream err) { super(); this.consoleAdapter = consoleAdapter; this.parent = parent; this.args = args; this.in = in; this.out = out; this.err = err; } /** * Creates a new process with the same properties, but different streams. * * @param in the in stream * @param out the out stream * @param err the error stream * @return the new process */ public Process redirect(InputStream in, PrintStream out, PrintStream err) { return new Process(consoleAdapter, parent, args, in, out, err); } /** * Execute the process. Parses the arguments and launches the command in the same or a dedicated child process. * * @return the result of the command */ public int execute() { try { int index = args.lastIndexOf(">", ">>", "&"); if (index > 0) { String arg = args.consumeString(index); return new Process(consoleAdapter, this, args.consume(index).add(0, arg), in, out, err).execute(); } return execute(this); } finally { if (err != System.err) { err.close(); } if (out != System.out) { out.close(); } if (in != System.in) { try { in.close(); } catch (IOException e) { // ignore } } } } /** * The result of the command. * * @return the result */ public int getResult() { return result; } /** * Executes the process, handles errors. * * @param process the process to be executed * @return the result of the command */ private static int execute(Process process) { if (process.args.isEmpty()) { return 0; } int result = 0; String commandName = process.args.consumeString(); try { result = execute(process, commandName); } catch (ArgumentException e) { process.err.println(e); } catch (Exception e) { process.err.println("An exception occured:"); e.printStackTrace(process.err); result = -1; } return result; } /** * Executes the specified command using the specified process. * * @param process the process * @param commandName the name of the command * @return the result of the command * @throws Exception on occasion */ private static int execute(Process process, String commandName) throws Exception { Command command = process.consoleAdapter.getCommand(commandName.toLowerCase()); if (command == null) { process.err.printf("Unknown command: %s\n", commandName); process.err.println("Type \"help\" to get help."); return -1; } return command.execute(commandName, process); } }