info.informationsea.commandmanager.cli.CLICommandManager Maven / Gradle / Ivy
/*
CommandManager : manage commands
Copyright (C) 2015 Yasunobu OKAMURA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
package info.informationsea.commandmanager.cli;
import info.informationsea.commandmanager.core.CommandManager;
import info.informationsea.commandmanager.core.CommandResult;
import info.informationsea.commandmanager.core.ManagedCommand;
import jline.console.ConsoleReader;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineParser;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Command Manager for Command Line Interface.
*
* This command manager provides two built-in commands, "help" and "source". "help" command shows usage of commands.
* "source" command read a script file and run commands.
* @author Yasunobu OKAMURA
*/
@Slf4j
public class CLICommandManager extends CommandManager {
/**
* Default constructor
*/
public CLICommandManager() {
addCommand("help", CLIHelpCommand.class);
addCommand("source", CLISourceCommand.class);
}
/**
* Execute commands in the raw line. The raw line will be parsed with {@code ShellParser}.
* @param line commands. Commands should be separated by ';'
* @throws Exception Commands may throw Exception.
*/
public void executeMany(String line) throws Exception {
List args = ShellParser.parseShellLine(line);
executeMany(args.toArray(new String[args.size()]));
}
/**
* Execute commands in the parsed arguments.
* @param args commands. Commands should be separated by ';'
* @throws Exception Commands may throw Exception.
*/
public void executeMany(String[] args) throws Exception {
int startPos = 0;
for (int i = 0; i < args.length; i++) {
if (args[i].equals(";")) {
String[] newArgs = new String[i-startPos];
System.arraycopy(args, startPos, newArgs, 0, i-startPos);
//log.info("run {}", (Object) newArgs);
execute(newArgs);
startPos = i+1;
}
}
String[] newArgs = new String[args.length-startPos];
System.arraycopy(args, startPos, newArgs, 0, args.length-startPos);
//log.info("run last {}", (Object) newArgs);
execute(newArgs);
}
/**
* Execute a commands in the raw line. The raw line will be parsed with {@code ShellParser}.
* @param line a command and its arguments.
* @throws Exception A command may throw Exception.
*/
public void execute(String line) throws Exception {
List args = ShellParser.parseShellLine(line);
execute(args.toArray(new String[args.size()]));
}
/**
* Execute a commands in the string array.
* @param args a command and its arguments.
* @throws Exception A command may throw Exception.
*/
public void execute(String[] args) throws Exception {
ManagedCommand managedCommand = getConfiguredCommandInstance(args);
if (managedCommand == null) {
throw new IllegalArgumentException("Command is not found");
}
CommandResult result = managedCommand.execute();
if (result.getResult() != null) {
System.out.println(result.getResult());
}
}
/**
* Get a configured commands in the raw line.
* Parameters of a command are configured with arguments.
* The raw line will be parsed with {@code ShellParser}.
* @param line a command and its arguments.
* @throws Exception A argument parser may throw Exception.
*/
public ManagedCommand getConfiguredCommandInstance(String line) throws Exception {
List args = ShellParser.parseShellLine(line);
return getConfiguredCommandInstance(args.toArray(new String[args.size()]));
}
/**
* Get a configured commands with a string array.
* Parameters of a command are configured with arguments.
* @param args a command and its arguments.
* @throws Exception A argument parser may throw Exception.
*/
public ManagedCommand getConfiguredCommandInstance(String[] args) throws Exception {
ManagedCommand command = getCommandInstance(args[0]);
String[] commandArgs = new String[args.length-1];
System.arraycopy(args, 1, commandArgs, 0, args.length - 1);
CmdLineParser parser = new CmdLineParser(command);
parser.parseArgument(commandArgs);
if (command instanceof CLIBuiltinCommand) {
((CLIBuiltinCommand) command).setCommandManager(this);
}
return command;
}
/**
* Load a script from a reader and execute.
* @param reader script reader
* @throws Exception commands may throw Exception
*/
public void loadScript(Reader reader) throws Exception{
try (BufferedReader bufferedReader = new BufferedReader(reader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
executeMany(line);
}
}
}
/**
* Start console interface with the default console reader
* @throws IOException console reade may throw IOException
*/
public void startConsole() throws IOException {
startConsole(new ConsoleReader());
}
/**
* Start console interface with consoleReader
* @param consoleReader terminal console reader
* @throws IOException console reade may throw IOException
*/
public void startConsole(ConsoleReader consoleReader) throws IOException {
consoleReader.addCompleter(new CLICommandCompleter(this));
String line;
out : while ((line = consoleReader.readLine("> ")) != null) {
List args = ShellParser.parseShellLine(line);
if (args.size() == 0) continue;
switch (args.get(0)) {
case "clear":
consoleReader.clearScreen();
break;
case "exit":
break out;
default:
try {
execute(args.toArray(new String[args.size()]));
} catch (Exception e) {
log.info("Execute Error", e);
}
}
}
}
/**
* Super class of CLI command manager built-in commands
*/
public abstract static class CLIBuiltinCommand implements ManagedCommand {
@Setter @Getter
protected CLICommandManager commandManager;
}
public static class CLIHelpCommand extends CLIBuiltinCommand {
@Argument
private String command = null;
@Override
public CommandResult execute() throws Exception {
StringBuilder builder = new StringBuilder();
if (command == null) {
System.err.println("Command List:");
for (String one : commandManager.getCommands().keySet()) {
builder.append(String.format(" %s\n", one));
}
for (String one : new String[]{"exit", "clear", "source"}) {
builder.append(String.format(" %s\n", one));
}
} else {
switch (command) {
case "exit":
builder.append("exit : exit this program\n");
break;
case "clear":
builder.append("clear : clear screen\n");
break;
case "source":
builder.append("source FILE: load script\n");
break;
default:
CmdLineParser parser = new CmdLineParser(commandManager.getCommandInstance(command));
builder.append(command).append(" ");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(outputStream);
parser.printSingleLineUsage(ps);
ps.println();
parser.printUsage(ps);
builder.append(outputStream.toString("utf-8"));
}
}
return new CommandResult(builder.toString(), CommandResult.ResultState.SUCCESS);
}
@Override
public List getCandidateForArgument(int index) {
if (index == 0) {
ArrayList list = new ArrayList<>();
list.addAll(commandManager.getCommands().keySet());
list.add("exit");
list.add("clear");
list.add("source");
return list;
}
return null;
}
}
public static class CLISourceCommand extends CLIBuiltinCommand {
@Argument (required = true)
private File source;
@Override
public CommandResult execute() throws Exception {
commandManager.loadScript(new FileReader(source));
return new CommandResult(null, CommandResult.ResultState.SUCCESS);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy