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/09/15 08:52:46 UTC

[2/3] git commit: [KARAF-3221] Incorporate the fix for FELIX-4637 into shell/core, fix the scr commands to use a service.ranking property

[KARAF-3221] Incorporate the fix for FELIX-4637 into shell/core, fix the scr commands to use a service.ranking property


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

Branch: refs/heads/karaf-3.0.x
Commit: 9ad9fd54ec36d0719a3fa4ba01896a8d7dfed52d
Parents: 507b41d
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Sep 11 23:18:53 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon Sep 15 08:52:37 2014 +0200

----------------------------------------------------------------------
 .../scr/command/ActivateCommandComponent.java   |   4 +-
 .../scr/command/DeactivateCommandComponent.java |   4 +-
 .../scr/command/DetailsCommandComponent.java    |   4 +-
 .../karaf/scr/command/ListCommandComponent.java |   4 +-
 .../gogo/runtime/CommandProcessorImpl.java      | 358 +++++++++++++++++++
 .../impl/SecuredCommandProcessorImpl.java       |  20 +-
 6 files changed, 387 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/scr/command/src/main/java/org/apache/karaf/scr/command/ActivateCommandComponent.java
----------------------------------------------------------------------
diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/ActivateCommandComponent.java b/scr/command/src/main/java/org/apache/karaf/scr/command/ActivateCommandComponent.java
index d3b2607..46b9c21 100644
--- a/scr/command/src/main/java/org/apache/karaf/scr/command/ActivateCommandComponent.java
+++ b/scr/command/src/main/java/org/apache/karaf/scr/command/ActivateCommandComponent.java
@@ -30,6 +30,7 @@ import aQute.bnd.annotation.component.Activate;
 import aQute.bnd.annotation.component.Component;
 import aQute.bnd.annotation.component.Deactivate;
 import aQute.bnd.annotation.component.Reference;
