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 7c2b51939974634ede6007737962ba9cf1db5e57 Author: Stefan Seifert <[email protected]> AuthorDate: Fri Nov 14 17:16:11 2014 +0000 SLING-4166 OSGi Mock: Support for "modified" SCR lifecycle method git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1639705 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/sling/testing/mock/osgi/MockOsgi.java | 36 ++++++++++++++++++++- .../sling/testing/mock/osgi/OsgiMetadataUtil.java | 19 +++++------ .../testing/mock/osgi/ReflectionServiceUtil.java | 31 +++++++++++++++--- .../mock/osgi/ReflectionServiceUtilTest.java | 37 +++++++++++++++++++++- ...testing.mock.osgi.ReflectionServiceUtilTest.xml | 2 +- 5 files changed, 109 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java index bffb7b3..395f2c6 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java @@ -19,6 +19,8 @@ package org.apache.sling.testing.mock.osgi; import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.Map; @@ -226,8 +228,40 @@ public final class MockOsgi { return deactivate(target, bundleContext, toDictionary(properties)); } - private static Dictionary<String, Object> toDictionary(Map<String, Object> map) { + /** + * Simulate configuration modification of service instance. Invokes the @Modified annotated method. + * @param target Service instance. + * @param bundleContext Bundle context + * @param properties Properties + * @return true if modified method was called. False if it failed. + */ + public static boolean modified(Object target, BundleContext bundleContext, Dictionary<String, Object> properties) { + return modified(target, bundleContext, toMap(properties)); + } + + /** + * Simulate configuration modification of service instance. Invokes the @Modified annotated method. + * @param target Service instance. + * @param bundleContext Bundle context + * @param properties Properties + * @return true if modified method was called. False if it failed. + */ + public static boolean modified(Object target, BundleContext bundleContext, Map<String, Object> properties) { + return ReflectionServiceUtil.modified(target, bundleContext, properties); + } + + static Dictionary<String, Object> toDictionary(Map<String, Object> map) { return new Hashtable<String, Object>(map); } + static Map<String, Object> toMap(Dictionary<String, Object> dictionary) { + Map<String,Object> map = new HashMap<String, Object>(); + Enumeration<String> keys = dictionary.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + map.put(key, dictionary.get(key)); + } + return map; + } + } diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java index da8bca0..a1b7a0a 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java @@ -178,22 +178,23 @@ final class OsgiMetadataUtil { } public static String getActivateMethodName(Class clazz, Document metadata) { - if (metadata != null) { - String query = "/components/component[@name='" + clazz.getName() + "']"; - Node node = queryNode(metadata, query); - if (node != null) { - return getAttributeValue(node, "activate"); - } - } - return null; + return getLifecycleMethodName(clazz, metadata, "activate"); } public static String getDeactivateMethodName(Class clazz, Document metadata) { + return getLifecycleMethodName(clazz, metadata, "deactivate"); + } + + public static String getModifiedMethodName(Class clazz, Document metadata) { + return getLifecycleMethodName(clazz, metadata, "modified"); + } + + private static String getLifecycleMethodName(Class clazz, Document metadata, String methodName) { if (metadata != null) { String query = "/components/component[@name='" + clazz.getName() + "']"; Node node = queryNode(metadata, query); if (node != null) { - return getAttributeValue(node, "deactivate"); + return getAttributeValue(node, methodName); } } return null; 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 fa75ebf..8269501 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 @@ -53,8 +53,7 @@ final class ReflectionServiceUtil { * Simulate activation or deactivation of OSGi service instance. * @param target Service instance. * @param componentContext Component context - * @return true if activation method was called. False if such a method did - * not exist. + * @return true if activation/deactivation method was called. False if it failed. */ public static boolean activateDeactivate(Object target, ComponentContext componentContext, boolean activate) { Class<?> targetClass = target.getClass(); @@ -71,7 +70,7 @@ final class ReflectionServiceUtil { return false; } - // try to find matchin activate/deactivate method and execute it + // try to find matching activate/deactivate method and execute it // 1. componentContext Method method = getMethod(targetClass, methodName, new Class<?>[] { ComponentContext.class }); @@ -143,7 +142,31 @@ final class ReflectionServiceUtil { return true; } - log.warn("Method {}(ComponentContext) not found in class {}", methodName, targetClass.getName()); + log.warn("Method {} not found in class {}", methodName, targetClass.getName()); + return false; + } + + /** + * Simulate modification of configuration of OSGi service instance. + * @param target Service instance. + * @param properties Updated configuration + * @return true if modified method was called. False if it failed. + */ + public static boolean modified(Object target, BundleContext bundleContext, Map<String,Object> properties) { + Class<?> targetClass = target.getClass(); + + // get method name for activation/deactivation from osgi metadata + Document metadata = OsgiMetadataUtil.getMetadata(targetClass); + String methodName = OsgiMetadataUtil.getModifiedMethodName(targetClass, metadata); + + // try to find matching modified method and execute it + Method method = getMethod(targetClass, methodName, new Class<?>[] { Map.class }); + if (method != null) { + invokeMethod(target, method, new Object[] { properties }); + return true; + } + + log.warn("Method {} not found in class {}", methodName, targetClass.getName()); return false; } 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 6fd4ec2..37e5c49 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 @@ -45,6 +45,9 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Modified; + +import com.google.common.collect.ImmutableMap; public class ReflectionServiceUtilTest { @@ -85,12 +88,32 @@ public class ReflectionServiceUtilTest { List<Map<String, Object>> reference3Configs = service3.getReference3Configs(); assertEquals(1, reference3Configs.size()); assertEquals(200, reference3Configs.get(0).get(Constants.SERVICE_RANKING)); - + assertTrue(MockOsgi.deactivate(service3)); assertNull(service3.getComponentContext()); } @Test + public void testService3_Config() { + BundleContext bundleContext = MockOsgi.newBundleContext(); + + Map<String,Object> initialProperites = ImmutableMap.<String, Object>of("prop1", "value1"); + + Service3 service3 = new Service3(); + MockOsgi.activate(service3, bundleContext, initialProperites); + assertEquals(initialProperites, service3.getConfig()); + + Map<String,Object> newProperties = ImmutableMap.<String, Object>of("prop2", "value2"); + MockOsgi.modified(service3, bundleContext, newProperties); + assertEquals(newProperties, service3.getConfig()); + + newProperties = ImmutableMap.<String, Object>of("prop3", "value3"); + Dictionary<String,Object> newPropertiesDictonary = new Hashtable<String,Object>(newProperties); + MockOsgi.modified(service3, bundleContext, newPropertiesDictonary); + assertEquals(newProperties, service3.getConfig()); + } + + @Test public void testService4() { Service4 service4 = new Service4(); @@ -144,16 +167,24 @@ public class ReflectionServiceUtilTest { private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>(); private ComponentContext componentContext; + private Map<String, Object> config; + @SuppressWarnings("unchecked") @Activate private void activate(ComponentContext ctx) { this.componentContext = ctx; + this.config = MockOsgi.toMap(ctx.getProperties()); } @Deactivate private void deactivate(ComponentContext ctx) { this.componentContext = null; } + + @Modified + private void modified(Map<String,Object> newConfig) { + this.config = newConfig; + } public ServiceInterface1 getReference1() { return this.reference1; @@ -178,6 +209,10 @@ public class ReflectionServiceUtilTest { public ComponentContext getComponentContext() { return this.componentContext; } + + public Map<String, Object> getConfig() { + return config; + } protected void bindReference1(ServiceInterface1 service) { reference1 = service; diff --git a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest.xml b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest.xml index 923b90f..202dc40 100644 --- a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest.xml +++ b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest.xml @@ -17,7 +17,7 @@ <property name="service.ranking" type="Integer" value="200"/> <property name="service.pid" value="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$Service2"/> </scr:component> - <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$Service3" activate="activate" deactivate="deactivate"> + <scr:component name="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$Service3" activate="activate" deactivate="deactivate" modified="modified"> <implementation class="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$Service3"/> <property name="service.pid" value="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$Service3"/> <reference name="reference2" interface="org.apache.sling.testing.mock.osgi.ReflectionServiceUtilTest$ServiceInterface2" cardinality="1..n" policy="static" bind="bindReference2" unbind="unbindReference2"/> -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
