You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2012/05/11 10:39:19 UTC

svn commit: r1337063 [1/2] - in /karaf/trunk: shell/console/ shell/console/src/main/java/org/apache/felix/gogo/commands/ shell/console/src/main/java/org/apache/karaf/shell/commands/basic/ shell/console/src/main/java/org/apache/karaf/shell/commands/meta...

Author: cschneider
Date: Fri May 11 08:39:18 2012
New Revision: 1337063

URL: http://svn.apache.org/viewvc?rev=1337063&view=rev
Log:
KARAF-1447 Support old annotations for actions in addition to the new ones. Introduce metadata about commands

Added:
    karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java
    karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java
    karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java
    karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java
    karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/
    karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java
      - copied, changed from r1336532, karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java
    karaf/trunk/shell/help/src/main/resources/services/
      - copied from r1336087, karaf/trunk/shell/console/src/main/resources/META-INF/services/
Removed:
    karaf/trunk/shell/console/src/main/resources/META-INF/services/
    karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java
Modified:
    karaf/trunk/shell/console/pom.xml
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java
    karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java
    karaf/trunk/shell/help/pom.xml
    karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java
    karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java
    karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java
    karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java
    karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java

Modified: karaf/trunk/shell/console/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/pom.xml?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/pom.xml (original)
+++ karaf/trunk/shell/console/pom.xml Fri May 11 08:39:18 2012
@@ -141,7 +141,6 @@
                         	org.apache.karaf.shell.console,
                         	org.apache.karaf.shell.console.commands,
                         	org.apache.karaf.shell.console.completer,
-                        	org.apache.karaf.shell.console.table,
                         	org.apache.karaf.shell.util,
                             org.apache.felix.gogo*;version=${felix.gogo.version},
                             org.apache.felix.service.command;version=${felix.gogo.version};status=provisional;mandatory:=status,
@@ -154,7 +153,6 @@
                         	org.apache.karaf.shell.console.impl*,
                             org.fusesource.jansi.internal;-split-package:=first,
                             org.apache.felix.gogo.runtime*;-split-package:=first,
-                            org.apache.karaf.util*;-split-package:=first,
                             META-INF.native.*;-split-package:=first
                         </Private-Package>
                         <Bundle-NativeCode>

Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java Fri May 11 08:39:18 2012
@@ -0,0 +1,35 @@
+/*
+ * 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.felix.gogo.commands;
+
+
+/**
+ * An action allows to easily execute commands in karaf.
+ * It can be assumed that each action is only accessed by a single thread at a time.
+ * 
+ * An Action is always part of an AbstractCommand. The AbstractCommand makes sure
+ * the single threaded assumption above is true. Before the call to the execute method
+ * the action is checked for annotated fields (@Argument, @Option). These fields
+ * are populated from the command arguments before the action is called.
+ * 
+ * @deprecated use org.apache.karaf.shell.commands.Action instead
+ */
+@Deprecated
+public interface Action extends org.apache.karaf.shell.commands.Action {
+}

Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java Fri May 11 08:39:18 2012
@@ -0,0 +1,49 @@
+/*
+ * 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.felix.gogo.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Represents a positional argument on a command line (as opposed to an optional named {@link Option}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Argument
+{
+    public static final String DEFAULT_STRING= "DEFAULT";
+
+    String DEFAULT = "##default";
+
+    String name() default DEFAULT;
+
+    String description() default "";
+
+    boolean required() default false;
+
+    int index() default 0;
+
+    boolean multiValued() default false;
+
+    String valueToShowInHelp() default DEFAULT_STRING;
+}

Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java Fri May 11 08:39:18 2012
@@ -0,0 +1,54 @@
+/*
+ * 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.felix.gogo.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Used to denote a class represents a command which is executable within a shell/scope or as a
+ * command line process.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Deprecated
+public @interface Command
+{
+    /**
+     * Returns the scope or sub shell of the command
+     */
+    String scope();
+
+    /**
+     * REturns the name of the command if used inside a shell
+     */
+    String name();
+
+    /**
+     * Returns the description of the command which is used to generate command line help
+     */
+    String description() default "";
+
+    /**
+     * Returns a detailed description of the command
+     */
+    String detailedDescription() default "";
+}

Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java Fri May 11 08:39:18 2012
@@ -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.felix.gogo.commands;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to mark an optional named command line option who's name typically starts with "--"
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Option
+{
+    public static final String DEFAULT_STRING= "DEFAULT";
+
+    String name();
+
+    String[] aliases() default {};
+
+    String description() default "";
+
+    boolean required() default false;
+
+    boolean multiValued() default false;
+
+    String valueToShowInHelp() default DEFAULT_STRING;
+}

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java Fri May 11 08:39:18 2012
@@ -18,20 +18,18 @@
  */
 package org.apache.karaf.shell.commands.basic;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Type;
-import java.util.*;
-import java.io.PrintStream;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import jline.Terminal;
+
+import org.apache.felix.service.command.CommandSession;
 import org.apache.karaf.shell.commands.Action;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
@@ -40,76 +38,41 @@ import org.apache.karaf.shell.commands.H
 import org.apache.karaf.shell.commands.Option;
 import org.apache.karaf.shell.commands.converter.DefaultConverter;
 import org.apache.karaf.shell.commands.converter.GenericType;
