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>.