Enhance AbstractComponentManager.getMethod to specify whether only the declared methods
of the given class or also the super class methods should be considered. In addition,
the Class.getMethod method is not used anymore to comply with the specification stating
that the declared methods must be considered of a given class over any inherited (public)
methods.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@576355 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
index 3f7ca54..8ebd0fe 100644
--- a/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
@@ -731,41 +731,35 @@
      * @param name The name of the method.
      * @param parameterTypes The parameters to the method. Passing
      *      <code>null</code> is equivalent to using an empty array.
+     * @param only Whether to only look at the declared methods of the given
+     *      class or also inspect the super classes.
      *
      * @return The named method with enforced accessibility
      *
      * @throws NoSuchMethodException If no public or protected method with
      *      the given name can be found in the class or any of its super classes.
      */
-    static Method getMethod( Class clazz, String name, Class[] parameterTypes ) throws NoSuchMethodException
+    static Method getMethod( Class clazz, String name, Class[] parameterTypes, boolean only ) throws NoSuchMethodException
     {
-        // try the default mechanism first, which only yields public methods
-        try
-        {
-            return clazz.getMethod( name, parameterTypes );
-        }
-        catch ( NoSuchMethodException nsme )
-        {
-            // it is ok to not find a public method, try to find a protected now
-        }
-
-        // now use method declarations, requiring walking up the class
-        // hierarchy manually. this algorithm also returns protected methods
-        // which is, what we need here
         for ( ; clazz != null; clazz = clazz.getSuperclass() )
         {
             try
             {
+                // find the declared method in this class
                 Method method = clazz.getDeclaredMethod( name, parameterTypes );
 
-                // only accept a protected method, a public method should
-                // have been found above and neither private nor package
-                // protected methods are acceptable here
-                if ( Modifier.isProtected( method.getModifiers() ) )
+                // accept public and protected methods only and ensure accessibility
+                if ( Modifier.isPublic( method.getModifiers() ) || Modifier.isProtected( method.getModifiers() ) )
                 {
                     method.setAccessible( true );
                     return method;
                 }
+
+                // if only the clazz is to be scanned terminate here
+                if ( only )
+                {
+                    break;
+                }
             }
             catch ( NoSuchMethodException nsme )
             {
diff --git a/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
index 1311cdd..1563b3a 100644
--- a/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
@@ -171,7 +171,7 @@
         try
         {
             Method activateMethod = getMethod( implementationObject.getClass(), "activate", new Class[]
-                { ComponentContext.class } );
+                { ComponentContext.class }, false );
             activateMethod.invoke( implementationObject, new Object[]
                 { componentContext } );
         }
@@ -216,7 +216,7 @@
         try
         {
             Method deactivateMethod = getMethod( implementationObject.getClass(), "deactivate", new Class[]
-                { ComponentContext.class } );
+                { ComponentContext.class }, false );
             deactivateMethod.invoke( implementationObject, new Object[]
                 { componentContext } );
         }