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 2014/02/20 10:28:53 UTC

[1/2] git commit: [KARAF-2756] Fix completer arguments to handle more combinations of @Completer / @CompleterValues / CompletableFunction

Repository: karaf
Updated Branches:
  refs/heads/master b546fdf23 -> 8fd6385a6


[KARAF-2756] Fix completer arguments to handle more combinations of @Completer / @CompleterValues / CompletableFunction

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/10d8447f
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/10d8447f
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/10d8447f

Branch: refs/heads/master
Commit: 10d8447f58029e70d99b3a4ff825f02dd2be08f8
Parents: b546fdf
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Feb 20 10:23:58 2014 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Feb 20 10:24:18 2014 +0100

----------------------------------------------------------------------
 .../console/completer/ArgumentCompleter.java    | 239 ++++++++++---------
 1 file changed, 130 insertions(+), 109 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/10d8447f/shell/console/src/main/java/org/apache/karaf/shell/console/completer/ArgumentCompleter.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/karaf/shell/console/completer/ArgumentCompleter.java b/shell/console/src/main/java/org/apache/karaf/shell/console/completer/ArgumentCompleter.java
index 26090b0..745489e 100644
--- a/shell/console/src/main/java/org/apache/karaf/shell/console/completer/ArgumentCompleter.java
+++ b/shell/console/src/main/java/org/apache/karaf/shell/console/completer/ArgumentCompleter.java
@@ -22,6 +22,7 @@ import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.EnumSet;
@@ -101,82 +102,105 @@ public class ArgumentCompleter implements Completer {
         }
         options.put(HelpOption.HELP.name(), HelpOption.HELP);
         optionsCompleter = new StringsCompleter(options.keySet());
+
         // Build arguments completers
