You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2010/09/03 16:11:32 UTC

svn commit: r992303 - in /karaf/trunk/shell/console: ./ src/main/java/org/apache/felix/gogo/commands/basic/ src/main/java/org/apache/karaf/shell/console/ src/main/java/org/apache/karaf/shell/console/commands/ src/main/java/org/apache/karaf/shell/consol...

Author: gnodet
Date: Fri Sep  3 14:11:32 2010
New Revision: 992303

URL: http://svn.apache.org/viewvc?rev=992303&view=rev
Log:
added fix for https://issues.apache.org/jira/browse/KARAF-171 to provide a help command

Added:
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/Help.java
Modified:
    karaf/trunk/shell/console/pom.xml
    karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/completer/SimpleCommandsCompleter.java

Modified: karaf/trunk/shell/console/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/pom.xml?rev=992303&r1=992302&r2=992303&view=diff
==============================================================================
--- karaf/trunk/shell/console/pom.xml (original)
+++ karaf/trunk/shell/console/pom.xml Fri Sep  3 14:11:32 2010
@@ -42,6 +42,11 @@
 
     <dependencies>
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
             <groupId>jline</groupId>
             <artifactId>jline</artifactId>
         </dependency>

Modified: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java?rev=992303&r1=992302&r2=992303&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java Fri Sep  3 14:11:32 2010
@@ -283,7 +283,8 @@ public class DefaultActionPreparator imp
         }
     }
 
-    protected void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
+    // TODO move this to a helper class?
+    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
         int pfxLen = length(prefix);
         int maxwidth = termWidth - pfxLen;
         Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
@@ -294,7 +295,7 @@ public class DefaultActionPreparator imp
         }
     }
 
-    protected int length(String str) {
+    public static int length(String str) {
         return str.length();
     }
 

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java?rev=992303&r1=992302&r2=992303&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/Main.java Fri Sep  3 14:11:32 2010
@@ -26,8 +26,6 @@ import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
-import java.util.Properties;
-import java.util.Set;
 
 import jline.Terminal;
 import org.apache.felix.gogo.commands.Action;
@@ -36,6 +34,7 @@ import org.apache.felix.gogo.commands.ba
 import org.apache.felix.gogo.runtime.lang.Support;
 import org.apache.felix.gogo.runtime.shell.CommandShellImpl;
 import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
+import org.apache.karaf.shell.console.commands.Help;
 import org.apache.karaf.shell.console.completer.SimpleCommandsCompleter;
 import org.apache.karaf.shell.console.jline.Console;
 import org.apache.karaf.shell.console.jline.TerminalFactory;
@@ -78,7 +77,18 @@ public class Main {
             args = a;
         }
 
-        SimpleCommandsCompleter completer = new SimpleCommandsCompleter(getApplication());
+        final SimpleCommandsCompleter completer = new SimpleCommandsCompleter(this);
+
+        // add top level help
+        Command helpCommand = Help.class.getAnnotation(Command.class);
+        Function helpFunction = new AbstractCommand() {
+            @Override
+            protected Action createNewAction() throws Exception {
+                return new Help(completer);
+            }
+        };
+        addCommand(helpCommand, helpFunction, commandProcessor, completer);
+
         discoverCommands(commandProcessor, cl, completer);
 
         InputStream in = unwrap(System.in);
@@ -120,7 +130,7 @@ public class Main {
             args = a;
         }
 
-        SimpleCommandsCompleter completer = new SimpleCommandsCompleter(getApplication());
+        SimpleCommandsCompleter completer = new SimpleCommandsCompleter(this);
         discoverCommands(commandProcessor, cl, completer);
 
         InputStream in = parent.getKeyboard();
@@ -190,19 +200,15 @@ public class Main {
             while (line != null) {
                 line = line.trim();
                 if (line.length() > 0 && line.charAt(0) != '#') {
-                        final Class<Action> actionClass = (Class<Action>) 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());
-                            completer.addCommand(cmd, function);
-                        } catch (Exception e) {
+                    final Class<Action> actionClass = (Class<Action>) cl.loadClass(line);
+                    Command cmd = actionClass.getAnnotation(Command.class);
+                    Function function = new AbstractCommand() {
+                        @Override
+                        protected Action createNewAction() throws Exception {
+                            return ((Class<? extends Action>) actionClass).newInstance();
                         }
+                    };
+                    addCommand(cmd, function, commandProcessor, completer);
                 }
                 line = r.readLine();
             }
@@ -210,6 +216,14 @@ public class Main {
         }
     }
 
