diff --git a/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java b/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java index 33796e1..efbbb38 100644 --- a/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java +++ b/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java @@ -18,12 +18,7 @@ */ package org.apache.karaf.shell.console; -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintStream; +import java.io.*; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -45,6 +40,7 @@ import org.apache.karaf.shell.console.jline.TerminalFactory; import org.fusesource.jansi.AnsiConsole; import org.osgi.service.command.CommandSession; import org.osgi.service.command.Function; +import org.osgi.service.threadio.ThreadIO; public class Main { private String application = System.getProperty("karaf.name", "root"); @@ -55,7 +51,14 @@ public class Main { main.run(args); } + /** + * Use this method when the shell is being executed as a top level shell. + * + * @param args + * @throws Exception + */ public void run(String args[]) throws Exception { + ThreadIOImpl threadio = new ThreadIOImpl(); threadio.start(); @@ -73,45 +76,58 @@ public class Main { args = a; } - Enumeration urls = cl.getResources(getDiscoveryResource()); - while (urls.hasMoreElements()) { - URL url = urls.nextElement(); - BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream())); - String line = r.readLine(); - while (line != null) { - line = line.trim(); - if (line.length() > 0 && line.charAt(0) != '#') { - final Class actionClass = (Class) cl.loadClass(line); - try { - Command cmd = actionClass.getAnnotation(Command.class); - Function function = new AbstractCommand() { - @Override - protected Action createNewAction() throws Exception { - return actionClass.newInstance(); - } - }; - commandProcessor.addCommand(cmd.scope(), function, cmd.name()); - } catch (Exception e) { - } - } - line = r.readLine(); + discoverCommands(commandProcessor, cl); + + InputStream in = unwrap(System.in); + PrintStream out = wrap(unwrap(System.out)); + PrintStream err = wrap(unwrap(System.err)); + run(commandProcessor, args, in, out, err); + + // TODO: do we need to stop the threadio that was started? + // threadio.stop(); + } + + /** + * Use this method when the shell is being executed as a command + * of another shell. + * + * @param parent + * @param args + * @throws Exception + */ + public void run(CommandSession parent, String args[]) throws Exception { + + CommandShellImpl commandProcessor = new CommandShellImpl(); + // TODO: find out what the down side of not using a real ThreadIO implementation is. + commandProcessor.setThreadio(new ThreadIO(){ + public void setStreams(InputStream in, PrintStream out, PrintStream err) { } - r.close(); + public void close() { + } + }); + commandProcessor.setConverter(new Support()); + + ClassLoader cl = Main.class.getClassLoader(); + if (args.length > 0 && args[0].startsWith("--classpath=")) { + String base = args[0].substring("--classpath=".length()); + List urls = getFiles(new File(base)); + cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), cl); + String[] a = new String[args.length - 1]; + System.arraycopy(args, 1, a, 0, a.length); + args = a; } + discoverCommands(commandProcessor, cl); - TerminalFactory terminalFactory = new TerminalFactory(); + InputStream in = parent.getKeyboard(); + PrintStream out = parent.getConsole(); + PrintStream err = parent.getConsole(); + run(commandProcessor, args, in, out, err); + } - InputStream in = unwrap(System.in); - PrintStream out = unwrap(System.out); - PrintStream err = unwrap(System.err); + private void run(final CommandShellImpl commandProcessor, String[] args, final InputStream in, final PrintStream out, final PrintStream err) throws Exception { + TerminalFactory terminalFactory = new TerminalFactory(); Terminal terminal = terminalFactory.getTerminal(); - Console console = new Console(commandProcessor, - in, - wrap(out), - wrap(err), - terminal, - null, - null) { + Console console = new Console(commandProcessor, in, out, err, terminal, null, null) { @Override protected Properties loadBrandingProperties() { return super.loadBrandingProperties(); @@ -150,6 +166,34 @@ public class Main { return "META-INF/services/org/apache/karaf/shell/commands"; } + private void discoverCommands(CommandShellImpl commandProcessor, ClassLoader cl) throws IOException, ClassNotFoundException { + Enumeration urls = cl.getResources(getDiscoveryResource()); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream())); + String line = r.readLine(); + while (line != null) { + line = line.trim(); + if (line.length() > 0 && line.charAt(0) != '#') { + final Class actionClass = (Class) cl.loadClass(line); + try { + Command cmd = actionClass.getAnnotation(Command.class); + Function function = new AbstractCommand() { + @Override + protected Action createNewAction() throws Exception { + return actionClass.newInstance(); + } + }; + commandProcessor.addCommand(cmd.scope(), function, cmd.name()); + } catch (Exception e) { + } + } + line = r.readLine(); + } + r.close(); + } + } + public String getApplication() { return application; } diff --git a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java index 0cfc5a3..2ad9601 100644 --- a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java +++ b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java @@ -67,7 +67,7 @@ public class Console implements Runnable private BlockingQueue queue; private boolean interrupt; private Thread pipe; - private boolean running; + volatile private boolean running; private Runnable closeCallback; private Terminal terminal; private InputStream consoleInput; @@ -131,7 +131,6 @@ public class Console implements Runnable //System.err.println("Closing"); running = false; pipe.interrupt(); - Thread.interrupted(); } public void run() @@ -211,6 +210,7 @@ public class Console implements Runnable } } } + close(); //System.err.println("Exiting console..."); if (closeCallback != null) {