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:20:50 UTC
[sling-org-apache-sling-testing-osgi-mock] 02/10: SLING-5324
osgi-mock: Support OSGi R6 field-based reference bindings
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-2.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit 3f5a1729ed9dcc5b10affea05320b3f0f9d91612
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Mon Nov 23 23:45:50 2015 +0000
SLING-5324 osgi-mock: Support OSGi R6 field-based reference bindings
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1715990 13f79535-47bb-0310-9956-ffa450edef68
---
.../sling/testing/mock/osgi/OsgiMetadataUtil.java | 108 +++++++++++++
.../sling/testing/mock/osgi/OsgiServiceUtil.java | 173 +++++++++++++++++++--
...ockBundleContextDynamicReferncesOsgiR6Test.java | 169 ++++++++++++++++++++
.../testing/mock/osgi/OsgiServiceUtilTest.java | 56 +++++++
...sling.testing.mock.osgi.OsgiServiceUtilTest.xml | 8 +
5 files changed, 500 insertions(+), 14 deletions(-)
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 7c3db48..85db326 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
@@ -386,8 +386,11 @@ final class OsgiMetadataUtil {
private final String interfaceType;
private final ReferenceCardinality cardinality;
private final ReferencePolicy policy;
+ private final ReferencePolicyOption policyOption;
private final String bind;
private final String unbind;
+ private final String field;
+ private final FieldCollectionType fieldCollectionType;
private Reference(Class<?> clazz, Node node) {
this.clazz = clazz;
@@ -395,8 +398,11 @@ final class OsgiMetadataUtil {
this.interfaceType = getAttributeValue(node, "interface");
this.cardinality = toCardinality(getAttributeValue(node, "cardinality"));
this.policy = toPolicy(getAttributeValue(node, "policy"));
+ this.policyOption = toPolicyOption(getAttributeValue(node, "policy-option"));
this.bind = getAttributeValue(node, "bind");
this.unbind = getAttributeValue(node, "unbind");
+ this.field = getAttributeValue(node, "field");
+ this.fieldCollectionType = toFieldCollectionType(getAttributeValue(node, "field-collection-type"));
}
public Class<?> getServiceClass() {
@@ -411,14 +417,31 @@ final class OsgiMetadataUtil {
return this.interfaceType;
}
+ public Class getInterfaceTypeAsClass() {
+ try {
+ return Class.forName(getInterfaceType());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Service reference type not found: " + getInterfaceType());
+ }
+ }
+
public ReferenceCardinality getCardinality() {
return this.cardinality;
}
+
+ public boolean isCardinalityMultiple() {
+ return this.cardinality == ReferenceCardinality.OPTIONAL_MULTIPLE
+ || this.cardinality == ReferenceCardinality.MANDATORY_MULTIPLE;
+ }
public ReferencePolicy getPolicy() {
return policy;
}
+ public ReferencePolicyOption getPolicyOption() {
+ return policyOption;
+ }
+
public String getBind() {
return this.bind;
}
@@ -427,6 +450,14 @@ final class OsgiMetadataUtil {
return this.unbind;
}
+ public String getField() {
+ return this.field;
+ }
+
+ public FieldCollectionType getFieldCollectionType() {
+ return this.fieldCollectionType;
+ }
+
private static ReferenceCardinality toCardinality(String value) {
for (ReferenceCardinality item : ReferenceCardinality.values()) {
if (StringUtils.equals(item.getCardinalityString(), value)) {
@@ -445,6 +476,24 @@ final class OsgiMetadataUtil {
return ReferencePolicy.STATIC;
}
+ private static ReferencePolicyOption toPolicyOption(String value) {
+ for (ReferencePolicyOption item : ReferencePolicyOption.values()) {
+ if (StringUtils.equalsIgnoreCase(item.name(), value)) {
+ return item;
+ }
+ }
+ return ReferencePolicyOption.RELUCTANT;
+ }
+
+ private static FieldCollectionType toFieldCollectionType(String value) {
+ for (FieldCollectionType item : FieldCollectionType.values()) {
+ if (StringUtils.equalsIgnoreCase(item.name(), value)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
}
@@ -513,4 +562,63 @@ final class OsgiMetadataUtil {
DYNAMIC;
}
+
+ /**
+ * Options for {@link Reference#policyOption()} property.
+ */
+ enum ReferencePolicyOption {
+
+ /**
+ * The reluctant policy option is the default policy option.
+ * When a new target service for a reference becomes available,
+ * references having the reluctant policy option for the static
+ * policy or the dynamic policy with a unary cardinality will
+ * ignore the new target service. References having the dynamic
+ * policy with a multiple cardinality will bind the new
+ * target service
+ */
+ RELUCTANT,
+
+ /**
+ * When a new target service for a reference becomes available,
+ * references having the greedy policy option will bind the new
+ * target service.
+ */
+ GREEDY;
+ }
+
+ /**
+ * Options for {@link Reference#policyOption()} property.
+ */
+ enum FieldCollectionType {
+
+ /**
+ * The bound service object. This is the default field collection type.
+ */
+ SERVICE,
+
+ /**
+ * A Service Reference for the bound service.
+ */
+ REFERENCE,
+
+ /**
+ * A Component Service Objects for the bound service.
+ */
+ SERVICEOBJECTS,
+
+ /**
+ * An unmodifiable Map containing the service properties of the bound service.
+ * This Map must implement Comparable.
+ */
+ PROPERTIES,
+
+ /**
+ * An unmodifiable Map.Entry whose key is an unmodifiable Map containing the
+ * service properties of the bound service, as above, and whose value is the
+ * bound service object. This Map.Entry must implement Comparable.
+ */
+ TUPLE;
+ }
+
}
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index 84ccbf8..1f8eaa0 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -18,10 +18,12 @@
*/
package org.apache.sling.testing.mock.osgi;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +31,7 @@ import java.util.SortedSet;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.FieldCollectionType;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.ReferenceCardinality;
@@ -262,6 +265,49 @@ final class OsgiServiceUtil {
}
}
+ private static Field getField(Class clazz, String fieldName, Class<?> type) {
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ if (StringUtils.equals(field.getName(), fieldName) && field.getType().equals(type)) {
+ return field;
+ }
+ }
+ // not found? check super classes
+ Class<?> superClass = clazz.getSuperclass();
+ if (superClass != null && superClass != Object.class) {
+ return getField(superClass, fieldName, type);
+ }
+ return null;
+ }
+
+ private static Field getFieldWithAssignableType(Class clazz, String fieldName, Class<?> type) {
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ if (StringUtils.equals(field.getName(), fieldName) && field.getType().isAssignableFrom(type)) {
+ return field;
+ }
+ }
+ // not found? check super classes
+ Class<?> superClass = clazz.getSuperclass();
+ if (superClass != null && superClass != Object.class) {
+ return getFieldWithAssignableType(superClass, fieldName, type);
+ }
+ return null;
+ }
+
+ private static void setField(Object target, Field field, Object value) {
+ try {
+ field.setAccessible(true);
+ field.set(target, value);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ } catch (IllegalArgumentException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ }
+ }
+
/**
* Simulate OSGi service dependency injection. Injects direct references and
* multiple references.
@@ -294,12 +340,7 @@ final class OsgiServiceUtil {
Class<?> targetClass = target.getClass();
// get reference type
- Class<?> type;
- try {
- type = Class.forName(reference.getInterfaceType());
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Unable to instantiate reference type: " + reference.getInterfaceType(), ex);
- }
+ Class<?> type = reference.getInterfaceTypeAsClass();
// get matching service references
List<ServiceInfo> matchingServices = getMatchingServices(type, bundleContext);
@@ -330,6 +371,13 @@ final class OsgiServiceUtil {
// try to invoke bind method
String methodName = bind ? reference.getBind() : reference.getUnbind();
+ String fieldName = reference.getField();
+
+ if (StringUtils.isEmpty(methodName) && StringUtils.isEmpty(fieldName)) {
+ throw new RuntimeException("No bind/unbind method name or file name defined "
+ + "for reference '" + reference.getName() + "' for class " + targetClass.getName());
+ }
+
if (StringUtils.isNotEmpty(methodName)) {
// 1. ServiceReference
@@ -340,12 +388,7 @@ final class OsgiServiceUtil {
}
// 2. assignable from service instance
- Class<?> interfaceType;
- try {
- interfaceType = Class.forName(reference.getInterfaceType());
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Service reference type not found: " + reference.getInterfaceType());
- }
+ Class<?> interfaceType = reference.getInterfaceTypeAsClass();
method = getMethodWithAssignableTypes(targetClass, methodName, new Class<?>[] { interfaceType });
if (method != null) {
invokeMethod(target, method, new Object[] { serviceInfo.getServiceInstance() });
@@ -358,10 +401,112 @@ final class OsgiServiceUtil {
invokeMethod(target, method, new Object[] { serviceInfo.getServiceInstance(), serviceInfo.getServiceConfig() });
return;
}
+
+ throw new RuntimeException((bind ? "Bind" : "Unbind") + " method with name " + methodName + " not found "
+ + "for reference '" + reference.getName() + "' for class " + targetClass.getName());
+ }
+
+ // in OSGi declarative services 1.3 there are no bind/unbind methods - modify the field directly
+ else if (StringUtils.isNotEmpty(fieldName)) {
+
+ // check for field with list/collection reference
+ if (reference.isCardinalityMultiple()) {
+ switch (reference.getFieldCollectionType()) {
+ case SERVICE:
+ case REFERENCE:
+ Object item = serviceInfo.getServiceInstance();
+ if (reference.getFieldCollectionType() == FieldCollectionType.REFERENCE) {
+ item = serviceInfo.getServiceReference();
+ }
+ // 1. collection
+ Field field = getFieldWithAssignableType(targetClass, fieldName, Collection.class);
+ if (field != null) {
+ if (bind) {
+ addToCollection(target, field, item);
+ }
+ else {
+ removeFromCollection(target, field, item);
+ }
+ return;
+ }
+
+ // 2. list
+ field = getField(targetClass, fieldName, List.class);
+ if (field != null) {
+ if (bind) {
+ addToCollection(target, field, item);
+ }
+ else {
+ removeFromCollection(target, field, item);
+ }
+ return;
+ }
+ break;
+ default:
+ throw new RuntimeException("Field collection type '" + reference.getFieldCollectionType() + "' not supported "
+ + "for reference '" + reference.getName() + "' for class " + targetClass.getName());
+ }
+ }
+
+ // check for single field reference
+ else {
+ // 1. assignable from service instance
+ Class<?> interfaceType = reference.getInterfaceTypeAsClass();
+ Field field = getFieldWithAssignableType(targetClass, fieldName, interfaceType);
+ if (field != null) {
+ setField(target, field, bind ? serviceInfo.getServiceInstance() : null);
+ return;
+ }
+
+ // 2. ServiceReference
+ field = getField(targetClass, fieldName, ServiceReference.class);
+ if (field != null) {
+ setField(target, field, bind ? serviceInfo.getServiceReference() : null);
+ return;
+ }
+ }
}
- throw new RuntimeException((bind ? "Bind" : "Unbind") + " method with name " + methodName + " not found "
- + "for reference '" + reference.getName() + "' for class " + targetClass.getName());
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void addToCollection(Object target, Field field, Object item) {
+ try {
+ field.setAccessible(true);
+ Collection<Object> collection = (Collection<Object>)field.get(target);
+ if (collection == null) {
+ collection = new ArrayList<>();
+ }
+ collection.add(item);
+ field.set(target, collection);
+
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ } catch (IllegalArgumentException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void removeFromCollection(Object target, Field field, Object item) {
+ try {
+ field.setAccessible(true);
+ Collection<Object> collection = (Collection<Object>)field.get(target);
+ if (collection == null) {
+ return;
+ }
+ collection.remove(item);
+ field.set(target, collection);
+
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ } catch (IllegalArgumentException ex) {
+ throw new RuntimeException("Unable to set field '" + field.getName() + "' for class "
+ + target.getClass().getName(), ex);
+ }
}
/**
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferncesOsgiR6Test.java b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferncesOsgiR6Test.java
new file mode 100644
index 0000000..0af80e9
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferncesOsgiR6Test.java
@@ -0,0 +1,169 @@
+/*
+ * 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.assertNull;
+import static org.junit.Assert.assertSame;
+
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.Service3OsgiR6;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface1;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface1Optional;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface2;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface3;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceSuperInterface3;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.google.common.collect.ImmutableSet;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MockBundleContextDynamicReferncesOsgiR6Test {
+
+ private BundleContext bundleContext;
+ private Service3OsgiR6 service;
+ private ServiceRegistration reg1a;
+ private ServiceRegistration reg2a;
+
+ @Mock
+ private ServiceInterface1 dependency1a;
+ @Mock
+ private ServiceInterface1 dependency1b;
+ @Mock
+ private ServiceInterface1Optional dependency1aOptional;
+ @Mock
+ private ServiceInterface1Optional dependency1bOptional;
+ @Mock
+ private ServiceInterface2 dependency2a;
+ @Mock
+ private ServiceInterface2 dependency2b;
+ @Mock
+ private ServiceSuperInterface3 dependency3a;
+ @Mock
+ private ServiceSuperInterface3 dependency3b;
+
+ @Before
+ public void setUp() {
+ bundleContext = MockOsgi.newBundleContext();
+
+ // setup service instance with only minimum mandatory references
+ reg1a = bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, null);
+ reg2a = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, null);
+
+ service = new Service3OsgiR6();
+ MockOsgi.injectServices(service, bundleContext);
+ MockOsgi.activate(service, bundleContext);
+ bundleContext.registerService(Service3OsgiR6.class.getName(), service, null);
+
+ assertDependency1(dependency1a);
+ assertDependency1Optional(null);
+ assertDependencies2(dependency2a);
+ assertDependencies3();
+ }
+
+ @Test
+ public void testAddRemoveOptionalUnaryService() {
+ ServiceRegistration reg1aOptional = bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
+ assertDependency1Optional(dependency1aOptional);
+
+ reg1aOptional.unregister();
+ assertDependency1Optional(null);
+ }
+
+ public void testAddOptionalUnaryService_TooMany() {
+ bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
+ assertDependency1Optional(dependency1aOptional);
+
+ // in real OSGi this should fail - but this is not covered by the current implementation. so test the real implementation here.
+ bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1bOptional, null);
+ assertDependency1Optional(dependency1bOptional);
+ }
+
+ @Test(expected = ReferenceViolationException.class)
+ public void testAddMandatoryUnaryService_TooMany() {
+ bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
+ }
+
+ @Test(expected = ReferenceViolationException.class)
+ public void testRemoveMandatoryUnaryService_TooMany() {
+ reg1a.unregister();
+ }
+
+ @Test
+ public void testAddRemoveOptionalMultipleService() {
+ ServiceRegistration reg3a = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3a, null);
+ assertDependencies3(dependency3a);
+
+ ServiceRegistration reg3b = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3b, null);
+ assertDependencies3(dependency3a, dependency3b);
+
+ reg3a.unregister();
+ assertDependencies3(dependency3b);
+
+ reg3b.unregister();
+ assertDependencies3();
+ }
+
+ @Test
+ public void testAddRemoveMandatoryMultipleService() {
+ ServiceRegistration reg2b = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2b, null);
+ assertDependencies2(dependency2a, dependency2b);
+
+ reg2b.unregister();
+ assertDependencies2(dependency2a);
+
+ // in real OSGi this should fail - but this is not covered by the current implementation. so test the real implementation here.
+ reg2a.unregister();
+ assertDependencies2();
+ }
+
+ private void assertDependency1(ServiceInterface1 instance) {
+ if (instance == null) {
+ assertNull(service.getReference1());
+ }
+ else {
+ assertSame(instance, service.getReference1());
+ }
+ }
+
+ private void assertDependency1Optional(ServiceInterface1Optional instance) {
+ if (instance == null) {
+ assertNull(service.getReference1Optional());
+ }
+ else {
+ assertSame(instance, service.getReference1Optional());
+ }
+ }
+
+ private void assertDependencies2(ServiceInterface2... instances) {
+ assertEquals(ImmutableSet.<ServiceInterface2>copyOf(instances),
+ ImmutableSet.<ServiceInterface2>copyOf(service.getReferences2()));
+ }
+
+ private void assertDependencies3(ServiceSuperInterface3... instances) {
+ assertEquals(ImmutableSet.<ServiceSuperInterface3>copyOf(instances),
+ ImmutableSet.<ServiceSuperInterface3>copyOf(service.getReferences3()));
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
index 170957f..9135bcf 100644
--- a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
@@ -335,6 +335,62 @@ public class OsgiServiceUtilTest {
}
+ public static class Service3OsgiR6 {
+
+ private ServiceInterface1 reference1;
+ private ServiceInterface1Optional reference1Optional;
+ private List<ServiceReference> references2 = new ArrayList<ServiceReference>();
+ private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
+
+ private ComponentContext componentContext;
+ private Map<String, Object> config;
+
+ @Activate
+ private void activate(ComponentContext ctx) {
+ this.componentContext = ctx;
+ this.config = MapUtil.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;
+ }
+
+ 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 ComponentContext getComponentContext() {
+ return this.componentContext;
+ }
+
+ public Map<String, Object> getConfig() {
+ return config;
+ }
+
+ }
+
@Component
@Reference(referenceInterface = ServiceInterface1.class, name = "customName", bind = "customBind", unbind = "customUnbind")
public static class Service4 {
diff --git a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
index a9d3623..94602cc 100644
--- a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
+++ b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
@@ -43,6 +43,14 @@
<reference name="reference2" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface2" cardinality="1..n" policy="dynamic" bind="bindReference2" unbind="unbindReference2"/>
<reference name="reference3" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3" cardinality="0..n" policy="dynamic" bind="bindReference3" unbind="unbindReference3"/>
</scr:component>
+ <scr:component name="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3OsgiR6" activate="activate" deactivate="deactivate" modified="modified">
+ <implementation class="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3OsgiR6"/>
+ <property name="service.pid" value="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3OsgiR6"/>
+ <reference name="reference1" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface1" cardinality="1..1" policy="dynamic" field="reference1"/>
+ <reference name="reference1Optional" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface1Optional" cardinality="0..1" policy="dynamic" field="reference1Optional"/>
+ <reference name="reference2" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface2" cardinality="1..n" policy="dynamic" field="references2" field-collection-type="reference"/>
+ <reference name="reference3" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3" cardinality="0..n" policy="dynamic" field="references3" field-collection-type="service"/>
+ </scr:component>
<scr:component name="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4_other_name">
<implementation class="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4"/>
<property name="service.pid" value="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4"/>
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.