blob: 72c48f0ced317d51268336fdaa5b9cb03b1d139e [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation
*
* 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 org.apache.felix.mishell.console;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptContext;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import org.apache.felix.mishell.EngineNotFoundException;
import org.apache.felix.mishell.JMXEngineContext;
public class Console implements Runnable{
public static final String DEFAULT_LANGUAGE = "javascript";
Logger log = Logger.getLogger(this.getClass().getCanonicalName());
Level l=Level.FINEST;
private String language=DEFAULT_LANGUAGE;
private String prompt;
BufferedReader in;
PrintStream out;
private Commander commander;
private boolean stop = false;
private JMXEngineContext engineContext;
public Console(JMXEngineContext engineContext) throws IOException{
this.engineContext=engineContext;
prompt="mishell."+engineContext.getLanguage()+"$ ";
in=new BufferedReader(new InputStreamReader(System.in));
out=System.out;
commander= new Commander();
addBuiltInCmds();
stop=false;
}
private void setLanguage(String name)throws EngineNotFoundException{
engineContext.setLanguage(name);
language=engineContext.getEngine().getFactory().getLanguageName();
prompt="mishell."+language+"$ ";
}
public void run() {
try {
out.println("Welcome to Apache Mishell!!");
out.println("For getting help type 'help' ");
out.print(prompt);
while (!stop) {
try {
String cmd = in.readLine();
executeCommand(cmd);
out.print(prompt);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop() {
stop = true;
}
public void executeCommand(String cmd) {
try {
commander.executeCommand(cmd, out);
} catch (CommandNotFoundException e) {
try {
Object result=engineContext.getEngine().eval(cmd);
if(result==null)return;
else out.println(language+": "+result);
} catch (ScriptException se) {
out.println(se.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void addCommand(Command cmd){
commander.add(cmd);
}
/**
* This method is needed for non-trivial commands that could eventually be added, as
* they will need to use the engineContext to do useful things
* @return
*/
public JMXEngineContext getEngineContext(){
return engineContext;
}
private void addBuiltInCmds(){
commander.add(new Command(){
public void executeCommand(String cmd, PrintStream out) throws Exception {
Set<Entry<String, Object>> bindings= engineContext.getEngine().getContext().getBindings(ScriptContext.ENGINE_SCOPE).entrySet();
for (Entry<String, Object> entry : bindings) {
out.println(entry.getKey()+" ["+entry.getValue().getClass().getName()+"]\n");
}
}
public String getName() {
return "browse";
}
public String getHelp() {
return "prints the bindings for current engine";
}
});
commander.add(new Command(){
public void executeCommand(String cmd, PrintStream out) throws Exception {
out.println("exiting console.");
stop=true;
}
public String getName() {
return "exit";
}
public String getHelp() {
return "exit this console";
}
});
commander.add(new Command(){
public void executeCommand(String cmd, PrintStream out) throws Exception {
String[] args=cmd.split(" ");//TODO implement scape seqs, that is, if path contains spaces, for example.
if(args.length>1){
setLanguage(args[1]);
} else{
for (ScriptEngineFactory factory: engineContext.getEngineManager().getEngineFactories()) {
out.print(factory.getLanguageName()+"; version "+factory.getLanguageVersion());
out.print("; AKA: ");
for(String alias: factory.getNames()) out.print(alias+" ");
out.print("\n");
}
}
}
public String getName() {
return "language";
}
public String getHelp() {
return "language [languageName]. Changes current language, or prints available ones";
}
});
commander.add(new Command(){
public void executeCommand(String cmd, PrintStream out) throws Exception {
for (Command c : commander) {
out.println(c.getName()+": "+c.getHelp());
}
}
public String getName() {
return "help";
}
public String getHelp() {
return "Prints this help";
}
});
commander.add(new Command(){
public void executeCommand(String cmd, PrintStream out) throws Exception {
String[] args=cmd.split(" ");
if(args.length<2 || args.length>3) {
out.println(this.getHelp());
return;
}
Reader reader;
if (args.length==2) {
try {
reader=new FileReader(args[1]);
} catch(FileNotFoundException fne) {
out.println("Invalid path: "+args[1]);
return;
}
if(args.length==3 && (args[1].equals("-r")||args[1].equals("--remote"))) {
try {
URL url=new URL(args[2]);
reader=new InputStreamReader(url.openStream());
} catch (MalformedURLException mue) {
out.println("bad url");
return;
}
}
try {
engineContext.getEngine().eval(reader);
} catch (ScriptException se) {
out.println(se.getMessage());
}
}
}
public String getName() {
return "load";
}
public String getHelp() {
return "load [-r, --remote] scriptName. Loads the script. If remote, uses url instead of path";
}
});
}
}