stefanseifert closed pull request #3: Dynamic reference properties
URL: https://github.com/apache/sling-org-apache-sling-testing-osgi-mock/pull/3
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java 
b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
index 0340a55..02836f4 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
@@ -37,6 +37,7 @@
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.framework.FilterImpl;
+import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.DynamicReference;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
 import org.apache.sling.testing.mock.osgi.OsgiServiceUtil.ReferenceInfo;
 import org.apache.sling.testing.mock.osgi.OsgiServiceUtil.ServiceInfo;
@@ -142,6 +143,11 @@ private void 
handleRefsUpdateOnRegister(MockServiceRegistration registration) {
         List<ReferenceInfo> affectedDynamicReferences = 
OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
         for (ReferenceInfo referenceInfo : affectedDynamicReferences) {
             Reference reference = referenceInfo.getReference();
+            // Look for a target override
+            Object o = 
referenceInfo.getServiceRegistration().getProperties().get(reference.getName() 
+ ".target");
+            if (o != null && o instanceof String) {
+                reference = new DynamicReference(reference,(String)o);
+            }
             if (reference.matchesTargetFilter(registration.getReference())) {
                 switch (reference.getCardinality()) {
                 case MANDATORY_UNARY:
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 7c07578..4d22717 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
@@ -145,7 +145,20 @@ public static LogService newLogService(final Class<?> 
loggerContext) {
      * @return true if all dependencies could be injected, false if the 
service has no dependencies.
      */
     public static boolean injectServices(Object target, BundleContext 
bundleContext) {
-        return OsgiServiceUtil.injectServices(target, bundleContext);
+        return MockOsgi.injectServices(target, bundleContext, (Map<String, 
Object>)null);
+    }
+
+    /**
+     * Simulate OSGi service dependency injection. Injects direct references 
and
+     * multiple references. If a some references could not be injected no error
+     * is thrown.
+     * @param target Service instance
+     * @param bundleContext Bundle context from which services are fetched to 
inject.
+     * @param properties Service properties (used to resolve dynamic reference 
properties)
+     * @return true if all dependencies could be injected, false if the 
service has no dependencies.
+     */
+    public static boolean injectServices(Object target, BundleContext 
bundleContext, Map<String, Object> properties) {
+        return OsgiServiceUtil.injectServices(target, bundleContext, 
properties);
     }
 
     /**
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 1fca7a5..1e0b8d3 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
@@ -470,20 +470,20 @@ public String getModifiedMethodName() {
 
     static class Reference {
 
-        private final Class<?> clazz;
-        private final String name;
-        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 final String target;
-        private final Filter targetFilter;
-
-        private Reference(Class<?> clazz, Node node) {
+        protected final Class<?> clazz;
+        protected final String name;
+        protected final String interfaceType;
+        protected final ReferenceCardinality cardinality;
+        protected final ReferencePolicy policy;
+        protected final ReferencePolicyOption policyOption;
+        protected final String bind;
+        protected final String unbind;
+        protected final String field;
+        protected final FieldCollectionType fieldCollectionType;
+        protected String target;
+        protected Filter targetFilter;
+
+        protected Reference(Class<?> clazz, Node node) {
             this.clazz = clazz;
             this.name = getAttributeValue(node, "name");
             this.interfaceType = getAttributeValue(node, "interface");
@@ -507,6 +507,21 @@ private Reference(Class<?> clazz, Node node) {
             }
         }
 
+        protected Reference(Reference reference) {
+            this.clazz = reference.clazz;
+            this.name = reference.name;
+            this.interfaceType = reference.interfaceType;
+            this.cardinality = reference.cardinality;
+            this.policy = reference.policy;
+            this.policyOption = reference.policyOption;
+            this.bind = reference.bind;
+            this.unbind = reference.unbind;
+            this.field = reference.field;
+            this.fieldCollectionType = reference.fieldCollectionType;
+            this.target = reference.target;
+            this.targetFilter = reference.targetFilter;
+        }
+
         public Class<?> getServiceClass() {
             return clazz;
         }
@@ -614,6 +629,22 @@ private static FieldCollectionType 
toFieldCollectionType(String value) {
 
     }
 
+    static class DynamicReference extends Reference {
+        public DynamicReference(Reference reference, String target) {
+            super(reference);
+            this.target = target;
+            if (StringUtils.isNotEmpty(this.target)) {
+                try {
+                    this.targetFilter = new FilterImpl(this.target);
+                } catch (InvalidSyntaxException ex) {
+                    throw new RuntimeException("Invalid target filter in 
reference '" + this.name + "' of class " + clazz.getName(), ex);
+                }
+            }
+            else {
+                this.targetFilter = null;
+            }
+        }
+    }
 
     /**
      * Options for {@link Reference#cardinality()} property.
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 b3fd20c..488b4fe 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
@@ -31,6 +31,7 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.scr.impl.inject.Annotations;
+import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.DynamicReference;
 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;
@@ -369,9 +370,10 @@ private static void setField(Object target, Field field, 
Object value) {
      * multiple references.
      * @param target Service instance
      * @param bundleContext Bundle context from which services are fetched to 
inject.
+     * @param properties Services properties (used to resolve dynamic 
reference properties)
      * @return true if all dependencies could be injected, false if the 
service has no dependencies.
      */
-    public static boolean injectServices(Object target, BundleContext 
bundleContext) {
+    public static boolean injectServices(Object target, BundleContext 
bundleContext, Map<String, Object> properties) {
 
         // collect all declared reference annotations on class and field level
         Class<?> targetClass = target.getClass();
@@ -387,6 +389,13 @@ public static boolean injectServices(Object target, 
BundleContext bundleContext)
 
         // try to inject services
         for (Reference reference : references) {
+            if (properties != null) {
+                // Look for a target override
+                Object o = properties.get(reference.getName() + ".target");
+                if (o != null && o instanceof String) {
+                    reference = new DynamicReference(reference,(String)o);
+                }
+            }
             injectServiceReference(reference, target, bundleContext);
         }
         return true;
diff --git 
a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java 
b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
index acb96e7..ae9d0b2 100644
--- 
a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
+++ 
b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
@@ -150,7 +150,7 @@ public final BundleContext bundleContext() {
      * @return Registered service instance
      */
     public final <T> T registerInjectActivateService(final T service, final 
Map<String, Object> properties) {
-        MockOsgi.injectServices(service, bundleContext());
+        MockOsgi.injectServices(service, bundleContext(), properties);
         MockOsgi.activate(service, bundleContext(), properties);
         registerService(null, service, properties);
         return service;
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java 
b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
index d1f57fc..db6c8d4 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Mock implementation of selected OSGi APIs.
  */
-@org.osgi.annotation.versioning.Version("3.3")
+@org.osgi.annotation.versioning.Version("3.4")
 package org.apache.sling.testing.mock.osgi;
diff --git 
a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
 
b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
index b7d022c..fa8a8c4 100644
--- 
a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
+++ 
b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
@@ -63,6 +63,8 @@
     private ServiceSuperInterface3 dependency3a;
     @Mock
     private ServiceSuperInterface3 dependency3b;
+    @Mock
+    private ServiceSuperInterface3 dependency3c;
 
     @Before
     public void setUp() {
@@ -75,7 +77,7 @@ public void setUp() {
         service = new Service3OsgiR6();
         MockOsgi.injectServices(service, bundleContext);
         MockOsgi.activate(service, bundleContext);
-        bundleContext.registerService(Service3OsgiR6.class.getName(), service, 
null);
+        bundleContext.registerService(Service3OsgiR6.class.getName(), service, 
MapUtil.toDictionary(ImmutableMap.<String,Object>of("reference3DynamicFiltered.target","(prop1=def)")));
         
         assertDependency1(dependency1a);
         assertDependency1Optional(null);
@@ -152,6 +154,22 @@ public void testReferenceWithTargetFilter() {
         assertDependencies3Filtered(dependency3a);
     }
     
+    @Test
+    public void testReferenceWithDynamicTargetFilter() {
+        assertDependencies3DynamicFiltered(null);
+        
+        bundleContext.registerService(ServiceInterface3.class.getName(), 
dependency3a, 
+                MapUtil.toDictionary(ImmutableMap.<String, Object>of("prop1", 
"abc")));
+
+        bundleContext.registerService(ServiceInterface3.class.getName(), 
dependency3b, 
+                MapUtil.toDictionary(ImmutableMap.<String, Object>of("prop1", 
"def")));
+
+        bundleContext.registerService(ServiceInterface3.class.getName(), 
dependency3c, 
+                MapUtil.toDictionary(ImmutableMap.<String, Object>of("prop1", 
"hij")));
+        
+        assertDependencies3DynamicFiltered(dependency3b);
+    }
+
     private void assertDependency1(ServiceInterface1 instance) {
         if (instance == null) {
             assertNull(service.getReference1());
@@ -184,5 +202,9 @@ private void 
assertDependencies3Filtered(ServiceSuperInterface3... instances) {
         assertEquals(ImmutableSet.<ServiceSuperInterface3>copyOf(instances), 
                 
ImmutableSet.<ServiceSuperInterface3>copyOf(service.getReferences3Filtered()));
     }
-    
+
+    private void assertDependencies3DynamicFiltered(ServiceSuperInterface3 
instance) {
+        assertEquals(instance,service.getReference3DynamicFiltered());
+    }
+
 }
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 1f92fa7..6ae014a 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
@@ -341,6 +341,7 @@ protected void unbindReference3(ServiceSuperInterface3 
service, Map<String, Obje
         private List<ServiceReference> references2;
         private List<ServiceSuperInterface3> references3;
         private List<ServiceSuperInterface3> references3Filtered;
+        private ServiceSuperInterface3 reference3DynamicFiltered;
 
         private ComponentContext componentContext;
         private Map<String, Object> config;
@@ -385,6 +386,11 @@ public ServiceInterface1Optional getReference1Optional() {
             return this.references3Filtered;
         }
 
+
+        public ServiceSuperInterface3 getReference3DynamicFiltered() {
+            return this.reference3DynamicFiltered;
+        }
+
         public ComponentContext getComponentContext() {
             return this.componentContext;
         }
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 0229572..7698b9e 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
@@ -51,6 +51,7 @@
     <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"/>
     <reference name="references3Filtered" 
interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3"
 cardinality="0..n" policy="dynamic" field="references3Filtered" 
field-collection-type="service" target="(prop1=abc)"/>
+    <reference name="reference3DynamicFiltered" 
interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3"
 cardinality="0..1" policy="dynamic" field="reference3DynamicFiltered" 
field-collection-type="service"/>
   </scr:component>
   <scr:component 
name="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3StaticGreedy"
 activate="activate" deactivate="deactivate" modified="modified">
     <implementation 
class="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3StaticGreedy"/>


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to