This is an automated email from the ASF dual-hosted git repository. sseifert pushed a commit to branch feature/SLING-11698-serviceobjects in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit 381f3f60e75b58dec92f56c8a6d194aa35cba4f7 Author: Stefan Seifert <[email protected]> AuthorDate: Tue Nov 22 22:03:36 2022 +0100 SLING-11698 full support for ComponentServiceObjects --- .../sling/testing/mock/osgi/OsgiServiceUtil.java | 77 +++++++---- ...eferencesOsgiR6ComponentServiceObjectsTest.java | 34 +++++ ...ckBundleContextDynamicReferencesOsgiR6Test.java | 7 +- ...ctionComponentServiceObjectsReferencesTest.java | 34 +++++ ...icGreedyConstructorInjectionReferencesTest.java | 6 +- .../testing/mock/osgi/OsgiServiceUtilTest.java | 12 +- .../osgi/testsvc/osgiserviceutil/DictionaryTo.java | 42 ++++++ .../osgi/testsvc/osgiserviceutil/Service3.java | 11 +- .../testsvc/osgiserviceutil/Service3OsgiR6.java | 118 ++-------------- ...Service3OsgiR6ComponentServiceObjectsImpl.java} | 69 +++++----- ...Service3OsgiR6.java => Service3OsgiR6Impl.java} | 13 +- ...ructorInjectionComponentServiceObjectsImpl.java | 148 +++++++++++++++++++++ .../osgiserviceutil/Service3StaticGreedyImpl.java | 11 +- 13 files changed, 381 insertions(+), 201 deletions(-) diff --git a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java index 6adc7b3..35460ce 100644 --- a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java +++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java @@ -50,7 +50,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceObjects; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentServiceObjects; @@ -577,7 +576,7 @@ final class OsgiServiceUtil { switch (reference.getFieldCollectionType()) { case SERVICE: matchingServices.stream() - .map(ServiceInfo::getServiceInstance) + .map(ServiceInfo::getService) .forEach(collection::add); break; case REFERENCE: @@ -585,6 +584,9 @@ final class OsgiServiceUtil { .map(ServiceInfo::getServiceReference) .forEach(collection::add); break; + case SERVICEOBJECTS: + collection.addAll(matchingServices); + break; default: throw new RuntimeException("Field collection type '" + reference.getFieldCollectionType() + "' not supported " + "for reference '" + reference.getName() + "' (" + type.getName() + ") into constructor parameter " + parameterIndex + " for class " + targetClass.getName()); @@ -598,13 +600,18 @@ final class OsgiServiceUtil { // 1. assignable from service instance if (parameterType.isAssignableFrom(reference.getInterfaceTypeAsClass())) { - return firstServiceInfo.map(ServiceInfo::getServiceInstance); + return firstServiceInfo.map(ServiceInfo::getService); } // 2. ServiceReference if (parameterType == ServiceReference.class) { return firstServiceInfo.map(ServiceInfo::getServiceReference); } + + // 3. ServiceReference + if (parameterType == ComponentServiceObjects.class) { + return firstServiceInfo; + } } // no match @@ -669,7 +676,7 @@ final class OsgiServiceUtil { // 2. ComponentServiceObjects method = getMethod(targetClass, methodName, new Class<?>[] { ComponentServiceObjects.class }); if (method != null) { - invokeMethod(target, method, new Object[] { toComponentServiceObjects(bundleContext.getServiceObjects(serviceInfo.getServiceReference())) }); + invokeMethod(target, method, new Object[] { serviceInfo }); return; } @@ -677,7 +684,7 @@ final class OsgiServiceUtil { Class<?> interfaceType = reference.getInterfaceTypeAsClass(); method = getMethodWithAssignableTypes(targetClass, methodName, new Class<?>[] { interfaceType }); if (method != null) { - invokeMethod(target, method, new Object[] { serviceInfo.getServiceInstance() }); + invokeMethod(target, method, new Object[] { serviceInfo.getService() }); return; } @@ -698,10 +705,10 @@ final class OsgiServiceUtil { args[i] = serviceInfo.getServiceReference(); } else if (method.getParameterTypes()[i] == ComponentServiceObjects.class) { - args[i] = toComponentServiceObjects(bundleContext.getServiceObjects(serviceInfo.getServiceReference())); + args[i] = serviceInfo; } else if (method.getParameterTypes()[i].isAssignableFrom(interfaceType)) { - args[i] = serviceInfo.getServiceInstance(); + args[i] = serviceInfo.getService(); } else if (method.getParameterTypes()[i] == Map.class) { args[i] = serviceInfo.getServiceConfig(); @@ -723,12 +730,16 @@ final class OsgiServiceUtil { switch (reference.getFieldCollectionType()) { case SERVICE: case REFERENCE: + case SERVICEOBJECTS: Object item = null; if (serviceInfo != null) { - item = serviceInfo.getServiceInstance(); + item = serviceInfo.getService(); if (reference.getFieldCollectionType() == FieldCollectionType.REFERENCE) { item = serviceInfo.getServiceReference(); } + else if (reference.getFieldCollectionType() == FieldCollectionType.SERVICEOBJECTS) { + item = serviceInfo; + } } Field field = getCollectionField(targetClass, fieldName); if (field != null) { @@ -753,7 +764,7 @@ final class OsgiServiceUtil { Class<?> interfaceType = reference.getInterfaceTypeAsClass(); Field field = getFieldWithAssignableType(targetClass, fieldName, interfaceType); if (field != null) { - setField(target, field, bind && serviceInfo != null ? serviceInfo.getServiceInstance() : null); + setField(target, field, bind && serviceInfo != null ? serviceInfo.getService() : null); return; } @@ -763,28 +774,18 @@ final class OsgiServiceUtil { setField(target, field, bind && serviceInfo != null ? serviceInfo.getServiceReference() : null); return; } + + // 3. ComponentServiceObjects + field = getField(targetClass, fieldName, ComponentServiceObjects.class); + if (field != null) { + setField(target, field, bind && serviceInfo != null ? serviceInfo : null); + return; + } } } } - private static <T> ComponentServiceObjects<T> toComponentServiceObjects(ServiceObjects<T> serviceObjects) { - return new ComponentServiceObjects<T>() { - @Override - public T getService() { - return serviceObjects.getService(); - } - @Override - public void ungetService(T service) { - serviceObjects.ungetService(service); - } - @Override - public ServiceReference<T> getServiceReference() { - return serviceObjects.getServiceReference(); - } - }; - } - @SuppressWarnings("unchecked") private static void addToCollection(Object target, Field field, Object item) { try { @@ -942,7 +943,7 @@ final class OsgiServiceUtil { return references; } - static class ServiceInfo<T> { + static class ServiceInfo<T> implements ComponentServiceObjects<T> { private final T serviceInstance; private final Map<String, Object> serviceConfig; @@ -960,7 +961,7 @@ final class OsgiServiceUtil { this.serviceReference = registration.getReference(); } - public T getServiceInstance() { + public T getService() { return this.serviceInstance; } @@ -972,6 +973,26 @@ final class OsgiServiceUtil { return serviceReference; } + @Override + public void ungetService(T service) { + // nothing to do + } + + @Override + @SuppressWarnings("null") + public int hashCode() { + return serviceInstance.hashCode(); + } + + @Override + @SuppressWarnings("null") + public boolean equals(Object obj) { + if (obj instanceof ServiceInfo) { + return serviceInstance.equals(((ServiceInfo)obj).serviceInstance); + } + return false; + } + } static class ReferenceInfo<T> { diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java new file mode 100644 index 0000000..0b04165 --- /dev/null +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6; +import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6ComponentServiceObjectsImpl; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest extends MockBundleContextDynamicReferencesOsgiR6Test { + + @Override + protected Service3OsgiR6 newService3OsgiR6() { + return new Service3OsgiR6ComponentServiceObjectsImpl(); + } + +} diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java index 4bebcf4..db6d6d1 100644 --- a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6; +import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6Impl; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1Optional; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface2; @@ -74,7 +75,7 @@ public class MockBundleContextDynamicReferencesOsgiR6Test { reg1a = bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, null); reg2a = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, null); - service = new Service3OsgiR6(); + service = newService3OsgiR6(); MockOsgi.injectServices(service, bundleContext); MockOsgi.activate(service, bundleContext); bundleContext.registerService(Service3OsgiR6.class.getName(), service, MapUtil.toDictionary(ImmutableMap.<String,Object>of("reference3DynamicFiltered.target","(prop1=def)"))); @@ -85,6 +86,10 @@ public class MockBundleContextDynamicReferencesOsgiR6Test { assertDependencies3(); } + protected Service3OsgiR6 newService3OsgiR6() { + return new Service3OsgiR6Impl(); + } + @Test public void testAddRemoveOptionalUnaryService() { ServiceRegistration reg1aOptional = bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null); diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java new file mode 100644 index 0000000..45abff3 --- /dev/null +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedy; +import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest extends MockBundleContextStaticGreedyConstructorInjectionReferencesTest { + + @Override + protected Class<? extends Service3StaticGreedy> getService3StaticGreedyClass() { + return Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.class; + } + +} diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java index 1673f93..ce0bebf 100644 --- a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java @@ -72,7 +72,7 @@ public class MockBundleContextStaticGreedyConstructorInjectionReferencesTest { reg1a = bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, null); reg2a = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, null); - Service3StaticGreedy service = MockOsgi.activateInjectServices(Service3StaticGreedyConstructorInjectionImpl.class, bundleContext); + Service3StaticGreedy service = MockOsgi.activateInjectServices(getService3StaticGreedyClass(), bundleContext); bundleContext.registerService(Service3StaticGreedy.class.getName(), service, null); assertDependency1(dependency1a); @@ -81,6 +81,10 @@ public class MockBundleContextStaticGreedyConstructorInjectionReferencesTest { assertDependencies3(); } + protected Class<? extends Service3StaticGreedy> getService3StaticGreedyClass() { + return Service3StaticGreedyConstructorInjectionImpl.class; + } + @Test public void testAddRemoveOptionalUnaryService() { ServiceRegistration reg1aOptional = bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null); diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java index 3e428ce..53eb85f 100644 --- a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java @@ -36,6 +36,8 @@ import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service1; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service2; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6; +import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6ComponentServiceObjectsImpl; +import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6Impl; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service4; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service5; import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceFactory1; @@ -110,7 +112,15 @@ public class OsgiServiceUtilTest { @Test public void testService3OsgiR6() { - Service3OsgiR6 service3 = new Service3OsgiR6(); + testService3OsgiR6(new Service3OsgiR6Impl()); + } + + @Test + public void testService3OsgiR6ComponentServiceObjects() { + testService3OsgiR6(new Service3OsgiR6ComponentServiceObjectsImpl()); + } + + private void testService3OsgiR6(Service3OsgiR6 service3) { assertTrue(MockOsgi.injectServices(service3, bundleContext)); Dictionary<String, Object> service3Config = new Hashtable<String, Object>(); diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java new file mode 100644 index 0000000..8b5f111 --- /dev/null +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java @@ -0,0 +1,42 @@ +/* + * 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.testsvc.osgiserviceutil; + +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +final class DictionaryTo { + + private DictionaryTo() { + // static methods only + } + + public static Map<String,Object> map(Dictionary<String,Object> dictionary) { + Map<String,Object> result = new HashMap<>(); + Enumeration<String> keys = dictionary.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + result.put(key, dictionary.get(key)); + } + return result; + } + +} diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java index 6f0bd12..fb48824 100644 --- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java @@ -19,8 +19,6 @@ package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil; import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -69,14 +67,7 @@ public class Service3 implements ServiceInterface2 { @Activate private void activate(ComponentContext ctx) { this.componentContext = ctx; - - // copy properties dictionary to config map - this.config = new HashMap<>(); - Enumeration<String> keys = ctx.getProperties().keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - this.config.put(key, ctx.getProperties().get(key)); - } + this.config = DictionaryTo.map(ctx.getProperties()); } @Deactivate diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java index 17ad401..b8745b8 100644 --- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java @@ -18,129 +18,33 @@ */ package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil; -import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.FieldOption; -import org.osgi.service.component.annotations.Modified; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -@Component -public class Service3OsgiR6 { +public interface Service3OsgiR6 { - @Reference - private ServiceInterface1 reference1; + ServiceInterface1 getReference1(); - @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - private volatile ServiceInterface1Optional reference1Optional; + ServiceInterface1Optional getReference1Optional(); - @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE, - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceReference<ServiceInterface2>> references2 = new ArrayList<>(); + List<ServiceInterface2> getReferences2(); - @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceSuperInterface3> references3; + List<ServiceSuperInterface3> getReferences3(); - @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, target="(prop1=abc)", - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceSuperInterface3> references3Filtered; + List<ServiceSuperInterface3> getReferences3Filtered(); - @Reference(cardinality = ReferenceCardinality.OPTIONAL, - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, - name = "reference3DynamicFiltered") - private volatile ServiceSuperInterface3 reference3DynamicFiltered; + ServiceSuperInterface3 getReference3DynamicFiltered(); - @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, - fieldOption = FieldOption.UPDATE) - private volatile Set<ServiceSuperInterface3> references3Set; + Set<ServiceSuperInterface3> getReferences3Set(); - @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, - policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile Collection<ServiceSuperInterface3> references3Collection; + Collection<ServiceSuperInterface3> getReferences3Collection(); - private ComponentContext componentContext; - private Map<String, Object> config; + ComponentContext getComponentContext(); - @Activate - private void activate(ComponentContext ctx) { - this.componentContext = ctx; - - // copy properties dictionary to config map - this.config = new HashMap<>(); - Enumeration<String> keys = ctx.getProperties().keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - this.config.put(key, ctx.getProperties().get(key)); - } - } - - @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; - } - - public ServiceInterface1Optional getReference1Optional() { - return this.reference1Optional; - } - - public List<ServiceInterface2> getReferences2() { - List<ServiceInterface2> services = new ArrayList<ServiceInterface2>(); - for (ServiceReference<?> serviceReference : references2) { - services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference)); - } - return services; - } - - public List<ServiceSuperInterface3> getReferences3() { - return this.references3; - } - - public List<ServiceSuperInterface3> getReferences3Filtered() { - return this.references3Filtered; - } - - public ServiceSuperInterface3 getReference3DynamicFiltered() { - return this.reference3DynamicFiltered; - } - - public Set<ServiceSuperInterface3> getReferences3Set() { - return this.references3Set; - } - - public Collection<ServiceSuperInterface3> getReferences3Collection() { - return this.references3Collection; - } - - public ComponentContext getComponentContext() { - return this.componentContext; - } - - public Map<String, Object> getConfig() { - return config; - } + Map<String, Object> getConfig(); } diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java similarity index 64% copy from test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java copy to test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java index 17ad401..969227c 100644 --- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java @@ -20,14 +20,14 @@ package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; -import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.ComponentServiceObjects; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; @@ -39,39 +39,39 @@ import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; @Component -public class Service3OsgiR6 { +public class Service3OsgiR6ComponentServiceObjectsImpl implements Service3OsgiR6 { @Reference - private ServiceInterface1 reference1; + private ComponentServiceObjects<ServiceInterface1> reference1; @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - private volatile ServiceInterface1Optional reference1Optional; + private volatile ComponentServiceObjects<ServiceInterface1Optional> reference1Optional; @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceReference<ServiceInterface2>> references2 = new ArrayList<>(); + private volatile List<ComponentServiceObjects<ServiceInterface2>> references2 = new ArrayList<>(); @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceSuperInterface3> references3; + private volatile List<ComponentServiceObjects<ServiceSuperInterface3>> references3; @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, target="(prop1=abc)", policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile List<ServiceSuperInterface3> references3Filtered; + private volatile List<ComponentServiceObjects<ServiceSuperInterface3>> references3Filtered; @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, name = "reference3DynamicFiltered") - private volatile ServiceSuperInterface3 reference3DynamicFiltered; + private volatile ComponentServiceObjects<ServiceSuperInterface3> reference3DynamicFiltered; @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, fieldOption = FieldOption.UPDATE) - private volatile Set<ServiceSuperInterface3> references3Set; + private volatile Set<ComponentServiceObjects<ServiceSuperInterface3>> references3Set; @Reference(service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) - private volatile Collection<ServiceSuperInterface3> references3Collection; + private volatile Collection<ComponentServiceObjects<ServiceSuperInterface3>> references3Collection; private ComponentContext componentContext; private Map<String, Object> config; @@ -79,14 +79,7 @@ public class Service3OsgiR6 { @Activate private void activate(ComponentContext ctx) { this.componentContext = ctx; - - // copy properties dictionary to config map - this.config = new HashMap<>(); - Enumeration<String> keys = ctx.getProperties().keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - this.config.put(key, ctx.getProperties().get(key)); - } + this.config = DictionaryTo.map(ctx.getProperties()); } @Deactivate @@ -100,39 +93,51 @@ public class Service3OsgiR6 { } public ServiceInterface1 getReference1() { - return this.reference1; + return Optional.ofNullable(this.reference1) + .map(ComponentServiceObjects::getService) + .orElse(null); } public ServiceInterface1Optional getReference1Optional() { - return this.reference1Optional; + return Optional.ofNullable(this.reference1Optional) + .map(ComponentServiceObjects::getService) + .orElse(null); } public List<ServiceInterface2> getReferences2() { - List<ServiceInterface2> services = new ArrayList<ServiceInterface2>(); - for (ServiceReference<?> serviceReference : references2) { - services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference)); - } - return services; + return references2.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); } public List<ServiceSuperInterface3> getReferences3() { - return this.references3; + return this.references3.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); } public List<ServiceSuperInterface3> getReferences3Filtered() { - return this.references3Filtered; + return this.references3Filtered.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); } public ServiceSuperInterface3 getReference3DynamicFiltered() { - return this.reference3DynamicFiltered; + return Optional.ofNullable(this.reference3DynamicFiltered) + .map(ComponentServiceObjects::getService) + .orElse(null); } public Set<ServiceSuperInterface3> getReferences3Set() { - return this.references3Set; + return this.references3Set.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toSet()); } public Collection<ServiceSuperInterface3> getReferences3Collection() { - return this.references3Collection; + return this.references3Collection.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); } public ComponentContext getComponentContext() { diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java similarity index 92% copy from test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java copy to test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java index 17ad401..5c2043a 100644 --- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java @@ -20,8 +20,6 @@ package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,7 +37,7 @@ import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; @Component -public class Service3OsgiR6 { +public class Service3OsgiR6Impl implements Service3OsgiR6 { @Reference private ServiceInterface1 reference1; @@ -79,14 +77,7 @@ public class Service3OsgiR6 { @Activate private void activate(ComponentContext ctx) { this.componentContext = ctx; - - // copy properties dictionary to config map - this.config = new HashMap<>(); - Enumeration<String> keys = ctx.getProperties().keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - this.config.put(key, ctx.getProperties().get(key)); - } + this.config = DictionaryTo.map(ctx.getProperties()); } @Deactivate diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java new file mode 100644 index 0000000..af66ad9 --- /dev/null +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java @@ -0,0 +1,148 @@ +/* + * 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.testsvc.osgiserviceutil; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.ComponentServiceObjects; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; + +@Component(service= Service3StaticGreedy.class) +public class Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl implements Service3StaticGreedy { + + private final ComponentServiceObjects<ServiceInterface1> reference1; + private final ComponentServiceObjects<ServiceInterface1Optional> reference1Optional; + private final List<ComponentServiceObjects<ServiceInterface2>> references2; + private final List<ComponentServiceObjects<ServiceSuperInterface3>> references3; + + private final ComponentContext componentContext; + private final Map<String, Object> config; + + // this constructor should be ignored as it contains additional parameters not valid for injection + public Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl( + ComponentServiceObjects<ServiceInterface1> reference1, + ComponentServiceObjects<ServiceInterface1Optional> reference1Optional, + List<ComponentServiceObjects<ServiceInterface2>> references2, + List<ComponentServiceObjects<ServiceSuperInterface3>> references3, + ComponentContext ctx, + Map<String, Object> config, + Object illegalParameter) { + + this.componentContext = ctx; + + this.reference1 = reference1; + this.reference1Optional = reference1Optional; + this.references2 = references2; + this.references3 = references3; + + this.config = config; + } + + @Activate + public Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl( + + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY) + ComponentServiceObjects<ServiceInterface1> reference1, + + @Reference(cardinality = ReferenceCardinality.OPTIONAL, + policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY) + ComponentServiceObjects<ServiceInterface1Optional> reference1Optional, + + @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE, + policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY) + List<ComponentServiceObjects<ServiceInterface2>> references2, + + @Reference(name = "reference3", service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE, + policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY) + List<ComponentServiceObjects<ServiceSuperInterface3>> references3, + + ComponentContext ctx, + Map<String, Object> config) { + + this.componentContext = ctx; + + this.reference1 = reference1; + this.reference1Optional = reference1Optional; + this.references2 = references2; + this.references3 = references3; + + this.config = config; + } + + @Override + public ServiceInterface1 getReference1() { + return Optional.ofNullable(this.reference1) + .map(ComponentServiceObjects::getService) + .orElse(null); + } + + @Override + public ServiceInterface1Optional getReference1Optional() { + return Optional.ofNullable(this.reference1Optional) + .map(ComponentServiceObjects::getService) + .orElse(null); + } + + @Override + public List<ServiceInterface2> getReferences2() { + return references2.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); + } + + @Override + public List<ServiceSuperInterface3> getReferences3() { + return this.references3.stream() + .map(ComponentServiceObjects::getService) + .collect(Collectors.toList()); + } + + @Override + public List<Map<String, Object>> getReference3Configs() { + return this.references3.stream() + .map(ComponentServiceObjects::getServiceReference) + .map(ServiceReference::getProperties) + .map(DictionaryTo::map) + .collect(Collectors.toList()); + } + + @Override + public List<ServiceSuperInterface3> getReferences3Filtered() { + return null; + } + + public ComponentContext getComponentContext() { + return this.componentContext; + } + + public Map<String, Object> getConfig() { + return config; + } + +} diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java index 6beb5d8..aadd261 100644 --- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java @@ -19,8 +19,6 @@ package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil; import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -67,14 +65,7 @@ public class Service3StaticGreedyImpl implements Service3StaticGreedy { @Activate private void activate(ComponentContext ctx) { this.componentContext = ctx; - - // copy properties dictionary to config map - this.config = new HashMap<>(); - Enumeration<String> keys = ctx.getProperties().keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - this.config.put(key, ctx.getProperties().get(key)); - } + this.config = DictionaryTo.map(ctx.getProperties()); } @Deactivate
