
org.ow2.frascati.fscript.console.TextConsole Maven / Gradle / Ivy
The newest version!
/**
* OW2 FraSCAti FScript
* Copyright (C) 2009-2010 INRIA, University of Lille 1
*
* This library 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 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: [email protected]
*
* Author: Christophe Demarey
*
* Contributor(s): Philippe Merle
*
*/
package org.ow2.frascati.fscript.console;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Ordering.natural;
import static java.util.Collections.emptySet;
import static java.util.Collections.sort;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.script.Bindings;
import javax.script.SimpleBindings;
import jline.ConsoleReader;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.fscript.FScript;
import org.objectweb.fractal.fscript.FScriptEngine;
import org.objectweb.fractal.fscript.console.Command;
import org.objectweb.fractal.fscript.console.SessionDiagnosticListener;
import org.objectweb.fractal.fscript.diagnostics.DiagnosticListener;
import org.objectweb.fractal.fscript.model.Axis;
import org.objectweb.fractal.fscript.model.Model;
import org.objectweb.fractal.util.Fractal;
import org.ow2.frascati.fscript.FraSCAtiFScript;
import org.ow2.frascati.fscript.console.commands.AbstractCommand;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
/**
* A FraSCAtiScript console ("shell") to manipulate SCA and Fractal architectures interactively on the
* command-line.
*
* @author Christophe Demarey
*/
public class TextConsole
extends org.objectweb.fractal.fscript.console.TextConsole
{
/** The console context. */
private Bindings bindings = null;
/**
* Convenient constructor used to start a console with an
* empty engine context.
* @param fscript The FScript implementation
* @throws IOException
*/
public TextConsole(Component fscript) throws IOException
{
this(fscript, new SimpleBindings());
}
/**
* Default constructor
* @param fscript The FScript implementation
* @param ctx The context to use for this console.
* @throws IOException
*/
public TextConsole(Component fscript, Bindings ctx) throws IOException
{
checkNotNull(fscript);
this.fscript = fscript;
this.bindings = ctx;
this.commands = newHashMap();
registerCommands();
this.console = new ConsoleReader();
register(new QuitCommand());
addCompletors();
BANNER = "FraSCAtiScript console.\n\n" + "Useful commands:\n"
+ "- type ':help' for a list of available commands\n"
+ "- type ':help ' for detailed help on a specific command\n"
+ "- type ':quit' to exit\n\n";
PROMPT = "FraSCAtiScript> ";
}
/**
* Get the command context that will be used to execute this command.
* @return the command context.
*/
public final Bindings getContext()
{
return this.bindings;
}
protected final void registerCommands()
{
// Internal commands
register(new HelpCommand());
Properties commandsConfig = new Properties();
try {
String resourceName = "org/ow2/frascati/fscript/console/commands.properties";
ClassLoader cl = FraSCAtiFScript.getSingleton().getClassLoaderManager().getClassLoader();
InputStream commandsStream = cl.getResourceAsStream(resourceName);
if (commandsStream == null) {
showError("Could not find configuration file " + resourceName + ".");
throw new RuntimeException("Could not find configuration file "
+ resourceName + ".");
}
commandsConfig.load(commandsStream);
} catch (IOException e) {
showError("Could not read commands configuration file.", e);
throw new RuntimeException("Could not read commands configuration file.", e);
}
for (Object o : commandsConfig.keySet()) {
String key = (String) o;
if (key.endsWith(".class")) {
String name = key.substring("command.".length(), key.lastIndexOf('.'));
String klass = commandsConfig.getProperty(key);
String shortDesc = commandsConfig.getProperty("command." + name
+ ".shortDesc");
String longDesc = commandsConfig.getProperty("command." + name
+ ".longDesc");
Command cmd = createCommand(name, klass, shortDesc, longDesc);
if (cmd != null) {
register(cmd);
}
}
}
}
protected final void register(Command cmd)
{
cmd.setSession(this);
cmd.setFScriptEngine(fscript);
this.commands.put(cmd.getName(), cmd);
}
private class QuitCommand
extends AbstractCommand
{
@Override
public final String getName()
{
return "quit";
}
@Override
public final String getShortDescription()
{
return "Quit the console.";
}
@Override
public final String getLongDescription()
{
return getShortDescription();
}
public final void execute(String args) throws Exception
{
TextConsole.this.finished = true;
}
}
protected class HelpCommand
extends AbstractCommand
{
public HelpCommand() {};
@Override
public final String getName()
{
return "help";
}
@Override
public final String getShortDescription()
{
return "Shows a list of available commands.";
}
@Override
public final String getLongDescription()
{
return super.getShortDescription();
}
public final void execute(String args) throws Exception
{
if (args.length() == 0) {
listAvailableCommands();
} else {
String name = args.startsWith(":") ? args.substring(1) : args;
Command cmd = commands.get(name);
if (cmd != null) {
showMessage(cmd.getLongDescription());
} else {
showError("No such command: " + name);
}
}
}
private void listAvailableCommands()
{
showTitle("Available commands");
showMessage("Type ':help ' for more details on a specific command.");
newline();
List sortedCmds = newArrayList(commands.values());
sort(sortedCmds, natural().onResultOf(new Function() {
public final String apply(Command cmd)
{
return cmd.getName();
}
}));
String[][] table = new String[sortedCmds.size() + 1][2];
table[0][0] = "Command";
table[0][1] = "Description";
int i = 0;
for (Command command : sortedCmds) {
table[i + 1][0] = command.toString();
table[i + 1][1] = command.getShortDescription();
i += 1;
}
showTable(table);
}
}
protected class Request
{
private final Command command;
private final String arguments;
public Request(String commandName, String arguments)
{
this.command = commands.get(commandName);
this.arguments = arguments;
}
public final void execute() throws Exception
{
if (command != null) {
command.execute(arguments);
} else {
showError("Invalid request.");
}
}
}
protected final Request parseRequest(String line)
{
if (line == null) {
return new Request("quit", "");
} else if (line.startsWith(":")) {
int i = line.indexOf(' ');
if (i != -1) {
return new Request(line.substring(1, i), line.substring(i + 1));
} else {
return new Request(line.substring(1), "");
}
} else if (line.endsWith(";") || line.contains("{")) {
return new Request("exec", line);
} else {
return new Request("eval", line);
}
}
public final void setFScriptEngine(Component newEngine)
{
this.fscript = newEngine;
for (Command cmd : commands.values()) {
cmd.setFScriptEngine(this.fscript);
}
}
public final void setSessionInterpreter(Component fscript)
{
for (Command cmd : commands.values()) {
cmd.setFScriptEngine(fscript);
}
}
public final DiagnosticListener getDiagnosticListener()
{
return new SessionDiagnosticListener(this);
}
public final void processRequest(String line) throws Exception
{
if (line != null && line.length() == 0) {
return;
}
Request request = parseRequest(line);
if (request != null) {
request.execute();
}
}
public final Set getGlobalVariablesNames()
{
FScriptEngine engine = FScript.getFScriptEngine(fscript);
return engine.getGlobals();
}
public final Set getAxesNames()
{
Model model = getModel();
if (model != null) {
Set axes = model.getAxes();
Set names = new HashSet();
for (Axis axis : axes) {
names.add(axis.getName());
}
return names;
} else {
return emptySet();
}
}
protected final Model getModel()
{
try {
for (Component c : Fractal.getContentController(fscript).getFcSubComponents()) {
String name = Fractal.getNameController(c).getFcName();
if ("model".equals(name)) {
return (Model) c.getFcInterface("model");
}
}
return null;
} catch (Exception e) {
showWarning("Incompatible FScript implementation.");
showWarning("Axis name completion disabled.");
return null;
}
}
public final Set getCommandNames()
{
return commands.keySet();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy