This is an automated email from the ASF dual-hosted git repository. jsedding pushed a commit to branch feature/SLING-11919-field-injection-Optional in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit d5904b26791f09a6a9df899e476a8ef880995a80 Author: Julian Sedding <[email protected]> AuthorDate: Wed Jun 28 23:20:54 2023 +0200 SLING-11919 - [osgi-mock] Support R8 field injection of type Optional --- .../sling/testing/mock/osgi/OsgiServiceUtil.java | 21 ++++++---- .../testing/mock/osgi/OsgiServiceUtilTest.java | 15 +++++++ .../Service3OsgiR8OptionalField.java | 27 +++++++++++++ .../Service3OsgiR8OptionalFieldImpl.java | 47 ++++++++++++++++++++++ 4 files changed, 103 insertions(+), 7 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 d76549a..f4d91a1 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 @@ -652,10 +652,9 @@ final class OsgiServiceUtil { if (!reference.isCardinalityOptional()) { throw new ReferenceViolationException("Unable to inject mandatory reference '" + reference.getName() + "' (" + type.getName() + ") for class " + targetClass.getName() + " : no matching services were found. bundleContext=" + bundleContext); } - if (reference.isCardinalityMultiple()) { - // make sure at least empty array is set - invokeBindUnbindMethod(reference, target, null, true); - } + + // make sure at least empty array or empty Optional is set + invokeBindUnbindMethod(reference, target, null, true); } // multiple references found? inject only first one with highest ranking @@ -789,22 +788,30 @@ final class OsgiServiceUtil { // 1. assignable from service instance Class<?> interfaceType = reference.getInterfaceTypeAsClass(); Field field = getFieldWithAssignableType(targetClass, fieldName, interfaceType); + final boolean servicePresent = bind && serviceInfo != null; if (field != null) { - setField(target, field, bind && serviceInfo != null ? serviceInfo.getService() : null); + setField(target, field, servicePresent ? serviceInfo.getService() : null); return; } // 2. ServiceReference field = getField(targetClass, fieldName, ServiceReference.class); if (field != null) { - setField(target, field, bind && serviceInfo != null ? serviceInfo.getServiceReference() : null); + setField(target, field, servicePresent ? serviceInfo.getServiceReference() : null); return; } // 3. ComponentServiceObjects field = getField(targetClass, fieldName, ComponentServiceObjects.class); if (field != null) { - setField(target, field, bind && serviceInfo != null ? serviceInfo : null); + setField(target, field, servicePresent ? serviceInfo : null); + return; + } + + // 4. Optional + field = getField(targetClass, fieldName, Optional.class); + if (field != null) { + setField(target, field, servicePresent ? Optional.of(serviceInfo.getService()) : Optional.empty()); return; } } 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 53eb85f..36db246 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 @@ -38,6 +38,7 @@ 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.Service3OsgiR8OptionalFieldImpl; 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; @@ -175,6 +176,20 @@ public class OsgiServiceUtilTest { assertEquals("value4", service3.getConfig().get("prop3")); } + @Test + public void testService3OsgiR8OptionalField() { + final Service3OsgiR8OptionalFieldImpl service3OsgiR8OptionalField = new Service3OsgiR8OptionalFieldImpl(); + MockOsgi.registerInjectActivateService(service3OsgiR8OptionalField, bundleContext); + assertTrue(service3OsgiR8OptionalField.getOptionalService1().isPresent()); + assertSame(service1, service3OsgiR8OptionalField.getOptionalService1().get()); + assertFalse(service3OsgiR8OptionalField.getOptionalService5().isPresent()); + + final Service5 service5 = new Service5(); + bundleContext.registerService(ServiceInterface5.class, service5, new Hashtable<>()); + assertTrue(service3OsgiR8OptionalField.getOptionalService5().isPresent()); + assertSame(service5, service3OsgiR8OptionalField.getOptionalService5().get()); + } + @Test public void testService4() { Service4 service4 = new Service4(); diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalField.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalField.java new file mode 100644 index 0000000..fdd543d --- /dev/null +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalField.java @@ -0,0 +1,27 @@ +/* + * 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.Optional; + +public interface Service3OsgiR8OptionalField { + Optional<ServiceInterface1> getOptionalService1(); + + Optional<ServiceInterface5> getOptionalService5(); +} diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalFieldImpl.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalFieldImpl.java new file mode 100644 index 0000000..a7edf3f --- /dev/null +++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR8OptionalFieldImpl.java @@ -0,0 +1,47 @@ +/* + * 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 org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferencePolicy; + +import java.util.Optional; + +@Component +public class Service3OsgiR8OptionalFieldImpl implements Service3OsgiR8OptionalField { + + @Reference + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + Optional<ServiceInterface1> optionalService1; + + @Reference + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + volatile Optional<ServiceInterface5> optionalService5; + + @Override + public Optional<ServiceInterface1> getOptionalService1() { + return optionalService1; + } + + @Override + public Optional<ServiceInterface5> getOptionalService5() { + return optionalService5; + } +}