-import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
 import org.apache.karaf.shell.console.NameScoping;
 import org.fusesource.jansi.Ansi;
 
 public class DefaultActionPreparator implements ActionPreparator {
 
     public boolean prepare(Action action, CommandSession session, List<Object> params) throws Exception {
-        Map<Option, Field> options = new HashMap<Option, Field>();
-        Map<Argument, Field> arguments = new HashMap<Argument, Field>();
-        List<Argument> orderedArguments = new ArrayList<Argument>();
-        // Introspect
-        for (Class type = action.getClass(); type != null; type = type.getSuperclass()) {
-            for (Field field : type.getDeclaredFields()) {
-                Option option = field.getAnnotation(Option.class);
-                if (option != null) {
-                    options.put(option, field);
-                }
-                Argument argument = field.getAnnotation(Argument.class);
-                if (argument != null) {
-                    if (Argument.DEFAULT.equals(argument.name())) {
-                        final Argument delegate = argument;
-                        final String name = field.getName();
-                        argument = new Argument() {
-                            public String name() {
-                                return name;
-                            }
-
-                            public String description() {
-                                return delegate.description();
-                            }
-
-                            public boolean required() {
-                                return delegate.required();
-                            }
-
-                            public int index() {
-                                return delegate.index();
-                            }
-
-                            public boolean multiValued() {
-                                return delegate.multiValued();
-                            }
-
-                            public String valueToShowInHelp() {
-                                return delegate.valueToShowInHelp();
-                            }
-
-                            public Class<? extends Annotation> annotationType() {
-                                return delegate.annotationType();
-                            }
-                        };
-                    }
-                    arguments.put(argument, field);
-                    int index = argument.index();
-                    while (orderedArguments.size() <= index) {
-                        orderedArguments.add(null);
-                    }
-                    if (orderedArguments.get(index) != null) {
-                        throw new IllegalArgumentException("Duplicate argument index: " + index);
-                    }
-                    orderedArguments.set(index, argument);
-                }
-            }
-        }
-        // Check indexes are correct
-        for (int i = 0; i < orderedArguments.size(); i++) {
-            if (orderedArguments.get(i) == null) {
-                throw new IllegalArgumentException("Missing argument for index: " + i);
+        ActionMetaData actionMetaData = new ActionMetaDataFactory().create(action.getClass());
+        Map<Option, Field> options = actionMetaData.getOptions();
+        Map<Argument, Field> arguments = actionMetaData.getArguments();
+        List<Argument> orderedArguments = actionMetaData.getOrderedArguments();
+        Command command2 = actionMetaData.getCommand();
+        String commandErrorSt = (command2 != null) ? Ansi.ansi()
+                .fg(Ansi.Color.RED)
+                .a("Error executing command ")
+                .a(command2.scope())
+                .a(":")
+                .a(Ansi.Attribute.INTENSITY_BOLD)
+                .a(command2.name())
+                .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
+                .fg(Ansi.Color.DEFAULT)
+                .a(": ")
+                .toString() : "";
+        for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
+            Object param = it.next();
+            if (HelpOption.HELP.name().equals(param)) {
+                Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
+                int termWidth = term != null ? term.getWidth() : 80;
+                boolean globalScope = NameScoping.isGlobalScope(session, actionMetaData.getCommand().scope());
+                actionMetaData.printUsage(action, System.out, globalScope, termWidth);
+                return false;
             }
         }
+        
         // Populate
         Map<Option, Object> optionValues = new HashMap<Option, Object>();
         Map<Argument, Object> argumentValues = new HashMap<Argument, Object>();
@@ -117,11 +80,7 @@ public class DefaultActionPreparator imp
         int argIndex = 0;
         for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
             Object param = it.next();
-            // Check for help
-            if (HelpOption.HELP.name().equals(param) || Arrays.asList(HelpOption.HELP.aliases()).contains(param)) {
-                printUsage(session, action, options, arguments, System.out);
-                return false;
-            }
+
             if (processOptions && param instanceof String && ((String) param).startsWith("-")) {
                 boolean isKeyValuePair = ((String) param).indexOf('=') != -1;
                 String name;
@@ -140,30 +99,16 @@ public class DefaultActionPreparator imp
                     }
                 }
                 if (option == null) {
-                    Command command = action.getClass().getAnnotation(Command.class);
-                    if (command != null) {
-                        throw new CommandException(
+                    throw new CommandException(commandErrorSt + 
                                 Ansi.ansi()
-                                        .fg(Ansi.Color.RED)
-                                        .a("Error executing command ")
-                                        .a(command.scope())
-                                        .a(":")
-                                        .a(Ansi.Attribute.INTENSITY_BOLD)
-                                        .a(command.name())
-                                        .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                        .a(" undefined option ")
+                                        .a("undefined option ")
                                         .a(Ansi.Attribute.INTENSITY_BOLD)
                                         .a(param)
                                         .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                        .fg(Ansi.Color.DEFAULT)
                                         .newline()
-                                        .a("Try '" + command.scope() + ":" + command.name() + " --help' for more information.")
+                                        .a("Try <command> --help' for more information.")
                                         .toString(),
-                                "Undefined option: " + param
-                        );
-                    } else {
-                        throw new CommandException("Undefined option: " + param);
-                    }
+                                        "Undefined option: " + param);
                 }
                 Field field = options.get(option);
                 if (value == null && (field.getType() == boolean.class || field.getType() == Boolean.class)) {
@@ -173,30 +118,13 @@ public class DefaultActionPreparator imp
                     value = it.next();
                 }
                 if (value == null) {
-                    Command command = action.getClass().getAnnotation(Command.class);
-                    if (command != null) {
-                        throw new CommandException(
-                                Ansi.ansi()
-                                        .fg(Ansi.Color.RED)
-                                        .a("Error executing command ")
-                                        .a(command.scope())
-                                        .a(":")
-                                        .a(Ansi.Attribute.INTENSITY_BOLD)
-                                        .a(command.name())
-                                        .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                        .a(" missing value for option ")
-                                        .a(Ansi.Attribute.INTENSITY_BOLD)
-                                        .a(param)
-                                        .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                        .fg(Ansi.Color.DEFAULT)
-                                        .toString(),
+                        throw new CommandException(commandErrorSt +
+                                Ansi.ansi().a("missing value for option ").bold().a(param).boldOff().toString(),
                                 "Missing value for option: " + param
                         );
-                    } else {
-                        throw new CommandException("Missing value for option: " + param);
-                    }
                 }
                 if (option.multiValued()) {
+                    @SuppressWarnings("unchecked")
                     List<Object> l = (List<Object>) optionValues.get(option);
                     if (l == null) {
                         l = new ArrayList<Object>();
@@ -209,31 +137,17 @@ public class DefaultActionPreparator imp
             } else {
                 processOptions = false;
                 if (argIndex >= orderedArguments.size()) {
-                    Command command = action.getClass().getAnnotation(Command.class);
-                    if (command != null) {
-                        throw new CommandException(
-                                Ansi.ansi()
-                                        .fg(Ansi.Color.RED)
-                                        .a("Error executing command ")
-                                        .a(command.scope())
-                                        .a(":")
-                                        .a(Ansi.Attribute.INTENSITY_BOLD)
-                                        .a(command.name())
-                                        .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                        .a(": too many arguments specified")
-                                        .fg(Ansi.Color.DEFAULT)
-                                        .toString(),
+                        throw new CommandException(commandErrorSt +
+                                Ansi.ansi().a("too many arguments specified").toString(),
                                 "Too many arguments specified"
                         );
-                    } else {
-                        throw new CommandException("Too many arguments specified");
-                    }
                 }
                 Argument argument = orderedArguments.get(argIndex);
                 if (!argument.multiValued()) {
                     argIndex++;
                 }
                 if (argument.multiValued()) {
+                    @SuppressWarnings("unchecked")
                     List<Object> l = (List<Object>) argumentValues.get(argument);
                     if (l == null) {
                         l = new ArrayList<Object>();
@@ -248,58 +162,21 @@ public class DefaultActionPreparator imp
         // Check required arguments / options
         for (Option option : options.keySet()) {
             if (option.required() && optionValues.get(option) == null) {
-                Command command = action.getClass().getAnnotation(Command.class);
-                if (command != null) {
-                    throw new CommandException(
-                            Ansi.ansi()
-                                    .fg(Ansi.Color.RED)
-                                    .a("Error executing command ")
-                                    .a(command.scope())
-                                    .a(":")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(command.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(": option ")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(option.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(" is required")
-                                    .fg(Ansi.Color.DEFAULT)
-                                    .toString(),
+                    throw new CommandException(commandErrorSt +
+                            Ansi.ansi().a("option ").bold().a(option.name()).boldOff().a(" is required").toString(),
                             "Option " + option.name() + " is required"
                     );
-                } else {
-                    throw new CommandException("Option " + option.name() + " is required");
-                }
             }
         }
         for (Argument argument : arguments.keySet()) {
             if (argument.required() && argumentValues.get(argument) == null) {
-                Command command = action.getClass().getAnnotation(Command.class);
-                if (command != null) {
-                    throw new CommandException(
-                            Ansi.ansi()
-                                    .fg(Ansi.Color.RED)
-                                    .a("Error executing command ")
-                                    .a(command.scope())
-                                    .a(":")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(command.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(": argument ")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(argument.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(" is required")
-                                    .fg(Ansi.Color.DEFAULT)
-                                    .toString(),
+                    throw new CommandException(commandErrorSt +
+                            Ansi.ansi().a("argument ").bold().a(argument.name()).boldOff().a(" is required").toString(),
                             "Argument " + argument.name() + " is required"
                     );
-                } else {
-                    throw new CommandException("Argument " + argument.name() + " is required");
-                }
             }
         }
+            
         // Convert and inject values
         for (Map.Entry<Option, Object> entry : optionValues.entrySet()) {
             Field field = options.get(entry.getKey());
@@ -307,36 +184,13 @@ public class DefaultActionPreparator imp
             try {
                 value = convert(action, session, entry.getValue(), field.getGenericType());
             } catch (Exception e) {
-                Command command = action.getClass().getAnnotation(Command.class);
-                if (command != null) {
-                    throw new CommandException(
-                            Ansi.ansi()
-                                    .fg(Ansi.Color.RED)
-                                    .a("Error executing command ")
-                                    .a(command.scope())
-                                    .a(":")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(command.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(": unable to convert option ")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(entry.getKey().name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(" with value '")
-                                    .a(entry.getValue())
-                                    .a("' to type ")
-                                    .a(new GenericType(field.getGenericType()).toString())
-                                    .fg(Ansi.Color.DEFAULT)
-                                    .toString(),
+                    throw new CommandException(commandErrorSt +
+                            Ansi.ansi().a("unable to convert option ").bold().a(entry.getKey().name()).boldOff().a(" with value '").a(entry.getValue()).a("' to type ")
+                                .a(new GenericType(field.getGenericType()).toString()).toString(),
                             "Unable to convert option " + entry.getKey().name() + " with value '"
                                     + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
                             e
                     );
-                } else {
-                    throw new CommandException("Unable to convert option " + entry.getKey().name() + " with value '"
-                            + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
-                            e);
-                }
             }
             field.setAccessible(true);
             field.set(action, value);
@@ -347,36 +201,14 @@ public class DefaultActionPreparator imp
             try {
                 value = convert(action, session, entry.getValue(), field.getGenericType());
             } catch (Exception e) {
-                Command command = action.getClass().getAnnotation(Command.class);
-                if (command != null) {
-                    throw new CommandException(
+                    throw new CommandException(commandErrorSt +
                             Ansi.ansi()
-                                    .fg(Ansi.Color.RED)
-                                    .a("Error executing command ")
-                                    .a(command.scope())
-                                    .a(":")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(command.name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(": unable to convert argument ")
-                                    .a(Ansi.Attribute.INTENSITY_BOLD)
-                                    .a(entry.getKey().name())
-                                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                                    .a(" with value '")
-                                    .a(entry.getValue())
-                                    .a("' to type ")
-                                    .a(new GenericType(field.getGenericType()).toString())
-                                    .fg(Ansi.Color.DEFAULT)
-                                    .toString(),
+                                    .a("unable to convert argument ").bold().a(entry.getKey().name()).boldOff().a(" with value '").a(entry.getValue())
+                                    .a("' to type ").a(new GenericType(field.getGenericType()).toString()).toString(),
                             "Unable to convert argument " + entry.getKey().name() + " with value '"
                                     + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
                             e
                     );
-                } else {
-                    throw new CommandException("Unable to convert argument " + entry.getKey().name() + " with value '"
-                            + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
-                            e);
-                }
             }
             field.setAccessible(true);
             field.set(action, value);
@@ -384,199 +216,6 @@ public class DefaultActionPreparator imp
         return true;
     }
 
-    protected void printUsage(CommandSession session, Action action, Map<Option, Field> optionsMap, Map<Argument, Field> argsMap, PrintStream out) {
-        Command command = action.getClass().getAnnotation(Command.class);
-        if (command != null) {
-            Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
-            List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
-            Collections.sort(arguments, new Comparator<Argument>() {
-                public int compare(Argument o1, Argument o2) {
-                    return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
-                }
-            });
-            Set<Option> options = new HashSet<Option>(optionsMap.keySet());
-            options.add(HelpOption.HELP);
-            boolean globalScope = NameScoping.isGlobalScope(session, command.scope());
-            if (command != null && (command.description() != null || command.name() != null)) {
-                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DESCRIPTION").a(Ansi.Attribute.RESET));
-                out.print("        ");
-                if (command.name() != null) {
-                    if (globalScope) {
-                        out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
-                    } else {
-                        out.println(Ansi.ansi().a(command.scope()).a(":").a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
-                    }
-                    out.println();
-                }
-                out.print("\t");
-                out.println(command.description());
-                out.println();
-            }
-            StringBuffer syntax = new StringBuffer();
-            if (command != null) {
-                if (globalScope) {
-                    syntax.append(command.name());
-                } else {
-                    syntax.append(String.format("%s:%s", command.scope(), command.name()));
-                }
-            }
-            if (options.size() > 0) {
-                syntax.append(" [options]");
-            }
-            if (arguments.size() > 0) {
-                syntax.append(' ');
-                for (Argument argument : arguments) {
-                    if (!argument.required()) {
-                        syntax.append(String.format("[%s] ", argument.name()));
-                    } else {
-                        syntax.append(String.format("%s ", argument.name()));
-                    }
-                }
-            }
-
-            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SYNTAX").a(Ansi.Attribute.RESET));
-            out.print("        ");
-            out.println(syntax.toString());
-            out.println();
-            if (arguments.size() > 0) {
-                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("ARGUMENTS").a(Ansi.Attribute.RESET));
-                for (Argument argument : arguments) {
-                    out.print("        ");
-                    out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(argument.name()).a(Ansi.Attribute.RESET));
-                    printFormatted("                ", argument.description(), term != null ? term.getWidth() : 80, out);
-                    if (!argument.required()) {
-                        if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
-                            try {
-                                if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
-                                    argsMap.get(argument).setAccessible(true);
-                                    Object o = argsMap.get(argument).get(action);
-                                    printObjectDefaultsTo(out, o);
-                                } else {
-                                    printDefaultsTo(out, argument.valueToShowInHelp());
-                                }
-                            } catch (Throwable t) {
-                                // Ignore
-                            }
-                        }
-                    }
-                }
-                out.println();
-            }
-            if (options.size() > 0) {
-                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("OPTIONS").a(Ansi.Attribute.RESET));
-                for (Option option : options) {
-                    String opt = option.name();
-                    for (String alias : option.aliases()) {
-                        opt += ", " + alias;
-                    }
-                    out.print("        ");
-                    out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(opt).a(Ansi.Attribute.RESET));
-                    printFormatted("                ", option.description(), term != null ? term.getWidth() : 80, out);
-                    if (option.valueToShowInHelp() != null && option.valueToShowInHelp().length() != 0) {
-                        try {
-                            if (Option.DEFAULT_STRING.equals(option.valueToShowInHelp())) {
-                                optionsMap.get(option).setAccessible(true);
-                                Object o = optionsMap.get(option).get(action);
-                                printObjectDefaultsTo(out, o);
-                            } else {
-                                printDefaultsTo(out, option.valueToShowInHelp());
-                            }
-                        } catch (Throwable t) {
-                            // Ignore
-                        }
-                    }
-                }
-                out.println();
-            }
-            if (command.detailedDescription().length() > 0) {
-                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
-                String desc = loadDescription(action.getClass(), command.detailedDescription());
-                printFormatted("        ", desc, term != null ? term.getWidth() : 80, out);
-            }
-        }
-    }
-
-    private void printObjectDefaultsTo(PrintStream out, Object o) {
-        if (o != null
-                && (!(o instanceof Boolean) || ((Boolean) o))
-                && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
-            printDefaultsTo(out, o.toString());
-        }
-    }
-
-    private void printDefaultsTo(PrintStream out, String value) {
-        out.print("                (defaults to ");
-        out.print(value);
-        out.println(")");
-    }
-
-    protected String loadDescription(Class clazz, String desc) {
-        if (desc.startsWith("classpath:")) {
-            InputStream is = clazz.getResourceAsStream(desc.substring("classpath:".length()));
-            if (is == null) {
-                is = clazz.getClassLoader().getResourceAsStream(desc.substring("classpath:".length()));
-            }
-            if (is == null) {
-                desc = "Unable to load description from " + desc;
-            } else {
-                try {
-                    Reader r = new InputStreamReader(is);
-                    StringWriter sw = new StringWriter();
-                    int c;
-                    while ((c = r.read()) != -1) {
-                        sw.append((char) c);
-                    }
-                    desc = sw.toString();
-                } catch (IOException e) {
-                    desc = "Unable to load description from " + desc;
-                } finally {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
-        return desc;
-    }
-
-    // TODO move this to a helper class?
-    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
-        printFormatted(prefix, str, termWidth, out, true);
-    }
-
-    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out, boolean prefixFirstLine) {
-        int pfxLen = length(prefix);
-        int maxwidth = termWidth - pfxLen;
-        Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
-        int cur = 0;
-        while (cur >= 0) {
-            int lst = str.indexOf('\n', cur);
-            String s = (lst >= 0) ? str.substring(cur, lst) : str.substring(cur);
-            if (s.length() == 0) {
-                out.println();
-            } else {
-                Matcher m = wrap.matcher(s);
-                while (m.find()) {
-                    if (cur > 0 || prefixFirstLine) {
-                        out.print(prefix);
-                    }
-                    out.println(m.group());
-                }
-            }
-            if (lst >= 0) {
-                cur = lst + 1;
-            } else {
-                break;
-            }
-        }
-    }
-
-    public static int length(String str) {
-        return str.length();
-    }
-
     protected Object convert(Action action, CommandSession session, Object value, Type toType) throws Exception {
         if (toType == String.class) {
             return value != null ? value.toString() : null;

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java Fri May 11 08:39:18 2012
@@ -63,18 +63,18 @@ public class SimpleCommand extends Abstr
     }
 
 
-    public static ServiceRegistration export(BundleContext context, Class<? extends Action> actionClass)
+    public static ServiceRegistration<Function> export(BundleContext context, Class<? extends Action> actionClass)
     {
         Command cmd = actionClass.getAnnotation(Command.class);
         if (cmd == null)
         {
             throw new IllegalArgumentException("Action class is not annotated with @Command");
         }
-        Hashtable props = new Hashtable();
+        Hashtable<String, String> props = new Hashtable<String, String>();
         props.put("bundles.command.scope", cmd.scope());
         props.put("bundles.command.function", cmd.name());
         SimpleCommand command = new SimpleCommand(actionClass);
-        return context.registerService(Function.class.getName(), command, props);
+        return context.registerService(Function.class, command, props);
     }
 
 }

Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java Fri May 11 08:39:18 2012
@@ -0,0 +1,196 @@
+package org.apache.karaf.shell.commands.meta;
+
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.shell.commands.Action;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.HelpOption;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.util.IndentFormatter;
+import org.apache.karaf.shell.util.ShellUtil;
+import org.fusesource.jansi.Ansi;
+
+public class ActionMetaData {
+    private final Class<? extends Action> actionClass;
+    private final Command command;
+    private final Map<Option, Field> options;
+    private final Map<Argument, Field> arguments;
+    List<Argument> orderedArguments;
+    private final Completer[] completers;
+
+    public ActionMetaData(Class<? extends Action> actionClass, Command command, Map<Option, Field> options, Map<Argument, Field> args,
+            List<Argument> orderedArguments, Completer[] completers) {
+        super();
+        this.actionClass = actionClass;
+        this.command = command;
+        this.options = options;
+        this.arguments = args;
+        this.orderedArguments = orderedArguments;
+        this.completers = completers;
+    }
+
+    public Class<? extends Action> getActionClass() {
+        return actionClass;
+    }
+    
+    public Command getCommand() {
+        return command;
+    }
+
+    public Map<Option, Field> getOptions() {
+        return options;
+    }
+
+    public Map<Argument, Field> getArguments() {
+        return arguments;
+    }
+
+    public Completer[] getCompleters() {
+        return completers;
+    }
+
+    public List<Argument> getOrderedArguments() {
+        return orderedArguments;
+    }
+
+    public void printUsage(Action action, PrintStream out, boolean globalScope, int termWidth) {
+        if (command != null) {
+            List<Argument> argumentsSet = new ArrayList<Argument>(arguments.keySet());
+            Collections.sort(argumentsSet, new Comparator<Argument>() {
+                public int compare(Argument o1, Argument o2) {
+                    return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+                }
+            });
+            Set<Option> optionsSet = new HashSet<Option>(options.keySet());
+            optionsSet.add(HelpOption.HELP);
+            if (command != null && (command.description() != null || command.name() != null)) {
+                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DESCRIPTION").a(Ansi.Attribute.RESET));
+                out.print("        ");
+                if (command.name() != null) {
+                    if (globalScope) {
+                        out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
+                    } else {
+                        out.println(Ansi.ansi().a(command.scope()).a(":").a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
+                    }
+                    out.println();
+                }
+                out.print("\t");
+                out.println(command.description());
+                out.println();
+            }
+            StringBuffer syntax = new StringBuffer();
+            if (command != null) {
+                if (globalScope) {
+                    syntax.append(command.name());
+                } else {
+                    syntax.append(String.format("%s:%s", command.scope(), command.name()));
+                }
+            }
+            if (options.size() > 0) {
+                syntax.append(" [options]");
+            }
+            if (arguments.size() > 0) {
+                syntax.append(' ');
+                for (Argument argument : argumentsSet) {
+                    if (!argument.required()) {
+                        syntax.append(String.format("[%s] ", argument.name()));
+                    } else {
+                        syntax.append(String.format("%s ", argument.name()));
+                    }
+                }
+            }
+
+            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SYNTAX").a(Ansi.Attribute.RESET));
+            out.print("        ");
+            out.println(syntax.toString());
+            out.println();
+            if (arguments.size() > 0) {
+                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("ARGUMENTS").a(Ansi.Attribute.RESET));
+                for (Argument argument : argumentsSet) {
+                    out.print("        ");
+                    out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(argument.name()).a(Ansi.Attribute.RESET));
+                    IndentFormatter.printFormatted("                ", argument.description(), termWidth, out);
+                    if (!argument.required()) {
+                        if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
+                            try {
+                                if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
+                                    arguments.get(argument).setAccessible(true);
+                                    Object o = arguments.get(argument).get(action);
+                                    printObjectDefaultsTo(out, o);
+                                } else {
+                                    printDefaultsTo(out, argument.valueToShowInHelp());
+                                }
+                            } catch (Throwable t) {
+                                // Ignore
+                            }
+                        }
+                    }
+                }
+                out.println();
+            }
+            if (options.size() > 0) {
+                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("OPTIONS").a(Ansi.Attribute.RESET));
+                for (Option option : optionsSet) {
+                    String opt = option.name();
+                    for (String alias : option.aliases()) {
+                        opt += ", " + alias;
+                    }
+                    out.print("        ");
+                    out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(opt).a(Ansi.Attribute.RESET));
+                    IndentFormatter.printFormatted("                ", option.description(), termWidth, out);
+                    if (option.valueToShowInHelp() != null && option.valueToShowInHelp().length() != 0) {
+                        try {
+                            if (Option.DEFAULT_STRING.equals(option.valueToShowInHelp())) {
+                                options.get(option).setAccessible(true);
+                                Object o = options.get(option).get(action);
+                                printObjectDefaultsTo(out, o);
+                            } else {
+                                printDefaultsTo(out, option.valueToShowInHelp());
+                            }
+                        } catch (Throwable t) {
+                            // Ignore
+                        }
+                    }
+                }
+                out.println();
+            }
+            if (command.detailedDescription().length() > 0) {
+                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
+                String desc = loadDescription(actionClass, command.detailedDescription());
+                IndentFormatter.printFormatted("        ", desc, termWidth, out);
+            }
+        }
+    }
+    
+    private String loadDescription(Class clazz, String desc) {
+        if (desc.startsWith("classpath:")) {
+            desc = ShellUtil.loadClassPathResource(clazz, desc.substring("classpath:".length()));
+        }
+        return desc;
+    }
+
+    private void printObjectDefaultsTo(PrintStream out, Object o) {
+        if (o != null
+                && (!(o instanceof Boolean) || ((Boolean) o))
+                && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
+            printDefaultsTo(out, o.toString());
+        }
+    }
+
+    private void printDefaultsTo(PrintStream out, String value) {
+        out.print("                (defaults to ");
+        out.print(value);
+        out.println(")");
+    }
+
+}

Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java Fri May 11 08:39:18 2012
@@ -0,0 +1,232 @@
+package org.apache.karaf.shell.commands.meta;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.shell.commands.Action;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+public class ActionMetaDataFactory {
+    public ActionMetaData create(Class<? extends Action> actionClass) {
+        Command command = getCommand(actionClass);
+        Map<Option, Field> options = new HashMap<Option, Field>();
+        Map<Argument, Field> arguments = new HashMap<Argument, Field>();
+        List<Argument> orderedArguments = new ArrayList<Argument>();
+
+        for (Class<?> type = actionClass; type != null; type = type.getSuperclass()) {
+            for (Field field : type.getDeclaredFields()) {
+                Option option = field.getAnnotation(Option.class);
+                if (option == null) {
+                    option = getAndConvertDeprecatedOption(field);
+                }
+                if (option != null) {
+                    options.put(option, field);
+                }
+
+                Argument argument = field.getAnnotation(Argument.class);
+                if (argument == null) {
+                    argument = getAndConvertDeprecatedArgument(field);
+                }
+                if (argument != null) {
+                    argument = replaceDefaultArgument(field, argument);
+                    arguments.put(argument, field);
+                    int index = argument.index();
+                    while (orderedArguments.size() <= index) {
+                        orderedArguments.add(null);
+                    }
+                    if (orderedArguments.get(index) != null) {
+                        throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + actionClass.getName());
+                    }
+                    orderedArguments.set(index, argument);
+                }
+            }
+        }
+        assertIndexesAreCorrect(actionClass, orderedArguments);
+
+        return new ActionMetaData(actionClass, command, options, arguments, orderedArguments, null);
+    }
+
+    public Command getCommand(Class<? extends Action> actionClass) {
+        Command command = actionClass.getAnnotation(Command.class);
+        if (command == null) {
+            command = getAndConvertDeprecatedCommand(actionClass);
+        }
+        return command;
+    }
+
+    @SuppressWarnings("deprecation")
+    public Command getAndConvertDeprecatedCommand(Class<? extends Action> actionClass) {
+        final org.apache.felix.gogo.commands.Command oldCommand = actionClass.getAnnotation(org.apache.felix.gogo.commands.Command.class);
+        if (oldCommand == null) {
+            return null;
+        }
+        return new Command() {
+            
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return Command.class;
+            }
+            
+            @Override
+            public String scope() {
+                return oldCommand.scope();
+            }
+            
+            @Override
+            public String name() {
+                return oldCommand.name();
+            }
+            
+            @Override
+            public String detailedDescription() {
+                return oldCommand.detailedDescription();
+            }
+
+            @Override
+            public String description() {
+                return oldCommand.description();
+            }
+        };
+    }
+
+    @SuppressWarnings("deprecation")
+    private Option getAndConvertDeprecatedOption(Field field) {
+        final org.apache.felix.gogo.commands.Option oldOption = field.getAnnotation(org.apache.felix.gogo.commands.Option.class);
+        if (oldOption == null) {
+            return null;
+        }
+        return new Option() {
+            
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return Option.class;
+            }
+            
+            @Override
+            public String valueToShowInHelp() {
+                return oldOption.valueToShowInHelp();
+            }
+            
+            @Override
+            public boolean required() {
+                return oldOption.required();
+            }
+            
+            @Override
+            public String name() {
+                return oldOption.name();
+            }
+            
+            @Override
+            public boolean multiValued() {
+                return oldOption.multiValued();
+            }
+            
+            @Override
+            public String description() {
+                return oldOption.description();
+            }
+            
+            @Override
+            public String[] aliases() {
+                return oldOption.aliases();
+            }
+        };
+    }
+    
+    @SuppressWarnings("deprecation")
+    private Argument getAndConvertDeprecatedArgument(Field field) {
+        final org.apache.felix.gogo.commands.Argument oldArgument = field.getAnnotation(org.apache.felix.gogo.commands.Argument.class);
+        if (oldArgument == null) {
+            return null;
+        }
+        return new Argument() {
+            
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return Argument.class;
+            }
+            
+            @Override
+            public String valueToShowInHelp() {
+                return oldArgument.valueToShowInHelp();
+            }
+            
+            @Override
+            public boolean required() {
+                return oldArgument.required();
+            }
+            
+            @Override
+            public String name() {
+                return oldArgument.name();
+            }
+            
+            @Override
+            public boolean multiValued() {
+                return oldArgument.multiValued();
+            }
+            
+            @Override
+            public int index() {
+                return oldArgument.index();
+            }
+            
+            @Override
+            public String description() {
+                return oldArgument.description();
+            }
+        };
+    }
+
+    private Argument replaceDefaultArgument(Field field, Argument argument) {
+        if (Argument.DEFAULT.equals(argument.name())) {
+            final Argument delegate = argument;
+            final String name = field.getName();
+            argument = new Argument() {
+                public String name() {
+                    return name;
+                }
+
+                public String description() {
+                    return delegate.description();
+                }
+
+                public boolean required() {
+                    return delegate.required();
+                }
+
+                public int index() {
+                    return delegate.index();
+                }
+
+                public boolean multiValued() {
+                    return delegate.multiValued();
+                }
+
+                public String valueToShowInHelp() {
+                    return delegate.valueToShowInHelp();
+                }
+
+                public Class<? extends Annotation> annotationType() {
+                    return delegate.annotationType();
+                }
+            };
+        }
+        return argument;
+    }
+    
+    private void assertIndexesAreCorrect(Class<? extends Action> actionClass, List<Argument> orderedArguments) {
+        for (int i = 0; i < orderedArguments.size(); i++) {
+            if (orderedArguments.get(i) == null) {
+                throw new IllegalArgumentException("Missing argument for index: " + i + " on Action " + actionClass.getName());
+            }
+        }
+    }
+}

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java Fri May 11 08:39:18 2012
@@ -21,11 +21,11 @@ import java.lang.reflect.Type;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.felix.service.command.CommandSession;
 import org.apache.karaf.shell.commands.Action;
 import org.apache.karaf.shell.commands.basic.AbstractCommand;
 import org.apache.karaf.shell.commands.basic.ActionPreparator;
 import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
-import org.apache.felix.service.command.CommandSession;
 import org.apache.karaf.shell.console.BlueprintContainerAware;
 import org.apache.karaf.shell.console.BundleContextAware;
 import org.apache.karaf.shell.console.CompletableFunction;

Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java Fri May 11 08:39:18 2012
@@ -0,0 +1,58 @@
+/*
+ * 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.util;
+
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class IndentFormatter {
+
+    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out, boolean prefixFirstLine) {
+        int pfxLen = prefix.length();
+        int maxwidth = termWidth - pfxLen;
+        Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
+        int cur = 0;
+        while (cur >= 0) {
+            int lst = str.indexOf('\n', cur);
+            String s = (lst >= 0) ? str.substring(cur, lst) : str.substring(cur);
+            if (s.length() == 0) {
+                out.println();
+            } else {
+                Matcher m = wrap.matcher(s);
+                while (m.find()) {
+                    if (cur > 0 || prefixFirstLine) {
+                        out.print(prefix);
+                    }
+                    out.println(m.group());
+                }
+            }
+            if (lst >= 0) {
+                cur = lst + 1;
+            } else {
+                break;
+            }
+        }
+    }
+
+    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
+        printFormatted(prefix, str, termWidth, out, true);
+    }
+
+}

Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java Fri May 11 08:39:18 2012
@@ -19,6 +19,10 @@
 package org.apache.karaf.shell.util;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
@@ -181,4 +185,32 @@ public class ShellUtil {
         }
     }
 
+    public static String loadClassPathResource(Class<?> clazz, String path) {
+        InputStream is = clazz.getResourceAsStream(path);
+        if (is == null) {
+            is = clazz.getClassLoader().getResourceAsStream(path);
+        }
+        if (is == null) {
+            return "Unable to load description from " + path;
+        }
+        
+        try {
+            Reader r = new InputStreamReader(is);
+            StringWriter sw = new StringWriter();
+            int c;
+            while ((c = r.read()) != -1) {
+                sw.append((char) c);
+            }
+            return sw.toString();
+        } catch (IOException e) {
+            return "Unable to load description from " + path;
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+                // Ignore
+            }
+        }
+    }
+
 }

Copied: karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java (from r1336532, karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java)
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java?p2=karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java&p1=karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java&r1=1336532&r2=1337063&rev=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java (original)
+++ karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java Fri May 11 08:39:18 2012
@@ -16,19 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.karaf.shell.console.help;
+package org.apache.karaf.shell.util;
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 
 import junit.framework.TestCase;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
+
+import org.apache.karaf.shell.util.IndentFormatter;
 
 public class TestFormatting extends TestCase {
     
     public void testFormat() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        DefaultActionPreparator.printFormatted("  ",
+        IndentFormatter.printFormatted("  ",
                 "  This is a test with a long paragraph\n\n  with an indented paragraph\nAnd another one\n", 20, new PrintStream(baos, true));
         System.err.println(baos.toString());
     }

Modified: karaf/trunk/shell/help/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/pom.xml?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/pom.xml (original)
+++ karaf/trunk/shell/help/pom.xml Fri May 11 08:39:18 2012
@@ -45,6 +45,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.table</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
             <artifactId>org.apache.karaf.shell.console</artifactId>
         </dependency>
         <dependency>

Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java Fri May 11 08:39:18 2012
@@ -20,22 +20,24 @@ package org.apache.karaf.shell.help.impl
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
 import jline.Terminal;
+
 import org.apache.felix.gogo.runtime.CommandSessionImpl;
 import org.apache.felix.service.command.CommandSession;
 import org.apache.felix.service.command.Function;
 import org.apache.karaf.shell.commands.Action;
 import org.apache.karaf.shell.commands.Command;
 import org.apache.karaf.shell.commands.basic.AbstractCommand;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
+import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
 import org.apache.karaf.shell.console.HelpProvider;
 import org.apache.karaf.shell.console.NameScoping;
+import org.apache.karaf.shell.table.Col;
+import org.apache.karaf.shell.table.ShellTable;
 import org.fusesource.jansi.Ansi;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -68,11 +70,8 @@ public class CommandListHelpProvider imp
             function = unProxy(function);
             if (function instanceof AbstractCommand) {
                 try {
-                    Method mth = AbstractCommand.class.getDeclaredMethod("createNewAction");
-                    mth.setAccessible(true);
-                    Action action = (Action) mth.invoke(function);
-                    Class<? extends Action> clazz = action.getClass();
-                    Command ann = clazz.getAnnotation(Command.class);
+                    Class<? extends Action> actionClass = ((AbstractCommand) function).getActionClass();                    
+                    Command ann = new ActionMetaDataFactory().getCommand(actionClass);
                     description = ann.description();
                 } catch (Throwable e) {
                 }
@@ -87,43 +86,16 @@ public class CommandListHelpProvider imp
 
     protected void printMethodList(CommandSession session, PrintStream out, SortedMap<String, String> commands) {
         Terminal term = (Terminal) session.get(".jline.terminal");
+        int termWidth = term != null ? term.getWidth() : 80;
         out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("COMMANDS").a(Ansi.Attribute.RESET));
-        int max = 0;
+        ShellTable table = new ShellTable().noHeaders().separator(" ").size(termWidth);
+        table.column(new Col("Command").maxSize(35));
+        table.column(new Col("Description"));
         for (Map.Entry<String,String> entry : commands.entrySet()) {
             String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-            max = Math.max(max,key.length());
-        }
-        int margin = 4;
-        String prefix1 = "        ";
-        if (term != null && term.getWidth() - max - prefix1.length() - margin > 50) {
-            String prefix2 = prefix1;
-            for (int i = 0; i < max + margin; i++) {
-                prefix2 += " ";
-            }
-            for (Map.Entry<String,String> entry : commands.entrySet()) {
-                out.print(prefix1);
-                String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-                out.print(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
-                for (int i = 0; i < max - key.length() + margin; i++) {
-                    out.print(' ');
-                }
-                if (entry.getValue() != null) {
-                    DefaultActionPreparator.printFormatted(prefix2, entry.getValue(), term.getWidth(), out, false);
-                }
-            }
-        } else {
-            String prefix2 = prefix1 + prefix1;
-            for (Map.Entry<String,String> entry : commands.entrySet()) {
-                out.print(prefix1);
-                String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-                out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
-                if (entry.getValue() != null) {
-                    DefaultActionPreparator.printFormatted(prefix2, entry.getValue(),
-                            term != null ? term.getWidth() : 80, out);
-                }
-            }
+            table.addRow().addContent(key, entry.getValue());
         }
-        out.println();
+        table.print(out);
     }
     
     protected Function unProxy(Function function) {

Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java Fri May 11 08:39:18 2012
@@ -17,34 +17,9 @@
  */
 package org.apache.karaf.shell.help.impl;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import jline.Terminal;
-import org.apache.felix.service.command.Function;
-import org.apache.karaf.shell.commands.Action;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.basic.AbstractCommand;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
 import org.apache.karaf.shell.console.AbstractAction;
-import org.apache.karaf.shell.console.NameScoping;
-import org.apache.karaf.shell.console.SubShell;
-import org.fusesource.jansi.Ansi;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 
 /**
  * Displays help on the available commands
@@ -69,122 +44,4 @@ public class HelpAction extends Abstract
         return null;
     }
 
-    private SortedMap<String, String> getCommandDescriptions(Set<String> names) {
-        SortedMap<String,String> commands = new TreeMap<String,String>();
-        for (String name : names) {
-            if (command != null && !name.startsWith(command)) {
-                continue;
-            }
-            String description = null;
-            Function function = (Function) session.get(name);
-            function = unProxy(function);
-            if (function instanceof AbstractCommand) {
-                try {
-                    Method mth = AbstractCommand.class.getDeclaredMethod("createNewAction");
-                    mth.setAccessible(true);
-                    Action action = (Action) mth.invoke(function);
-                    Class<? extends Action> clazz = action.getClass();
-                    Command ann = clazz.getAnnotation(Command.class);
-                    description = ann.description();
-                } catch (Throwable e) {
-                }
-                if (name.startsWith("*:")) {
-                    name = name.substring(2);
-                }
-                commands.put(name, description);
-            }
-        }
-        return commands;
-    }
-
-    private void printMethodList(Terminal term, PrintStream out, SortedMap<String, String> commands) {
-        out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("COMMANDS").a(Ansi.Attribute.RESET));
-//        int max = 0;
-//        for (Map.Entry<String,String> entry : commands.entrySet()) {
-//            String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-//            max = Math.max(max,key.length());
-//        }
-        for (Map.Entry<String,String> entry : commands.entrySet()) {
-            out.print("        ");
-            String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
-            if (entry.getValue() != null) {
-                DefaultActionPreparator.printFormatted("                ", entry.getValue(),
-                        term != null ? term.getWidth() : 80, out);
-            }
-        }
-        out.println();
-    }
-
-    private void printSubShellHelp(Bundle bundle, SubShell subShell, PrintStream out) {
-        Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
-        out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SUBSHELL").a(Ansi.Attribute.RESET));
-        out.print("        ");
-        if (subShell.getName() != null) {
-            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(subShell.getName()).a(Ansi.Attribute.RESET));
-            out.println();
-        }
-        out.print("\t");
-        out.println(subShell.getDescription());
-        out.println();
-        if (subShell.getDetailedDescription() != null) {
-            out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
-            String desc = loadDescription(bundle, subShell.getDetailedDescription());
-            DefaultActionPreparator.printFormatted("        ", desc, term != null ? term.getWidth() : 80, out);
-        }
-    }
-
-    protected String loadDescription(Bundle bundle, String desc) {
-        if (desc.startsWith("classpath:")) {
-            URL url = bundle.getResource(desc.substring("classpath:".length()));
-            if (url == null) {
-                desc = "Unable to load description from " + desc;
-            } else {
-                InputStream is = null;
-                try {
-                    is = url.openStream();
-                    Reader r = new InputStreamReader(is);
-                    StringWriter sw = new StringWriter();
-                    int c;
-                    while ((c = r.read()) != -1) {
-                        sw.append((char) c);
-                    }
-                    desc = sw.toString();
-                } catch (IOException e) {
-                    desc = "Unable to load description from " + desc;
-                } finally {
-                    try {
-                        is.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
-        return desc;
-    }
-
-    protected Function unProxy(Function function) {
-        try {
-            if (function.getClass().getName().contains("CommandProxy")) {
-                Field contextField = function.getClass().getDeclaredField("context");
-                Field referenceField = function.getClass().getDeclaredField("reference");
-                contextField.setAccessible(true);
-                referenceField.setAccessible(true);
-                BundleContext context = (BundleContext) contextField.get(function);
-                ServiceReference reference = (ServiceReference) referenceField.get(function);
-                Object target = context.getService(reference);
-                try {
-                    if (target instanceof Function) {
-                        function = (Function) target;
-                    }
-                } finally {
-                    context.ungetService(reference);
-                }
-            }
-        } catch (Throwable t) {
-        }
-        return function;
-    }
-
 }

Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java Fri May 11 08:39:18 2012
@@ -17,13 +17,9 @@
  */
 package org.apache.karaf.shell.help.impl;
 
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
 import java.util.Map;
 
-import jline.Terminal;
 import org.apache.felix.service.command.CommandSession;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
 import org.apache.karaf.shell.console.HelpProvider;
 
 public class SimpleHelpProvider implements HelpProvider {
@@ -47,12 +43,6 @@ public class SimpleHelpProvider implemen
             }
         }
         String str = help.get(path);
-        if (str != null) {
-            Terminal term = (Terminal) session.get(".jline.terminal");
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            DefaultActionPreparator.printFormatted("", str, term != null ? term.getWidth() : 80, new PrintStream(baos, true));
-            str = baos.toString();
-        }
         return str;
     }
 }

Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java Fri May 11 08:39:18 2012
@@ -27,10 +27,12 @@ import java.io.StringWriter;
 import java.net.URL;
 
 import jline.Terminal;
+
 import org.apache.felix.service.command.CommandSession;
 import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
 import org.apache.karaf.shell.console.HelpProvider;
 import org.apache.karaf.shell.console.SubShell;
+import org.apache.karaf.shell.util.IndentFormatter;
 import org.fusesource.jansi.Ansi;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -90,7 +92,7 @@ public class SubShellHelpProvider implem
             while (desc.endsWith("\n")) {
                 desc = desc.substring(0, desc.length()  -1);
             }
-            DefaultActionPreparator.printFormatted("        ", desc, term != null ? term.getWidth() : 80, out);
+            IndentFormatter.printFormatted("        ", desc, term != null ? term.getWidth() : 80, out);
         }
         out.println();
         out.println("${command-list|" + subShell.getName() + ":}");