+    protected void addCommand(Command cmd, Function function, CommandShellImpl commandProcessor, SimpleCommandsCompleter completer) {
+        try {
+            commandProcessor.addCommand(cmd.scope(), function, cmd.name());
+            completer.addCommand(cmd, function);
+        } catch (Exception e) {
+        }
+    }
+
 
     public String getApplication() {
         return application;

Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/Help.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/Help.java?rev=992303&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/Help.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/Help.java Fri Sep  3 14:11:32 2010
@@ -0,0 +1,47 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.karaf.shell.console.commands;
+
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.shell.console.completer.SimpleCommandsCompleter;
+import org.osgi.service.command.CommandSession;
+
+/**
+ * Displays help on the available commands
+ */
+@Command(scope = "*", name = "help", description = "Displays this help or help about a command")
+public class Help implements Action {
+    @Argument(name = "command", required = false, description = "The command to get help for")
+    private String command;
+    private final SimpleCommandsCompleter completer;
+
+    public Help(SimpleCommandsCompleter completer) {
+        this.completer = completer;
+    }
+
+    public Object execute(CommandSession session) throws Exception {
+        if (command == null) {
+            return completer.printUsage(session);
+        }
+        else {
+            return completer.printCommandUsage(session, command);
+        }
+    }
+}

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/completer/SimpleCommandsCompleter.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/completer/SimpleCommandsCompleter.java?rev=992303&r1=992302&r2=992303&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/completer/SimpleCommandsCompleter.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/completer/SimpleCommandsCompleter.java Fri Sep  3 14:11:32 2010
@@ -18,17 +18,25 @@
  */
 package org.apache.karaf.shell.console.completer;
 
+import jline.Terminal;
 import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.basic.DefaultActionPreparator;
 import org.apache.karaf.shell.console.CompletableFunction;
 import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.Main;
+import org.fusesource.jansi.Ansi;
+import org.osgi.service.command.CommandSession;
 import org.osgi.service.command.Function;
 
+import java.io.PrintStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -37,19 +45,21 @@ import java.util.concurrent.ConcurrentHa
  */
 public class SimpleCommandsCompleter implements Completer {
 
+    private final Main main;
     private final Map<Command, Completer> completers = new ConcurrentHashMap<Command, Completer>();
-    private String application;
+    private final Map<String, Function> functions = Collections.synchronizedMap(new TreeMap<String, Function>());
+    private final Map<String, Command> commands = Collections.synchronizedMap(new TreeMap<String, Command>());
 
-    public SimpleCommandsCompleter(String application) {
-        this.application = application;
+    public SimpleCommandsCompleter(Main main) {
+        this.main = main;
     }
 
 
     public void addCommand(Command command, Function function) {
-        Set<String> functions = getNames(command);
-        if (functions != null) {
+        Set<String> names = getNames(command);
+        if (names != null) {
             List<Completer> cl = new ArrayList<Completer>();
-            cl.add(new StringsCompleter(functions));
+            cl.add(new StringsCompleter(names));
             if (function instanceof CompletableFunction) {
                 List<Completer> fcl = ((CompletableFunction) function).getCompleters();
                 if (fcl != null) {
@@ -64,6 +74,10 @@ public class SimpleCommandsCompleter imp
             }
             ArgumentCompleter c = new ArgumentCompleter(cl);
             completers.put(command, c);
+            for (String name : names) {
+                functions.put(name, function);
+                commands.put(name, command);
+            }
         }
     }
 
@@ -78,7 +92,7 @@ public class SimpleCommandsCompleter imp
         Object scope = command.scope();
         String function = command.name();
         if (function != null) {
-            if (scope == null || scope.equals(application)) {
+            if (scope == null || scope.equals(main.getApplication()) || scope.equals("*")) {
                 names.add(function);
                 return names;
             } else {
@@ -94,5 +108,36 @@ public class SimpleCommandsCompleter imp
         Collections.sort(candidates);
         return res;
     }
+
+    /**
+     * Prints the usage for all commands
+     */
+    public Object printUsage(CommandSession session) {
+        Terminal term = (Terminal) session.get(".jline.terminal");
+        PrintStream out = System.out;
+
+        if (commands.size() > 0) {
+            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("COMMANDS").a(Ansi.Attribute.RESET));
+            for (Command command : commands.values()) {
+                out.print("        ");
+                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
+                DefaultActionPreparator.printFormatted("                ", command.description(), term != null ? term.getTerminalWidth() : 80, out);
+            }
+            out.println();
+        }
+        return null;
+    }
+
+    /**
+     * Prints the usage for a single command
+     */
+    public Object printCommandUsage(CommandSession session, String command) throws Exception {
+        // lets just call the command if it exists using the help option
+        Function function = functions.get(command);
+        if (function == null) {
+            throw new IllegalArgumentException("No such command: " + command);
+        }
+        return function.execute(session, Arrays.asList(new Object[]{"--help"}));
+    }
 }