You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:18:36 UTC

[sling-org-apache-sling-testing-osgi-mock] 14/23: SLING-4163 OSGi Mock: Reference bind/unbind method picking order

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.osgi-mock-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git

commit c40b2dd59892d5723bed1caa280f9e9488ffb60a
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Fri Nov 14 16:16:48 2014 +0000

    SLING-4163 OSGi Mock: Reference bind/unbind method picking order
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1639692 13f79535-47bb-0310-9956-ffa450edef68
---
 .../testing/mock/osgi/ReflectionServiceUtil.java   | 155 ++++++++++-----------
 .../mock/osgi/ReflectionServiceUtilTest.java       |  16 ++-
 2 files changed, 81 insertions(+), 90 deletions(-)

diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtil.java
index 1ee8370..fa75ebf 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtil.java
@@ -74,21 +74,21 @@ final class ReflectionServiceUtil {
         // try to find matchin activate/deactivate method and execute it
         
         // 1. componentContext
-        Method method = getMethod(targetClass, methodName, new Class<?>[] { ComponentContext.class }, activate);
+        Method method = getMethod(targetClass, methodName, new Class<?>[] { ComponentContext.class });
         if (method != null) {
             invokeMethod(target, method, new Object[] { componentContext });
             return true;
         }
         
         // 2. bundleContext
-        method = getMethod(targetClass, methodName, new Class<?>[] { BundleContext.class }, activate);
+        method = getMethod(targetClass, methodName, new Class<?>[] { BundleContext.class });
         if (method != null) {
             invokeMethod(target, method, new Object[] { componentContext.getBundleContext() });
             return true;
         }
         
         // 3. map
-        method = getMethod(targetClass, methodName, new Class<?>[] { Map.class }, activate);
+        method = getMethod(targetClass, methodName, new Class<?>[] { Map.class });
         if (method != null) {
             invokeMethod(target, method, new Object[] { componentContext.getProperties() });
             return true;
@@ -96,7 +96,7 @@ final class ReflectionServiceUtil {
         
         // 4. int (deactivation only)
         if (!activate) {
-            method = getMethod(targetClass, methodName, new Class<?>[] { int.class }, activate);
+            method = getMethod(targetClass, methodName, new Class<?>[] { int.class });
             if (method != null) {
                 invokeMethod(target, method, new Object[] { 0 });
                 return true;
@@ -105,7 +105,7 @@ final class ReflectionServiceUtil {
         
         // 5. Integer (deactivation only)
         if (!activate) {
-            method = getMethod(targetClass, methodName, new Class<?>[] { Integer.class }, activate);
+            method = getMethod(targetClass, methodName, new Class<?>[] { Integer.class });
             if (method != null) {
                 invokeMethod(target, method, new Object[] { 0 });
                 return true;
@@ -115,7 +115,7 @@ final class ReflectionServiceUtil {
         // 6. mixed arguments of componentContext, bundleContext and map
         Class<?>[] mixedArgsAllowed = activate ? new Class<?>[] { ComponentContext.class, BundleContext.class, Map.class }
                 : new Class<?>[] { ComponentContext.class, BundleContext.class, Map.class, int.class, Integer.class };
-        method = getMethodWithAnyCombinationArgs(targetClass, methodName, mixedArgsAllowed, activate);
+        method = getMethodWithAnyCombinationArgs(targetClass, methodName, mixedArgsAllowed);
         if (method != null) {
             Object[] args = new Object[method.getParameterTypes().length];
             for (int i=0; i<args.length; i++) {
@@ -137,7 +137,7 @@ final class ReflectionServiceUtil {
         }
 
         // 7. noargs
-        method = getMethod(targetClass, methodName, new Class<?>[0], activate);
+        method = getMethod(targetClass, methodName, new Class<?>[0]);
         if (method != null) {
             invokeMethod(target, method, new Object[0]);
             return true;
@@ -147,18 +147,47 @@ final class ReflectionServiceUtil {
         return false;
     }
 
-    private static Method getMethod(Class clazz, String methodName, Class<?>[] signature, boolean activate) {
+    private static Method getMethod(Class clazz, String methodName, Class<?>[] types) {
         Method[] methods = clazz.getDeclaredMethods();
         for (Method method : methods) {
             if (StringUtils.equals(method.getName(), methodName)
-                    && Arrays.equals(method.getParameterTypes(), signature)) {
+                    && Arrays.equals(method.getParameterTypes(), types)) {
                 return method;
             }
         }
+        // not found? check super classes
+        Class<?> superClass = clazz.getSuperclass();
+        if (superClass != null && superClass != Object.class) {
+            return getMethod(superClass, methodName, types);
+        }
+        return null;
+    }
+    
+    private static Method getMethodWithAssignableTypes(Class clazz, String methodName, Class<?>[] types) {
+        Method[] methods = clazz.getDeclaredMethods();
+        for (Method method : methods) {
+            if (StringUtils.equals(method.getName(), methodName) && method.getParameterTypes().length==types.length) {
+                boolean foundMismatch = false;
+                for (int i=0; i<types.length; i++) {
+                    if (!method.getParameterTypes()[i].isAssignableFrom(types[i])) {
+                        foundMismatch = false;
+                        break;
+                    }
+                }
+                if (!foundMismatch) {
+                    return method;
+                }
+            }
+        }
+        // not found? check super classes
+        Class<?> superClass = clazz.getSuperclass();
+        if (superClass != null && superClass != Object.class) {
+            return getMethodWithAssignableTypes(superClass, methodName, types);
+        }
         return null;
     }
     
-    private static Method getMethodWithAnyCombinationArgs(Class clazz, String methodName, Class<?>[] types, boolean activate) {
+    private static Method getMethodWithAnyCombinationArgs(Class clazz, String methodName, Class<?>[] types) {
         Method[] methods = clazz.getDeclaredMethods();
         for (Method method : methods) {
             if (StringUtils.equals(method.getName(), methodName) && method.getParameterTypes().length > 1) {
@@ -170,6 +199,11 @@ final class ReflectionServiceUtil {
                 return method;
             }
         }
+        // not found? check super classes
+        Class<?> superClass = clazz.getSuperclass();
+        if (superClass != null && superClass != Object.class) {
+            return getMethodWithAnyCombinationArgs(superClass, methodName, types);
+        }
         return null;
     }
     
@@ -252,69 +286,38 @@ final class ReflectionServiceUtil {
         // try to invoke bind method
         String bindMethodName = reference.getBind();
         if (StringUtils.isNotEmpty(bindMethodName)) {
-            Method bindMethod = getFirstMethodWithNameAndSignature(targetClass, bindMethodName, new Class<?>[] { type });
+            
+            // 1. ServiceReference
+            Method bindMethod = getMethod(targetClass, bindMethodName, new Class<?>[] { ServiceReference.class });
             if (bindMethod != null) {
-                bindMethod.setAccessible(true);
                 for (ServiceInfo matchingService : matchingServices) {
-                    try {
-                        bindMethod.invoke(target, matchingService.getServiceInstance());
-                    } catch (IllegalAccessException ex) {
-                        throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                + targetClass.getName(), ex);
-                    } catch (IllegalArgumentException ex) {
-                        throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                + targetClass.getName(), ex);
-                    } catch (InvocationTargetException ex) {
-                        throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                + targetClass.getName(), ex.getCause());
-                    }
+                    invokeMethod(target, bindMethod, new Object[] { matchingService.getServiceReference() });
                 }
                 return true;
-            } else {
-                Method bindMethodWithConfig = getFirstMethodWithNameAndSignature(targetClass, bindMethodName,
-                        new Class<?>[] { type, Map.class });
-                if (bindMethodWithConfig != null) {
-                    bindMethodWithConfig.setAccessible(true);
-                    for (ServiceInfo matchingService : matchingServices) {
-                        try {
-                            bindMethodWithConfig.invoke(target, matchingService.getServiceInstance(),
-                                    matchingService.getServiceConfig());
-                        } catch (IllegalAccessException ex) {
-                            throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                    + targetClass.getName(), ex);
-                        } catch (IllegalArgumentException ex) {
-                            throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                    + targetClass.getName(), ex);
-                        } catch (InvocationTargetException ex) {
-                            throw new RuntimeException("Unable to invoke method " + bindMethodName + " for class "
-                                    + targetClass.getName(), ex.getCause());
-                        }
-                    }
-                    return true;
-                } else {
-                    Method bindMethodServiceReference = getFirstMethodWithNameAndSignature(targetClass, bindMethodName,
-                            new Class<?>[] { ServiceReference.class });
-                    if (bindMethodServiceReference != null) {
-                        bindMethodServiceReference.setAccessible(true);
-                        for (ServiceInfo matchingService : matchingServices) {
-                            if (matchingService.getServiceReference() != null) {
-                                try {
-                                    bindMethodServiceReference.invoke(target, matchingService.getServiceReference());
-                                } catch (IllegalAccessException ex) {
-                                    throw new RuntimeException("Unable to invoke method " + bindMethodName
-                                            + " for class " + targetClass.getName(), ex);
-                                } catch (IllegalArgumentException ex) {
-                                    throw new RuntimeException("Unable to invoke method " + bindMethodName
-                                            + " for class " + targetClass.getName(), ex);
-                                } catch (InvocationTargetException ex) {
-                                    throw new RuntimeException("Unable to invoke method " + bindMethodName
-                                            + " for class " + targetClass.getName(), ex.getCause());
-                                }
-                            }
-                        }
-                        return true;
-                    }
+            }
+            
+            // 2. assignable from service instance
+            Class<?> interfaceType;
+            try {
+                interfaceType = Class.forName(reference.getInterfaceType());
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException("Service reference type not found: " + reference.getInterfaceType());
+            }
+            bindMethod = getMethodWithAssignableTypes(targetClass, bindMethodName, new Class<?>[] { interfaceType });
+            if (bindMethod != null) {
+                for (ServiceInfo matchingService : matchingServices) {
+                    invokeMethod(target, bindMethod, new Object[] { matchingService.getServiceInstance() });
+                }
+                return true;
+            }
+            
+            // 3. assignable from service instance plus map
+            bindMethod = getMethodWithAssignableTypes(targetClass, bindMethodName, new Class<?>[] { interfaceType, Map.class });
+            if (bindMethod != null) {
+                for (ServiceInfo matchingService : matchingServices) {
+                    invokeMethod(target, bindMethod, new Object[] { matchingService.getServiceInstance(), matchingService.getServiceConfig() });
                 }
+                return true;
             }
         }
 
@@ -322,22 +325,6 @@ final class ReflectionServiceUtil {
         return false;
     }
 
-    private static Method getFirstMethodWithNameAndSignature(Class<?> clazz, String methodName, Class<?>[] signature) {
-        Method[] methods = clazz.getDeclaredMethods();
-        for (Method method : methods) {
-            if (StringUtils.equals(method.getName(), methodName)
-                    && Arrays.equals(method.getParameterTypes(), signature)) {
-                return method;
-            }
-        }
-        // not found? check super classes
-        Class<?> superClass = clazz.getSuperclass();
-        if (superClass != null && superClass != Object.class) {
-            return getFirstMethodWithNameAndSignature(superClass, methodName, signature);
-        }
-        return null;
-    }
-
     private static List<ServiceInfo> getMatchingServices(Class<?> type, BundleContext bundleContext) {
         List<ServiceInfo> matchingServices = new ArrayList<ServiceInfo>();
         try {
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilTest.java
index ff29037..6fd4ec2 100644
--- a/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilTest.java
@@ -78,7 +78,7 @@ public class ReflectionServiceUtilTest {
         assertEquals(1, references2.size());
         assertSame(service2, references2.get(0));
 
-        List<ServiceInterface3> references3 = service3.getReferences3();
+        List<ServiceSuperInterface3> references3 = service3.getReferences3();
         assertEquals(1, references3.size());
         assertSame(service2, references3.get(0));
 
@@ -108,7 +108,11 @@ public class ReflectionServiceUtilTest {
         // no methods
     }
 
-    public interface ServiceInterface3 {
+    public interface ServiceInterface3 extends ServiceSuperInterface3 {
+        // no methods
+    }
+
+    public interface ServiceSuperInterface3 {
         // no methods
     }
 
@@ -136,7 +140,7 @@ public class ReflectionServiceUtilTest {
         private List<ServiceReference> references2 = new ArrayList<ServiceReference>();
 
         @Reference(name = "reference3", referenceInterface = ServiceInterface3.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE)
-        private List<ServiceInterface3> references3 = new ArrayList<ServiceInterface3>();
+        private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
         private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();
 
         private ComponentContext componentContext;
@@ -163,7 +167,7 @@ public class ReflectionServiceUtilTest {
             return services;
         }
 
-        public List<ServiceInterface3> getReferences3() {
+        public List<ServiceSuperInterface3> getReferences3() {
             return this.references3;
         }
 
@@ -191,12 +195,12 @@ public class ReflectionServiceUtilTest {
             references2.remove(serviceReference);
         }
 
-        protected void bindReference3(ServiceInterface3 service, Map<String, Object> serviceConfig) {
+        protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
             references3.add(service);
             reference3Configs.add(serviceConfig);
         }
 
-        protected void unbindReference3(ServiceInterface3 service, Map<String, Object> serviceConfig) {
+        protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
             references3.remove(service);
             reference3Configs.remove(serviceConfig);
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.