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:33 UTC

[sling-org-apache-sling-testing-osgi-mock] 11/23: SLING-4142 MockOsgi: Activate/Deactivate method does not support different signatures

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 59f74f698a3683ce4270f6c6effc275005325808
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Fri Nov 7 00:08:14 2014 +0000

    SLING-4142 MockOsgi: Activate/Deactivate method does not support different signatures
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1637273 13f79535-47bb-0310-9956-ffa450edef68
---
 .../testing/mock/osgi/ReflectionServiceUtil.java   | 112 +++++++-
 ...eflectionServiceUtilActivateDeactivateTest.java | 285 +++++++++++++++++++++
 ...ReflectionServiceUtilActivateDeactivateTest.xml |  21 ++
 3 files changed, 405 insertions(+), 13 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 fe363ab..1ee8370 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
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
@@ -70,24 +71,78 @@ final class ReflectionServiceUtil {
             return false;
         }
 
-        // if method is defined try to execute it
+        // try to find matchin activate/deactivate method and execute it
+        
+        // 1. componentContext
         Method method = getMethod(targetClass, methodName, new Class<?>[] { ComponentContext.class }, activate);
         if (method != null) {
-            try {
-                method.setAccessible(true);
-                method.invoke(target, componentContext);
+            invokeMethod(target, method, new Object[] { componentContext });
+            return true;
+        }
+        
+        // 2. bundleContext
+        method = getMethod(targetClass, methodName, new Class<?>[] { BundleContext.class }, activate);
+        if (method != null) {
+            invokeMethod(target, method, new Object[] { componentContext.getBundleContext() });
+            return true;
+        }
+        
+        // 3. map
+        method = getMethod(targetClass, methodName, new Class<?>[] { Map.class }, activate);
+        if (method != null) {
+            invokeMethod(target, method, new Object[] { componentContext.getProperties() });
+            return true;
+        }
+        
+        // 4. int (deactivation only)
+        if (!activate) {
+            method = getMethod(targetClass, methodName, new Class<?>[] { int.class }, activate);
+            if (method != null) {
+                invokeMethod(target, method, new Object[] { 0 });
+                return true;
+            }
+        }
+        
+        // 5. Integer (deactivation only)
+        if (!activate) {
+            method = getMethod(targetClass, methodName, new Class<?>[] { Integer.class }, activate);
+            if (method != null) {
+                invokeMethod(target, method, new Object[] { 0 });
                 return true;
-            } catch (IllegalAccessException ex) {
-                throw new RuntimeException("Unable to invoke activate/deactivate method for class "
-                        + targetClass.getName(), ex);
-            } catch (IllegalArgumentException ex) {
-                throw new RuntimeException("Unable to invoke activate/deactivate method for class "
-                        + targetClass.getName(), ex);
-            } catch (InvocationTargetException ex) {
-                throw new RuntimeException("Unable to invoke activate/deactivate method for class "
-                        + targetClass.getName(), ex.getCause());
             }
         }
+        
+        // 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);
+        if (method != null) {
+            Object[] args = new Object[method.getParameterTypes().length];
+            for (int i=0; i<args.length; i++) {
+                if (method.getParameterTypes()[i] == ComponentContext.class) {
+                    args[i] = componentContext;
+                }
+                else if (method.getParameterTypes()[i] == BundleContext.class) {
+                    args[i] = componentContext.getBundleContext();
+                }
+                else if (method.getParameterTypes()[i] == Map.class) {
+                    args[i] = componentContext.getProperties();
+                }
+                else if (method.getParameterTypes()[i] == int.class || method.getParameterTypes()[i] == Integer.class) {
+                    args[i] = 0;
+                }
+            }
+            invokeMethod(target, method, args);
+            return true;
+        }
+
+        // 7. noargs
+        method = getMethod(targetClass, methodName, new Class<?>[0], activate);
+        if (method != null) {
+            invokeMethod(target, method, new Object[0]);
+            return true;
+        }
+        
         log.warn("Method {}(ComponentContext) not found in class {}", methodName, targetClass.getName());
         return false;
     }
@@ -102,6 +157,37 @@ final class ReflectionServiceUtil {
         }
         return null;
     }
