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 <[email protected]> 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 "[email protected]" <[email protected]>.