-        argsCompleters = new ArrayList<Completer>();
+        List<Completer> argsCompleters = null;
+        Map<String, Completer> optionalCompleters = null;
 
         if (function instanceof CompletableFunction) {
             Map<String, Completer> focl = ((CompletableFunction) function).getOptionalCompleters();
             List<Completer> fcl = ((CompletableFunction) function).getCompleters();
-            if (focl == null && fcl == null) {
-                boolean multi = false;
-                for (int key = 0; key < arguments.size(); key++) {
-                    Completer completer = null;
-                    Field field = arguments.get(key);
-                    if (field != null) {
-                        Argument argument = field.getAnnotation(Argument.class);
-                        multi = (argument != null && argument.multiValued());
-                        org.apache.karaf.shell.commands.Completer ann = field.getAnnotation(org.apache.karaf.shell.commands.Completer.class);
-                        if (ann != null) {
-                            Class clazz = ann.value();
-                            String[] values = ann.values();
-                            if (clazz != null) {
-                                if (values.length > 0 && clazz == StringsCompleter.class) {
-                                    completer = new StringsCompleter(values, ann.caseSensitive());
-                                } else {
-                                    BundleContext context = FrameworkUtil.getBundle(function.getClass()).getBundleContext();
-                                    completer = new ProxyServiceCompleter(context, clazz);
-                                }
+            if (focl != null || fcl != null) {
+                argsCompleters = new ArrayList<Completer>();
+                if (fcl != null) {
+                    for (Completer c : fcl) {
+                        argsCompleters.add(c == null ? NullCompleter.INSTANCE : c);
+                    }
+                }
+                optionalCompleters = focl;
+            }
+        }
+        if (argsCompleters == null) {
+            final Map<Integer, Object> values = getCompleterValues(function);
+            argsCompleters = new ArrayList<Completer>();
+            boolean multi = false;
+            for (int key = 0; key < arguments.size(); key++) {
+                Completer completer = null;
+                Field field = arguments.get(key);
+                if (field != null) {
+                    Argument argument = field.getAnnotation(Argument.class);
+                    multi = (argument != null && argument.multiValued());
+                    org.apache.karaf.shell.commands.Completer ann = field.getAnnotation(org.apache.karaf.shell.commands.Completer.class);
+                    if (ann != null) {
+                        Class clazz = ann.value();
+                        String[] value = ann.values();
+                        if (clazz != null) {
+                            if (value.length > 0 && clazz == StringsCompleter.class) {
+                                completer = new StringsCompleter(value, ann.caseSensitive());
+                            } else {
+                                BundleContext context = FrameworkUtil.getBundle(function.getClass()).getBundleContext();
+                                completer = new ProxyServiceCompleter(context, clazz);
                             }
                         }
+                    } else if (values.containsKey(key)) {
+                        Object value = values.get(key);
+                        if (value instanceof String[]) {
+                            completer = new StringsCompleter((String[]) value);
+                        } else if (value instanceof Collection) {
+                            completer = new StringsCompleter((Collection<String>) value);
+                        } else {
+                            LOGGER.warn("Could not use value " + value + " as set of completions!");
+                        }
+                    } else {
+                        completer = getDefaultCompleter(session, field);
                     }
-                    if (completer == null) {
-                        completer = NullCompleter.INSTANCE;
-                    }
-                    argsCompleters.add(completer);
                 }
-                if (argsCompleters.isEmpty() || !multi) {
-                    argsCompleters.add(NullCompleter.INSTANCE);
+                if (completer == null) {
+                    completer = NullCompleter.INSTANCE;
                 }
-                optionalCompleters = new HashMap<String, Completer>();
-                for (Option option : fields.keySet()) {
-                    Completer completer = null;
-                    Field field = fields.get(option);
-                    if (field != null) {
-                        org.apache.karaf.shell.commands.Completer ann = field.getAnnotation(org.apache.karaf.shell.commands.Completer.class);
-                        if (ann != null) {
-                            Class clazz = ann.value();
-                            String[] values = ann.values();
-                            if (clazz != null) {
-                                if (values.length > 0 && clazz == StringsCompleter.class) {
-                                    completer = new StringsCompleter(values, ann.caseSensitive());
-                                } else {
-                                    BundleContext context = FrameworkUtil.getBundle(function.getClass()).getBundleContext();
-                                    completer = new ProxyServiceCompleter(context, clazz);
-                                }
+                argsCompleters.add(completer);
+            }
+            if (argsCompleters.isEmpty() || !multi) {
+                argsCompleters.add(NullCompleter.INSTANCE);
+            }
+            optionalCompleters = new HashMap<String, Completer>();
+            for (Option option : fields.keySet()) {
+                Completer completer = null;
+                Field field = fields.get(option);
+                if (field != null) {
+                    org.apache.karaf.shell.commands.Completer ann = field.getAnnotation(org.apache.karaf.shell.commands.Completer.class);
+                    if (ann != null) {
+                        Class clazz = ann.value();
+                        String[] value = ann.values();
+                        if (clazz != null) {
+                            if (value.length > 0 && clazz == StringsCompleter.class) {
+                                completer = new StringsCompleter(value, ann.caseSensitive());
+                            } else {
+                                BundleContext context = FrameworkUtil.getBundle(function.getClass()).getBundleContext();
+                                completer = new ProxyServiceCompleter(context, clazz);
                             }
                         }
                     }
-                    if (completer == null) {
-                        completer = NullCompleter.INSTANCE;
-                    }
-                    optionalCompleters.put(option.name(), completer);
-                    if (option.aliases() != null) {
-                        for (String alias : option.aliases()) {
-                            optionalCompleters.put(alias, completer);
-                        }
-                    }
                 }
-            } else {
-                if (fcl != null) {
-                    for (Completer c : fcl) {
-                        argsCompleters.add(c == null ? NullCompleter.INSTANCE : c);
+                if (completer == null) {
+                    completer = NullCompleter.INSTANCE;
+                }
+                optionalCompleters.put(option.name(), completer);
+                if (option.aliases() != null) {
+                    for (String alias : option.aliases()) {
+                        optionalCompleters.put(alias, completer);
                     }
                 }
-                optionalCompleters = focl;
             }
-        } else {
-            optionalCompleters = new HashMap<String, Completer>();
-            final Map<Integer, Method> methods = new HashMap<Integer, Method>();
+        }
+        this.argsCompleters = argsCompleters;
+        this.optionalCompleters = optionalCompleters;
+    }
+
+    private Map<Integer, Object> getCompleterValues(CommandWithAction function) {
+        final Map<Integer, Object> values = new HashMap<Integer, Object>();
+        Action action = null;
+        try {
             for (Class<?> type = function.getActionClass(); type != null; type = type.getSuperclass()) {
                 for (Method method : type.getDeclaredMethods()) {
                     CompleterValues completerMethod = method.getAnnotation(CompleterValues.class);
@@ -185,65 +209,62 @@ public class ArgumentCompleter implements Completer {
                         Integer key = index;
                         if (index >= arguments.size() || index < 0) {
                             LOGGER.warn("Index out of range on @CompleterValues on class " + type.getName() + " for index: " + key + " see: " + method);
-                        }
-                        if (methods.containsKey(key)) {
+                        } else if (values.containsKey(key)) {
                             LOGGER.warn("Duplicate @CompleterMethod annotations on class " + type.getName() + " for index: " + key + " see: " + method);
                         } else {
-                            methods.put(key, method);
+                            try {
+                                Object value;
+                                if (Modifier.isStatic(method.getModifiers())) {
+                                    value = method.invoke(null);
+                                } else {
+                                    if (action == null) {
+                                        action = function.createNewAction();
+                                    }
+                                    value = method.invoke(action);
+                                }
+                                values.put(key, value);
+                            } catch (IllegalAccessException e) {
+                                LOGGER.warn("Could not invoke @CompleterMethod on " + function + ". " + e, e);
+                            } catch (InvocationTargetException e) {
+                                Throwable target = e.getTargetException();
+                                if (target == null) {
+                                    target = e;
+                                }
+                                LOGGER.warn("Could not invoke @CompleterMethod on " + function + ". " + target, target);
+                            }
                         }
                     }
                 }
             }
-            for (int i = 0, size = arguments.size(); i < size; i++) {
-                Completer argCompleter = NullCompleter.INSTANCE;
-                Method method = methods.get(i);
-                if (method != null) {
-                    // lets invoke the method
-                    Action action = function.createNewAction();
-                    try {
-                        Object value = method.invoke(action);
-                        if (value instanceof String[]) {
-                            argCompleter = new StringsCompleter((String[]) value);
-                        } else if (value instanceof Collection) {
-                            argCompleter = new StringsCompleter((Collection<String>) value);
-                        } else {
-                            LOGGER.warn("Could not use value " + value + " as set of completions!");
-                        }
-                    } catch (IllegalAccessException e) {
-                        LOGGER.warn("Could not invoke @CompleterMethod on " + function + ". " + e, e);
-                    } catch (InvocationTargetException e) {
-                        Throwable target = e.getTargetException();
-                        if (target == null) {
-                            target = e;
-                        }
-                        LOGGER.warn("Could not invoke @CompleterMethod on " + function + ". " + target, target);
-                    } finally {
-                        try {
-                            function.releaseAction(action);
-                        } catch (Exception e) {
-                            LOGGER.warn("Failed to release action: " + action + ". " + e, e);
-                        }
-                    }
-                } else {
-                    Field field = arguments.get(i);
-                    Class<?> type = field.getType();
-                    if (type.isAssignableFrom(File.class)) {
-                        argCompleter = new FileCompleter(session);
-                    } else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
-                        argCompleter = new StringsCompleter(new String[] {"false", "true"}, false);
-                    } else if (type.isAssignableFrom(Enum.class)) {
-                        Set<String> values = new HashSet<String>();
-                        for (Object o : EnumSet.allOf((Class<Enum>) type)) {
-                            values.add(o.toString());
-                        }
-                        argCompleter = new StringsCompleter(values, false);
-                    } else {
-                        // TODO any other completers we can add?
-                    }
+        } finally {
+            if (action != null) {
+                try {
+                    function.releaseAction(action);
+                } catch (Exception e) {
+                    LOGGER.warn("Failed to release action: " + action + ". " + e, e);
                 }
-                argsCompleters.add(argCompleter);
             }
         }
+        return values;
+    }
+
+    private Completer getDefaultCompleter(CommandSession session, Field field) {
+        Completer completer = null;
+        Class<?> type = field.getType();
+        if (type.isAssignableFrom(File.class)) {
+            completer = new FileCompleter(session);
+        } else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
+            completer = new StringsCompleter(new String[] {"false", "true"}, false);
+        } else if (type.isAssignableFrom(Enum.class)) {
+            Set<String> values = new HashSet<String>();
+            for (Object o : EnumSet.allOf((Class<Enum>) type)) {
+                values.add(o.toString());
+            }
+            completer = new StringsCompleter(values, false);
+        } else {
+            // TODO any other completers we can add?
+        }
+        return completer;
     }
 
     private String[] getNames(CommandSession session, String scopedCommand) {


[2/2] git commit: Fix SimpleCommand

Posted by gn...@apache.org.
Fix SimpleCommand

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/8fd6385a
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/8fd6385a
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/8fd6385a

Branch: refs/heads/master
Commit: 8fd6385a61aa707799955100d2a46e9b0acdbd01
Parents: 10d8447
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Feb 20 10:24:34 2014 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Thu Feb 20 10:24:34 2014 +0100

----------------------------------------------------------------------
 .../karaf/shell/commands/basic/SimpleCommand.java       | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/8fd6385a/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java b/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
index 6999236..4ea5dfc 100644
--- a/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
+++ b/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
@@ -23,6 +23,7 @@ import java.util.Hashtable;
 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.CommandWithAction;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.BundleContext;
 
@@ -62,8 +63,7 @@ public class SimpleCommand extends AbstractCommand {
         }
     }
 
-
-    public static ServiceRegistration<Function> export(BundleContext context, Class<? extends Action> actionClass)
+    public static ServiceRegistration export(BundleContext context, Class<? extends Action> actionClass)
     {
         Command cmd = actionClass.getAnnotation(Command.class);
         if (cmd == null)
@@ -71,10 +71,12 @@ public class SimpleCommand extends AbstractCommand {
             throw new IllegalArgumentException("Action class is not annotated with @Command");
         }
         Hashtable<String, String> props = new Hashtable<String, String>();
-        props.put("bundles.command.scope", cmd.scope());
-        props.put("bundles.command.function", cmd.name());
+        props.put("osgi.command.scope", cmd.scope());
+        props.put("osgi.command.function", cmd.name());
         SimpleCommand command = new SimpleCommand(actionClass);
-        return context.registerService(Function.class, command, props);
+        return context.registerService(
+                new String[] { Function.class.getName(), CommandWithAction.class.getName() },
+                command, props);
     }
 
 }