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/14 13:44:14 UTC

[04/15] git commit: [KARAF-2756] Define an annotation for completers and retrieve them from the OSGi Service Registry

[KARAF-2756] Define an annotation for completers and retrieve them from the OSGi Service Registry


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

Branch: refs/heads/master
Commit: ec6c1ba355556ddab7d0df9b7844aea0b6057f4b
Parents: d79376e
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Feb 12 22:23:48 2014 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Fri Feb 14 13:43:57 2014 +0100

----------------------------------------------------------------------
 .../apache/karaf/shell/commands/Completer.java  | 30 +++++++
 .../console/completer/ArgumentCompleter.java    | 93 ++++++++++++++++++--
 2 files changed, 118 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/ec6c1ba3/shell/console/src/main/java/org/apache/karaf/shell/commands/Completer.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/karaf/shell/commands/Completer.java b/shell/console/src/main/java/org/apache/karaf/shell/commands/Completer.java
new file mode 100644
index 0000000..6724dc6
--- /dev/null
+++ b/shell/console/src/main/java/org/apache/karaf/shell/commands/Completer.java
@@ -0,0 +1,30 @@
+/*
+ * 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.commands;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Completer {
+
+    Class<? extends org.apache.karaf.shell.console.Completer> value();
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/ec6c1ba3/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 967edb4..1424bd6 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
@@ -43,6 +43,9 @@ import org.apache.karaf.shell.console.CommandSessionHolder;
 import org.apache.karaf.shell.console.CompletableFunction;
 import org.apache.karaf.shell.console.Completer;
 import org.apache.karaf.shell.console.NameScoping;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -64,6 +67,7 @@ public class ArgumentCompleter implements Completer {
     final Map<Option, Field> fields = new HashMap<Option, Field>();
     final Map<String, Option> options = new HashMap<String, Option>();
     final Map<Integer, Field> arguments = new HashMap<Integer, Field>();
+    final Map<Field, org.apache.karaf.shell.commands.Completer> completerAnnotations = new HashMap<Field, org.apache.karaf.shell.commands.Completer>();
     boolean strict = true;
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -94,6 +98,12 @@ public class ArgumentCompleter implements Completer {
                         arguments.put(key, field);
                     }
                 }
+                if (option != null || argument != null) {
+                    org.apache.karaf.shell.commands.Completer completer = field.getAnnotation(org.apache.karaf.shell.commands.Completer.class);
+                    if (completer != null) {
+                        completerAnnotations.put(field, completer);
+                    }
+                }
             }
         }
         options.put(HelpOption.HELP.name(), HelpOption.HELP);
@@ -102,14 +112,61 @@ public class ArgumentCompleter implements Completer {
         argsCompleters = new ArrayList<Completer>();
 
         if (function instanceof CompletableFunction) {
-            optionalCompleters = ((CompletableFunction) function).getOptionalCompleters();
+            Map<String, Completer> focl = ((CompletableFunction) function).getOptionalCompleters();
             List<Completer> fcl = ((CompletableFunction) function).getCompleters();
-            if (fcl != null) {
-                for (Completer c : fcl) {
-                    argsCompleters.add(c == null ? NullCompleter.INSTANCE : c);
+            if (focl == null && fcl == null) {
+                for (int key = 0; key < arguments.size(); key++) {
+                    Completer completer = null;
+                    Field field = arguments.get(key);
+                    if (field != null) {
+                        org.apache.karaf.shell.commands.Completer ann = completerAnnotations.get(field);
+                        if (ann != null) {
+                            Class clazz = ann.value();
+                            if (clazz != null) {
+                                BundleContext context = FrameworkUtil.getBundle(function.getClass()).getBundleContext();
+                                completer = new ProxyServiceCompleter(context, clazz);
+                            }
+                        }
+                    }
+                    if (completer == null) {
+                        completer = NullCompleter.INSTANCE;
+                    }
+                    argsCompleters.add(completer);
+                }
+                if (argsCompleters.isEmpty()) {
+                    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 = completerAnnotations.get(field);
+                        if (ann != null) {
+                            Class clazz = ann.value();
+                            if (clazz != null) {
+                                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 {
-                argsCompleters.add(NullCompleter.INSTANCE);
+                if (fcl != null) {
+                    for (Completer c : fcl) {
+                        argsCompleters.add(c == null ? NullCompleter.INSTANCE : c);
+                    }
+                }
+                optionalCompleters = focl;
             }
         } else {
             optionalCompleters = new HashMap<String, Completer>();
@@ -454,4 +511,30 @@ public class ArgumentCompleter implements Completer {
             return this.bufferPosition;
         }
     }
+
+    public static class ProxyServiceCompleter implements Completer {
+        private final BundleContext context;
+        private final Class<? extends Completer> clazz;
+
+        public ProxyServiceCompleter(BundleContext context, Class<? extends Completer> clazz) {
+            this.context = context;
+            this.clazz = clazz;
+        }
+
+        @Override
+        public int complete(String buffer, int cursor, List<String> candidates) {
+            ServiceReference<? extends Completer> ref = context.getServiceReference(clazz);
+            if (ref != null) {
+                Completer completer = context.getService(ref);
+                if (completer != null) {
+                    try {
+                        return completer.complete(buffer, cursor, candidates);
+                    } finally {
+                        context.ungetService(ref);
+                    }
+                }
+            }
+            return -1;
+        }
+    }
 }