/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.cli.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jboss.aesh.complete.CompleteOperation;
import org.jboss.aesh.complete.Completion;
import org.jboss.aesh.console.ConsoleCallback;
import org.jboss.aesh.console.Prompt;
import org.jboss.aesh.console.settings.Settings;
import org.jboss.aesh.parser.Parser;
import org.jboss.as.cli.CliInitializationException;
import org.jboss.as.cli.CommandContext;
import org.jboss.as.cli.CommandHistory;
import org.jboss.as.cli.CommandLineCompleter;
/**
*
* @author Alexey Loubyansky
*/
public interface Console {
void addCompleter(CommandLineCompleter completer);
boolean isUseHistory();
CommandHistory getHistory();
void setCompletion(boolean complete);
void clearScreen();
void printColumns(Collection<String> list);
void print(String line);
void printNewLine();
String readLine(String prompt);
String readLine(String prompt, Character mask);
int getTerminalWidth();
int getTerminalHeight();
/**
* Checks whether the tab-completion is enabled.
*
* @return true if tab-completion is enabled, false - otherwise
*/
boolean isCompletionEnabled();
/**
* Enables or disables the tab-completion.
*
* @param completionEnabled true will enable the tab-completion, false will disable it
*/
// void setCompletionEnabled(boolean completionEnabled);
/**
* Interrupts blocking readLine method.
*
* Added as solution to BZ-1149099.
*/
void interrupt();
void controlled();
boolean isControlled();
void continuous();
void setCallback(ConsoleCallback consoleCallback);
void start();
void stop();
boolean running();
void setPrompt(String prompt);
void setPrompt(String prompt, Character mask);
void redrawPrompt();
static final class Factory {
public static Console getConsole(CommandContext ctx, Settings settings) throws CliInitializationException {
return getConsole(ctx, null, null, settings);
}
public static Console getConsole(final CommandContext ctx, InputStream is, OutputStream os, final Settings settings) throws CliInitializationException {
org.jboss.aesh.console.Console aeshConsole = null;
try {
aeshConsole = new org.jboss.aesh.console.Console(settings);
} catch (Throwable e) {
throw new CliInitializationException("Failed to initialize Aesh console", e);
}
final org.jboss.aesh.console.Console finalAeshConsole = aeshConsole;
Console console = new Console() {
private CommandContext cmdCtx = ctx;
private org.jboss.aesh.console.Console console = finalAeshConsole;
private CommandHistory history = new HistoryImpl();
private boolean controlled;
@Override
public void addCompleter(final CommandLineCompleter completer) {
console.addCompletion(new Completion() {
@Override
public void complete(CompleteOperation co) {
List<String> candidates = new ArrayList<>();
int offset = completer.complete(cmdCtx,
co.getBuffer(), co.getCursor(), candidates);
co.setOffset(offset);
co.setCompletionCandidates(candidates);
String buffer = cmdCtx.getArgumentsString() == null ? co.getBuffer() : ctx.getArgumentsString() + co.getBuffer();
if (co.getCompletionCandidates().size() == 1
&& co.getCompletionCandidates().get(0).getCharacters().startsWith(buffer))
co.doAppendSeparator(true);
else
co.doAppendSeparator(false);
}
});
}
@Override
public boolean isUseHistory() {
return !settings.isHistoryDisabled();
}
@Override
public CommandHistory getHistory() {
return history;
}
@Override
public void setCompletion(boolean complete){
console.setCompletionEnabled(complete);
}
@Override
public void clearScreen() {
try {
console.clear();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void printColumns(Collection<String> list) {
String[] newList = new String[list.size()];
list.toArray(newList);
console.getShell().out().println(
Parser.formatDisplayList(newList,
console.getTerminalSize().getHeight(),
console.getTerminalSize().getWidth()));
}
@Override
public void print(String line) {
console.getShell().out().print(line);
}
@Override
public void printNewLine() {
console.getShell().out().println();
}
@Override
public String readLine(String prompt) {
return read(prompt, null);
}
@Override
public String readLine(String prompt, Character mask) {
return read(prompt, mask);
}
private String read(String prompt, Character mask) {
int PID = -1;
try {
ConsoleCallback callback = console.getConsoleCallback();
if (callback instanceof CommandContextImpl.CLIAeshConsoleCallback) {
CommandContextImpl.CLIAeshConsoleCallback cliCallback = ((CommandContextImpl.CLIAeshConsoleCallback) callback);
if (cliCallback.hasActiveProcess()) {
PID = cliCallback.getProcessPID();
console.putProcessInBackground(PID);
}
}
Prompt origPrompt = null;
if(!console.getPrompt().getPromptAsString().equals(prompt)) {
origPrompt = console.getPrompt();
console.setPrompt(new Prompt(prompt, mask));
redrawPrompt();
}
try {
return console.getInputLine();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} finally {
if(origPrompt != null) {
console.setPrompt(origPrompt);
}
}
} finally {
if( PID != -1) {
console.putProcessInForeground(PID);
}
}
}
@Override
public int getTerminalWidth() {
return console.getTerminalSize().getWidth();
}
@Override
public int getTerminalHeight() {
return console.getTerminalSize().getHeight();
}
@Override
public boolean isCompletionEnabled(){
return settings.isCompletionDisabled();
}
@Override
public void interrupt() {
}
@Override
public void controlled() {
console.controlled();
controlled = true;
}
@Override
public void continuous() {
console.continuous();
controlled = false;
}
@Override
public boolean isControlled() {
return controlled;
}
@Override
public void setCallback(ConsoleCallback consoleCallback) {
if(console != null)
console.setConsoleCallback(consoleCallback);
}
@Override
public void start(){
if(console != null)
console.start();
}
@Override
public void stop() {
if(console != null) {
console.stop();
}
}
@Override
public boolean running() {
return console != null && (console.isRunning() || console.hasRunningProcesses());
}
@Override
public void setPrompt(String prompt){
setPrompt(prompt, null);
}
@Override
public void setPrompt(String prompt, Character mask) {
if(!prompt.equals(console.getPrompt().getPromptAsString())) {
console.setPrompt(new Prompt(prompt, mask));
}
}
@Override
public void redrawPrompt() {
console.clearBufferAndDisplayPrompt();
}
class HistoryImpl implements CommandHistory {
@Override
public List<String> asList() {
return console.getHistory().getAll();
}
@Override
public boolean isUseHistory() {
return console.getHistory().isEnabled();
}
@Override
public void setUseHistory(boolean useHistory) {
if(useHistory){
console.getHistory().enable();
}else{
console.getHistory().disable();
}
}
@Override
public void clear() {
console.getHistory().clear();
}
@Override
public int getMaxSize() {
return settings.getHistorySize();
}
}
};
return console;
}
}
}