+import org.osgi.framework.Constants;
 
 /**
  * Shell Command used to activate a Declarative Service Component.
@@ -42,7 +43,8 @@ import aQute.bnd.annotation.component.Reference;
         properties={
                 ScrCommandConstants.OSGI_COMMAND_SCOPE_KEY + "=" + ScrCommandConstants.SCR_COMMAND,
                 ScrCommandConstants.OSGI_COMMAND_FUNCTION_KEY + "=" + ScrCommandConstants.ACTIVATE_FUNCTION,
-                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true"
+                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true",
+                Constants.SERVICE_RANKING + "=1"
         })
 public class ActivateCommandComponent extends ScrCommandSupport {
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/scr/command/src/main/java/org/apache/karaf/scr/command/DeactivateCommandComponent.java
----------------------------------------------------------------------
diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/DeactivateCommandComponent.java b/scr/command/src/main/java/org/apache/karaf/scr/command/DeactivateCommandComponent.java
index ae2bf9f..c1cd01c 100644
--- a/scr/command/src/main/java/org/apache/karaf/scr/command/DeactivateCommandComponent.java
+++ b/scr/command/src/main/java/org/apache/karaf/scr/command/DeactivateCommandComponent.java
@@ -30,6 +30,7 @@ import aQute.bnd.annotation.component.Activate;
 import aQute.bnd.annotation.component.Component;
 import aQute.bnd.annotation.component.Deactivate;
 import aQute.bnd.annotation.component.Reference;
+import org.osgi.framework.Constants;
 
 /**
  * Shell Command used to deactivate a Declarative Service Component.
@@ -42,7 +43,8 @@ import aQute.bnd.annotation.component.Reference;
         properties={
                 ScrCommandConstants.OSGI_COMMAND_SCOPE_KEY + "=" + ScrCommandConstants.SCR_COMMAND,
                 ScrCommandConstants.OSGI_COMMAND_FUNCTION_KEY + "=" + ScrCommandConstants.DEACTIVATE_FUNCTION,
-                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true"
+                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true",
+                Constants.SERVICE_RANKING + "=1"
         })
 public class DeactivateCommandComponent extends ScrCommandSupport {
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java
----------------------------------------------------------------------
diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java b/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java
index 51407b0..51025ef 100644
--- a/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java
+++ b/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java
@@ -30,6 +30,7 @@ import aQute.bnd.annotation.component.Activate;
 import aQute.bnd.annotation.component.Component;
 import aQute.bnd.annotation.component.Deactivate;
 import aQute.bnd.annotation.component.Reference;
+import org.osgi.framework.Constants;
 
 /**
  * Shell Command that prints the current state details of a given
@@ -43,7 +44,8 @@ import aQute.bnd.annotation.component.Reference;
         properties={
                 ScrCommandConstants.OSGI_COMMAND_SCOPE_KEY + "=" + ScrCommandConstants.SCR_COMMAND,
                 ScrCommandConstants.OSGI_COMMAND_FUNCTION_KEY + "=" + ScrCommandConstants.DETAILS_FUNCTION,
-                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true"
+                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true",
+                Constants.SERVICE_RANKING + "=1"
         })
 public class DetailsCommandComponent extends ScrCommandSupport {
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/scr/command/src/main/java/org/apache/karaf/scr/command/ListCommandComponent.java
----------------------------------------------------------------------
diff --git a/scr/command/src/main/java/org/apache/karaf/scr/command/ListCommandComponent.java b/scr/command/src/main/java/org/apache/karaf/scr/command/ListCommandComponent.java
index 23d82f3..551f742 100644
--- a/scr/command/src/main/java/org/apache/karaf/scr/command/ListCommandComponent.java
+++ b/scr/command/src/main/java/org/apache/karaf/scr/command/ListCommandComponent.java
@@ -28,6 +28,7 @@ import aQute.bnd.annotation.component.Activate;
 import aQute.bnd.annotation.component.Component;
 import aQute.bnd.annotation.component.Deactivate;
 import aQute.bnd.annotation.component.Reference;
+import org.osgi.framework.Constants;
 
 /**
  * Shell Command that lists the available Declarative Service Components.
@@ -40,7 +41,8 @@ import aQute.bnd.annotation.component.Reference;
         properties={
                 ScrCommandConstants.OSGI_COMMAND_SCOPE_KEY + "=" + ScrCommandConstants.SCR_COMMAND,
                 ScrCommandConstants.OSGI_COMMAND_FUNCTION_KEY + "=" + ScrCommandConstants.LIST_FUNCTION,
-                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true"
+                ScrCommandConstants.HIDDEN_COMPONENT_KEY + "=true",
+                Constants.SERVICE_RANKING + "=1"
         })
 public class ListCommandComponent extends ScrCommandSupport {
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/shell/console/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java b/shell/console/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
new file mode 100644
index 0000000..72cff88
--- /dev/null
+++ b/shell/console/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
@@ -0,0 +1,358 @@
+/*
+ * 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.runtime;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.apache.felix.gogo.api.CommandSessionListener;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.apache.felix.service.command.Function;
+import org.apache.felix.service.threadio.ThreadIO;
+
+/**
+ * TODO: remove this class when upgraded to gogo-runtime >= 0.12.2, see FELIX-4637 / KARAF-3221
+ */
+public class CommandProcessorImpl implements CommandProcessor
+{
+    protected final Set<Converter> converters = new CopyOnWriteArraySet<Converter>();
+    protected final Set<CommandSessionListener> listeners = new CopyOnWriteArraySet<CommandSessionListener>();
+    protected final ConcurrentMap<String, Map<Object, Integer>> commands = new ConcurrentHashMap<String, Map<Object, Integer>>();
+    protected final Map<String, Object> constants = new ConcurrentHashMap<String, Object>();
+    protected final ThreadIO threadIO;
+    protected final WeakHashMap<CommandSession, Object> sessions = new WeakHashMap<CommandSession, Object>();
+    protected boolean stopped;
+
+    public CommandProcessorImpl(ThreadIO tio)
+    {
+        threadIO = tio;
+    }
+
+    public CommandSession createSession(InputStream in, PrintStream out, PrintStream err)
+    {
+        synchronized (sessions)
+        {
+            if (stopped) {
+                throw new IllegalStateException("CommandProcessor has been stopped");
+            }
+            CommandSessionImpl session = new CommandSessionImpl(this, in, out, err);
+            sessions.put(session, null);
+            return session;
+        }
+    }
+
+    public void stop()
+    {
+        synchronized (sessions)
+        {
+            stopped = true;
+            for (CommandSession session : sessions.keySet())
+            {
+                session.close();
+            }
+        }
+    }
+
+    public void addConverter(Converter c)
+    {
+        converters.add(c);
+    }
+
+    public void removeConverter(Converter c)
+    {
+        converters.remove(c);
+    }
+
+    public void addListener(CommandSessionListener l)
+    {
+        listeners.add(l);
+    }
+
+    public void removeListener(CommandSessionListener l)
+    {
+        listeners.remove(l);
+    }
+
+    public Set<String> getCommands()
+    {
+        return Collections.unmodifiableSet(commands.keySet());
+    }
+
+    Function getCommand(String name, final Object path)
+    {
+        int colon = name.indexOf(':');
+
+        if (colon < 0)
+        {
+            return null;
+        }
+
+        name = name.toLowerCase();
+        String cfunction = name.substring(colon);
+        boolean anyScope = (colon == 1 && name.charAt(0) == '*');
+
+        Map<Object, Integer> cmdMap = commands.get(name);
+
+        if (null == cmdMap && anyScope)
+        {
+            String scopePath = (null == path ? "*" : path.toString());
+
+            for (String scope : scopePath.split(":"))
+            {
+                if (scope.equals("*"))
+                {
+                    for (Entry<String, Map<Object, Integer>> entry : commands.entrySet())
+                    {
+                        if (entry.getKey().endsWith(cfunction))
+                        {
+                            cmdMap = entry.getValue();
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    cmdMap = commands.get(scope + cfunction);
+                    if (cmdMap != null)
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+
+        Object cmd = null;
+        if (cmdMap != null && !cmdMap.isEmpty())
+        {
+            for (Entry<Object, Integer> e : cmdMap.entrySet())
+            {
+                if (cmd == null || e.getValue() > cmdMap.get(cmd))
+                {
+                    cmd = e.getKey();
+                }
+            }
+        }
+        if ((null == cmd) || (cmd instanceof Function))
+        {
+            return (Function) cmd;
+        }
+
+        return new CommandProxy(cmd, cfunction.substring(1));
+    }
+
+    public void addCommand(String scope, Object target)
+    {
+        Class<?> tc = (target instanceof Class<?>) ? (Class<?>) target
+            : target.getClass();
+        addCommand(scope, target, tc);
+    }
+
+    public void addCommand(String scope, Object target, Class<?> functions)
+    {
+        addCommand(scope, target, functions, 0);
+    }
+
+    public void addCommand(String scope, Object target, Class<?> functions, int ranking)
+    {
+        if (target == null)
+        {
+            return;
+        }
+
+        String[] names = getFunctions(functions);
+        for (String function : names)
+        {
+            addCommand(scope, target, function, ranking);
+        }
+    }
+
+    public Object addConstant(String name, Object target)
+    {
+        return constants.put(name, target);
+    }
+
+    public Object removeConstant(String name)
+    {
+        return constants.remove(name);
+    }
+
+    public void addCommand(String scope, Object target, String function)
+    {
+        addCommand(scope, target, function, 0);
+    }
+
+    public void addCommand(String scope, Object target, String function, int ranking)
+    {
+        String key = (scope + ":" + function).toLowerCase();
+        Map<Object, Integer> cmdMap = commands.get(key);
+        if (cmdMap == null)
+        {
+            commands.putIfAbsent(key, new LinkedHashMap<Object, Integer>());
+            cmdMap = commands.get(key);
+        }
+        cmdMap.put(target, ranking);
+    }
+
+    public void removeCommand(String scope, String function)
+    {
+        // TODO: WARNING: this method does remove all mapping for scope:function
+        String key = (scope + ":" + function).toLowerCase();
+        commands.remove(key);
+    }
+
+    public void removeCommand(String scope, String function, Object target)
+    {
+        // TODO: WARNING: this method does remove all mapping for scope:function
+        String key = (scope + ":" + function).toLowerCase();
+        Map<Object, Integer> cmdMap = commands.get(key);
+        if (cmdMap != null)
+        {
+            cmdMap.remove(target);
+        }
+    }
+
+    public void removeCommand(Object target)
+    {
+        for (Map<Object, Integer> cmdMap : commands.values())
+        {
+            cmdMap.remove(target);
+        }
+    }
+
+    private String[] getFunctions(Class<?> target)
+    {
+        String[] functions;
+        Set<String> list = new TreeSet<String>();
+        Method methods[] = target.getMethods();
+        for (Method m : methods)
+        {
+            if (m.getDeclaringClass().equals(Object.class))
+            {
+                continue;
+            }
+            list.add(m.getName());
+            if (m.getName().startsWith("get"))
+            {
+                String s = m.getName().substring(3);
+                if (s.length() > 0)
+                {
+                    list.add(s.substring(0, 1).toLowerCase() + s.substring(1));
+                }
+            }
+        }
+
+        functions = list.toArray(new String[list.size()]);
+        return functions;
+    }
+
+    public Object convert(Class<?> desiredType, Object in)
+    {
+        for (Converter c : converters)
+        {
+            try
+            {
+                Object converted = c.convert(desiredType, in);
+                if (converted != null)
+                {
+                    return converted;
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    // eval is needed to force expansions to be treated as commands (FELIX-1473)
+    public Object eval(CommandSession session, Object[] argv) throws Exception
+    {
+        StringBuilder buf = new StringBuilder();
+
+        for (Object arg : argv)
+        {
+            if (buf.length() > 0)
+                buf.append(' ');
+            buf.append(arg);
+        }
+
+        return session.execute(buf);
+    }
+
+    void beforeExecute(CommandSession session, CharSequence commandline)
+    {
+        for (CommandSessionListener l : listeners)
+        {
+            try
+            {
+                l.beforeExecute(session, commandline);
+            }
+            catch (Throwable t)
+            {
+                // Ignore
+            }
+        }
+    }
+
+    void afterExecute(CommandSession session, CharSequence commandline,
+        Exception exception)
+    {
+        for (CommandSessionListener l : listeners)
+        {
+            try
+            {
+                l.afterExecute(session, commandline, exception);
+            }
+            catch (Throwable t)
+            {
+                // Ignore
+            }
+        }
+    }
+
+    void afterExecute(CommandSession session, CharSequence commandline, Object result)
+    {
+        for (CommandSessionListener l : listeners)
+        {
+            try
+            {
+                l.afterExecute(session, commandline, result);
+            }
+            catch (Throwable t)
+            {
+                // Ignore
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ad9fd54/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
----------------------------------------------------------------------
diff --git a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
index 3a83958..0e16a56 100644
--- a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
+++ b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
@@ -25,6 +25,7 @@ import org.apache.felix.service.command.Converter;
 import org.apache.felix.service.threadio.ThreadIO;
 import org.apache.karaf.jaas.boot.principal.RolePrincipal;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -114,8 +115,21 @@ public class SecuredCommandProcessorImpl extends CommandProcessorImpl {
             {
                 Object scope = reference.getProperty(CommandProcessor.COMMAND_SCOPE);
                 Object function = reference.getProperty(CommandProcessor.COMMAND_FUNCTION);
+                Object ranking = reference.getProperty(Constants.SERVICE_RANKING);
                 List<Object> commands = new ArrayList<Object>();
 
+                int rank = 0;
+                if (ranking != null)
+                {
+                    try
+                    {
+                        rank = Integer.parseInt(ranking.toString());
+                    }
+                    catch (NumberFormatException e)
+                    {
+                        // Ignore
+                    }
+                }
                 if (scope != null && function != null)
                 {
                     Map<String, CommandProxy> proxyMap = new HashMap<String, CommandProxy>();
@@ -125,7 +139,7 @@ public class SecuredCommandProcessorImpl extends CommandProcessorImpl {
                         {
                             CommandProxy target = new CommandProxy(context, reference, f.toString());
                             proxyMap.put(f.toString(), target);
-                            addCommand(scope.toString(), target, f.toString());
+                            addCommand(scope.toString(), target, f.toString(), rank);
                             commands.add(target);
                         }
                     }
@@ -133,7 +147,7 @@ public class SecuredCommandProcessorImpl extends CommandProcessorImpl {
                     {
                         CommandProxy target = new CommandProxy(context, reference, function.toString());
                         proxyMap.put(function.toString(), target);
-                        addCommand(scope.toString(), target, function.toString());
+                        addCommand(scope.toString(), target, function.toString(), rank);
                         commands.add(target);
                     }
                     proxies.put(reference, proxyMap);
@@ -153,7 +167,7 @@ public class SecuredCommandProcessorImpl extends CommandProcessorImpl {
                     Map<String, CommandProxy> proxyMap = proxies.remove(reference);
                     for (Map.Entry<String, CommandProxy> entry : proxyMap.entrySet())
                     {
-                        removeCommand(scope.toString(), entry.getKey());
+                        removeCommand(scope.toString(), entry.getKey(), entry.getValue());
                     }
                 }