+    
+    private static Method getMethodWithAnyCombinationArgs(Class clazz, String methodName, Class<?>[] types, boolean activate) {
+        Method[] methods = clazz.getDeclaredMethods();
+        for (Method method : methods) {
+            if (StringUtils.equals(method.getName(), methodName) && method.getParameterTypes().length > 1) {
+                for (Class<?> parameterType : method.getParameterTypes()) {
+                    if (!ArrayUtils.contains(types,  parameterType)) {
+                        return null;
+                    }
+                }
+                return method;
+            }
+        }
+        return null;
+    }
+    
+    private static void invokeMethod(Object target, Method method, Object[] args) {
+        try {
+            method.setAccessible(true);
+            method.invoke(target, args);
+        } catch (IllegalAccessException ex) {
+            throw new RuntimeException("Unable to invoke activate/deactivate method for class "
+                    + target.getClass().getName(), ex);
+        } catch (IllegalArgumentException ex) {
+            throw new RuntimeException("Unable to invoke activate/deactivate method for class "
+                    + target.getClass().getName(), ex);
+        } catch (InvocationTargetException ex) {
+            throw new RuntimeException("Unable to invoke activate/deactivate method for class "
+                    + target.getClass().getName(), ex.getCause());
+        }
+    }
 
     /**
      * Simulate OSGi service dependency injection. Injects direct references and
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilActivateDeactivateTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilActivateDeactivateTest.java
new file mode 100644
index 0000000..36cf88e
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/ReflectionServiceUtilActivateDeactivateTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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.sling.testing.mock.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test different variants of activate/deactivate methods with varying signatures.
+ */
+public class ReflectionServiceUtilActivateDeactivateTest {
+
+    private Map<String,Object> map = ImmutableMap.<String, Object>of("prop1", "value1");
+    private BundleContext bundleContext = MockOsgi.newBundleContext();
+    
+    @Test
+    public void testService1() {
+        Service1 service = new Service1();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        assertSame(bundleContext, service.getComponentContext().getBundleContext());
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Test
+    public void testService2() {
+        Service2 service = new Service2();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        assertSame(bundleContext, service.getBundleContext());
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Test
+    public void testService3() {
+        Service3 service = new Service3();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        assertEquals(map, ImmutableMap.copyOf(service.getMap()));
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Test
+    public void testService4() {
+        Service4 service = new Service4();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Test
+    public void testService5() {
+        Service5 service = new Service5();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Test
+    public void testService6() {
+        Service6 service = new Service6();
+        
+        assertTrue(MockOsgi.activate(service, bundleContext, map));
+        assertTrue(service.isActivated());
+        assertSame(bundleContext, service.getComponentContext().getBundleContext());
+        assertSame(bundleContext, service.getBundleContext());
+        assertEquals(map, ImmutableMap.copyOf(service.getMap()));
+        
+        assertTrue(MockOsgi.deactivate(service, bundleContext, map));
+        assertFalse(service.isActivated());
+    }
+
+    @Component
+    public static class Service1 {
+        
+        private boolean activated;
+        private ComponentContext componentContext;
+
+        @Activate
+        private void activate(ComponentContext ctx) {
+            this.activated = true;
+            this.componentContext = ctx;
+        }
+
+        @Deactivate
+        private void deactivate(ComponentContext ctx) {
+            this.activated = false;
+            this.componentContext = null;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+        public ComponentContext getComponentContext() {
+            return componentContext;
+        }
+
+    }
+
+    @Component
+    public static class Service2 {
+        
+        private boolean activated;
+        private BundleContext bundleContext;
+
+        @Activate
+        private void activate(BundleContext ctx) {
+            this.activated = true;
+            this.bundleContext = ctx;
+        }
+
+        @Deactivate
+        private void deactivate(BundleContext ctx) {
+            this.activated = false;
+            this.bundleContext = null;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+        public BundleContext getBundleContext() {
+            return bundleContext;
+        }
+
+    }
+
+    @Component
+    public static class Service3 {
+        
+        private boolean activated;
+        private Map<String, Object> map;
+
+        @Activate
+        private void activate(Map<String,Object> map) {
+            this.activated = true;
+            this.map = map;
+        }
+
+        @Deactivate
+        private void deactivate(Map<String,Object> map) {
+            this.activated = false;
+            this.map = null;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+        public Map<String, Object> getMap() {
+            return map;
+        }
+
+    }
+
+    @Component
+    public static class Service4 {
+        
+        private boolean activated;
+
+        @Activate
+        private void activate() {
+            this.activated = true;
+        }
+
+        @Deactivate
+        private void deactivate(int value) {
+            this.activated = false;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+    }
+
+    @Component
+    public static class Service5 {
+        
+        private boolean activated;
+
+        @Activate
+        private void activate() {
+            this.activated = true;
+        }
+
+        @Deactivate
+        private void deactivate(Integer value) {
+            this.activated = false;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+    }
+
+    @Component
+    public static class Service6 {
+        
+        private boolean activated;
+        private ComponentContext componentContext;
+        private BundleContext bundleContext;
+        private Map<String,Object> map;
+
+        @Activate
+        private void activate(ComponentContext componentContext, BundleContext bundleContext, Map<String,Object> map) {
+            this.activated = true;
+            this.componentContext = componentContext;
+            this.bundleContext = bundleContext;
+            this.map = map;
+        }
+
+        @Deactivate
+        private void deactivate(Map<String,Object> map, BundleContext bundleContext, int value1, Integer value2) {
+            this.activated = false;
+            this.componentContext = null;
+            this.bundleContext = null;
+            this.map = null;
+        }
+        
+        public boolean isActivated() {
+            return activated;
+        }
+
+        public ComponentContext getComponentContext() {
+            return componentContext;
+        }
+
+        public BundleContext getBundleContext() {
+            return bundleContext;
+        }
+
+        public Map<String, Object> getMap() {
+            return map;
+        }
+
+    }
+
+}
diff --git a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest.xml b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest.xml
new file mode 100644
index 0000000..23c4585
--- /dev/null
+++ b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service1" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service1"/>
+  </scr:component>
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service2" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service2"/>
+  </scr:component>
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service3" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service3"/>
+  </scr:component>
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service4" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service4"/>
+  </scr:component>
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service5" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service5"/>
+  </scr:component>
+  <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service6" activate="activate" deactivate="deactivate">
+    <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilActivateDeactivateTest$Service6"/>
+  </scr:component>
+</components>

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