You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2017/02/08 22:35:05 UTC

svn commit: r1782269 - in /felix/trunk/dependencymanager: org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/ org.apache.feli...

Author: pderop
Date: Wed Feb  8 22:35:05 2017
New Revision: 1782269

URL: http://svn.apache.org/viewvc?rev=1782269&view=rev
Log:
FELIX-5531: Document dependency callback signatures.
FELIX-5532: Swap callback is missing in @ServiceDependency annotation.
fixed some typo.


Added:
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ProviderSwappedByAspect.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/ProviderSwappedByAspectTest.java
Modified:
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/FELIX5516Test.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/DependencyBuilder.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/JsonReader.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java Wed Feb  8 22:35:05 2017
@@ -32,6 +32,42 @@ import java.lang.annotation.Target;
  * with the specified interface and existing properties from the original service plus any extra 
  * properties you supply here. If you declare the original service as a member it will be injected.
  * 
+ * <p> For "add", "change", "remove" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Component comp, ServiceReference ref, Service service)
+ * (Component comp, ServiceReference ref, Object service)
+ * (Component comp, ServiceReference ref)
+ * (Component comp, Service service)
+ * (Component comp, Object service)
+ * (Component comp)
+ * (Component comp, Map properties, Service service)
+ * (ServiceReference ref, Service service)
+ * (ServiceReference ref, Object service)
+ * (ServiceReference ref)
+ * (Service service)
+ * (Service service, Map propeerties)
+ * (Map properties, Service, service)
+ * (Service service, Dictionary properties)
+ * (Dictionary properties, Service service)
+ * (Object service)
+ * }</pre>
+ * 
+ * <p> For "swap" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Service old, Service replace)
+ * (Object old, Object replace)
+ * (ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (Component comp, Service old, Service replace)
+ * (Component comp, Object old, Object replace)
+ * (Component comp, ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (Component comp, ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (ServiceReference old, ServiceReference replace)
+ * (Component comp, ServiceReference old, ServiceReference replace)
+ * }</pre>
+ * 
  * <h3>Usage Examples</h3>
  * 
  * <p> Here, the AdapterService is registered into the OSGI registry each time an AdapteeService

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java Wed Feb  8 22:35:05 2017
@@ -32,6 +32,42 @@ import java.lang.annotation.Target;
  * extra properties you supply here. It will also inherit all dependencies, 
  * and if you declare the original service as a member it will be injected.
  * 
+ * <p> For "add", "change", "remove" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Component comp, ServiceReference ref, Service service)
+ * (Component comp, ServiceReference ref, Object service)
+ * (Component comp, ServiceReference ref)
+ * (Component comp, Service service)
+ * (Component comp, Object service)
+ * (Component comp)
+ * (Component comp, Map properties, Service service)
+ * (ServiceReference ref, Service service)
+ * (ServiceReference ref, Object service)
+ * (ServiceReference ref)
+ * (Service service)
+ * (Service service, Map propeerties)
+ * (Map properties, Service, service)
+ * (Service service, Dictionary properties)
+ * (Dictionary properties, Service service)
+ * (Object service)
+ * }</pre>
+ * 
+ * <p> For "swap" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Service old, Service replace)
+ * (Object old, Object replace)
+ * (ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (Component comp, Service old, Service replace)
+ * (Component comp, Object old, Object replace)
+ * (Component comp, ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (Component comp, ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (ServiceReference old, ServiceReference replace)
+ * (Component comp, ServiceReference old, ServiceReference replace)
+ * }</pre>
+ * 
  * <h3>Usage Examples</h3>
  * 
  * <p> Here, the AspectService is registered into the OSGI registry each time an InterceptedService

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java Wed Feb  8 22:35:05 2017
@@ -27,6 +27,42 @@ import java.lang.annotation.Target;
  * Annotates a method or a field for injecting a Service Dependency. When applied on a class 
  * field, optional unavailable dependencies are injected with a NullObject.
  * 
+ * <p> For "add", "change", "remove" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Component comp, ServiceReference ref, Service service)
+ * (Component comp, ServiceReference ref, Object service)
+ * (Component comp, ServiceReference ref)
+ * (Component comp, Service service)
+ * (Component comp, Object service)
+ * (Component comp)
+ * (Component comp, Map properties, Service service)
+ * (ServiceReference ref, Service service)
+ * (ServiceReference ref, Object service)
+ * (ServiceReference ref)
+ * (Service service)
+ * (Service service, Map propeerties)
+ * (Map properties, Service, service)
+ * (Service service, Dictionary properties)
+ * (Dictionary properties, Service service)
+ * (Object service)
+ * }</pre>
+ * 
+ * <p> For "swap" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Service old, Service replace)
+ * (Object old, Object replace)
+ * (ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (Component comp, Service old, Service replace)
+ * (Component comp, Object old, Object replace)
+ * (Component comp, ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (Component comp, ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (ServiceReference old, ServiceReference replace)
+ * (Component comp, ServiceReference old, ServiceReference replace)
+ * }</pre>
+ * 
  * <h3>Usage Examples</h3>
  * Here, the MyComponent component is injected with a dependency over a "MyDependency" service
  * 
@@ -79,6 +115,7 @@ public @interface ServiceDependency
     /**
      * The callback method to be invoked when the service is available. This attribute is only meaningful when 
      * the annotation is applied on a class field.
+     * 
      * @return the add callback
      */
     String added() default "";
@@ -95,6 +132,12 @@ public @interface ServiceDependency
      */
     String removed() default "";
     
+    /**
+     * the method to call when the service was swapped due to addition or removal of an aspect
+     * @return the swap callback
+     */
+    String swap() default "";
+
     /** 
      * The max time in millis to wait for the dependency availability. 
      * Specifying a positive number allow to block the caller thread between service updates. Only
@@ -160,7 +203,9 @@ public @interface ServiceDependency
      * <code>BundleContext.getService(ServiceReference ref)</code> methods. 
      * However, sometimes, your callback only needs the ServiceReference, and sometimes you don't want to dereference the service.
      * So, in this case you can use the <code>dereference(false)</code> method in order to tell to DM 
-     * that it should never internally dereference the service dependency internally. 
+     * that it should never internally dereference the service dependency internally.
+     * 
+     * @return false if the service must never be dereferenced by dependency manager (internally).
      */
     boolean dereference() default true;
 }

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java Wed Feb  8 22:35:05 2017
@@ -722,6 +722,9 @@ public class AnnotationCollector extends
         // removed callback
         writer.putString(annotation, EntryParam.removed, null); 
         
+        // swap callback
+        writer.putString(annotation, EntryParam.swap, null); 
+
         // name attribute
         parseDependencyName(writer, annotation);
         

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/FELIX5516Test.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/FELIX5516Test.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/FELIX5516Test.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/FELIX5516Test.java Wed Feb  8 22:35:05 2017
@@ -30,15 +30,30 @@ import org.osgi.framework.ServiceReferen
 import org.osgi.framework.ServiceRegistration;
 
 /**
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * Validates that a service dependency is not dereferenced internally by DM.
+ * When you use a method reference for the dependency callback, then dm-lambda auto-detect that the
+ * service dependency must not be internally dereferenced.
+ * But you when you method reflection based callbacks, you have to call the "dereference(false)" method
+ * from the ServiceDependencyBuilder, which indicates to DM that the service reference must not be 
+ * dereferenced internally (using BundleContext.getServiceReference() method). 
  */
 public class FELIX5516Test extends TestBase {
-    private final static Ensure m_ensure = new Ensure();
+    private final Ensure m_ensure = new Ensure();
 
-    public void testServiceNotDereferencedInternally() throws Exception {
+    public void testServiceNotDereferencedInternallyUsingMethodReference() throws Exception {
         final DependencyManager dm = getDM();
         Component service = component(dm).impl(new Factory()).provides(Service.class).build();
-        Component client = component(dm).impl(new Client()).withSvc(Service.class, svc -> svc.required().dereference(false).add(Client::bind)).build();
+        Component client = component(dm).impl(new Client()).withSvc(Service.class, svc -> svc.required().add(Client::bind)).build();
+        dm.add(service);
+        dm.add(client);
+        m_ensure.waitForStep(9,  5000);        
+        dm.clear();
+    }
+    
+    public void testServiceNotDereferencedInternallyUsingReflectionCallback() throws Exception {
+        final DependencyManager dm = getDM();
+        Component service = component(dm).impl(new Factory()).provides(Service.class).build();
+        Component client = component(dm).impl(new Client()).withSvc(Service.class, svc -> svc.required().dereference(false).add("bind")).build();
         dm.add(service);
         dm.add(client);
         m_ensure.waitForStep(9,  5000);        
@@ -47,11 +62,11 @@ public class FELIX5516Test extends TestB
 
     public interface Service {}
     
-    public static class ServiceImpl implements Service {
+    public class ServiceImpl implements Service {
     	
     }
     
-    public static class Factory implements PrototypeServiceFactory<Service> {
+    public class Factory implements PrototypeServiceFactory<Service> {
 		@Override
 		public Service getService(Bundle bundle, ServiceRegistration<Service> registration) {
 			m_ensure.step();
@@ -64,7 +79,7 @@ public class FELIX5516Test extends TestB
 		}
     }
     
-    public static class Client {
+    public class Client {
     	ServiceReference<Service> m_ref;
         BundleContext m_ctx;
                 

Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ProviderSwappedByAspect.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ProviderSwappedByAspect.java?rev=1782269&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ProviderSwappedByAspect.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ProviderSwappedByAspect.java Wed Feb  8 22:35:05 2017
@@ -0,0 +1,99 @@
+/*
+ * 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.felix.dm.runtime.itest.components;
+
+import org.apache.felix.dm.annotation.api.AspectService;
+import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.itest.util.Ensure;
+
+/**
+ * Check if a client already bound to a service provider is called in swap method
+ * when an aspect service replaces the original service.
+ */
+public class ProviderSwappedByAspect {
+	
+    public interface ProviderService {
+        public void run();
+    }
+
+    /**
+     * Tests an aspect service, and ensure that its lifecycle methods are properly invoked (init/start/stop/destroy)
+     */
+    @Component
+    public static class Consumer {
+        public final static String ENSURE = "ProviderSwappedByAspect.Consumer";
+        final static Ensure.Steps m_steps = new Ensure.Steps(
+        		1, // provider bound the first time in bind method
+        		3, // swap called (aspect is replacing provider)
+        		6, // aspect removed , so swap called again with original service
+        		8  // provider removed
+        		);
+
+        @ServiceDependency(filter = "(name=" + ENSURE + ")")
+        protected volatile Ensure m_sequencer;
+
+        @ServiceDependency(removed="unbind", swap="swap")
+        void bind(ProviderService service) {
+        	m_sequencer.steps(m_steps); 
+            service.run(); 
+        }
+        
+        void swap(ProviderService old, ProviderService replace) {
+        	System.out.println("swapped: old=" + old + ", replace=" + replace);
+        	m_sequencer.steps(m_steps); 
+        	replace.run(); 
+        }
+        
+        void unbind(ProviderService service) {
+        	m_sequencer.steps(m_steps);
+        	service.run(); 
+        }
+    }
+
+    @Component
+    public static class Provider implements ProviderService {
+        public final static String ENSURE = "ProviderSwappedByAspect.Provider";
+        
+        @ServiceDependency(filter = "(name=" + ENSURE + ")")
+        protected volatile Ensure m_sequencer;
+
+        public void run() {
+            m_sequencer.step();
+        }
+    }
+
+    @AspectService(ranking = 10, added="bind")
+    public static class ProviderAspect implements ProviderService {
+        public final static String ENSURE = "ProviderSwappedByAspect.ProviderAspect";
+		private ProviderService m_next;
+        
+        void bind(ProviderService provider) {
+        	m_next = provider;
+        }
+        
+        @ServiceDependency(filter = "(name=" + ENSURE + ")")
+        protected volatile Ensure m_sequencer;
+
+        public void run() {
+            m_sequencer.step();
+            m_next.run();
+        }
+    }
+}

Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/ProviderSwappedByAspectTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/ProviderSwappedByAspectTest.java?rev=1782269&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/ProviderSwappedByAspectTest.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/ProviderSwappedByAspectTest.java Wed Feb  8 22:35:05 2017
@@ -0,0 +1,60 @@
+/*
+* 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.felix.dm.runtime.itest.tests;
+
+import org.apache.felix.dm.itest.util.Ensure;
+import org.apache.felix.dm.itest.util.TestBase;
+import org.apache.felix.dm.runtime.itest.components.ProviderSwappedByAspect;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Check if a client already bound to a service provider is called in swap method
+ * when an aspect service replaces the original service.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings("rawtypes")
+public class ProviderSwappedByAspectTest extends TestBase {
+    
+	public void testAnnotatedAspect() {
+        Ensure e = new Ensure();
+        ServiceRegistration consumer = register(e, ProviderSwappedByAspect.Consumer.ENSURE);
+        ServiceRegistration provider = register(e, ProviderSwappedByAspect.Provider.ENSURE);
+        
+        // client bound to provider (1), and client calls provider (2)
+        e.waitForStep(2, 5000);
+        
+        ServiceRegistration aspect = register(e, ProviderSwappedByAspect.ProviderAspect.ENSURE);
+
+        // provider swapped with aspect (3), aspect called (4), original provider called (5)     
+        e.waitForStep(5, 5000);
+        
+        aspect.unregister();
+        
+        // aspect swapped by provider (6), provider called (7)
+        e.waitForStep(7, 5000);
+
+        provider.unregister();
+        
+        //provider unbound (8), provider called (9)
+        e.waitForStep(9, 5000);
+        
+        consumer.unregister();
+    }
+}

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/DependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/DependencyBuilder.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/DependencyBuilder.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/DependencyBuilder.java Wed Feb  8 22:35:05 2017
@@ -101,6 +101,7 @@ public class DependencyBuilder
         long timeout = m_metaData.getLong(Params.timeout, -1L);
         String changed = timeout != -1 ? null : m_metaData.getString(Params.changed, null);
         String removed = timeout != -1 ? null : m_metaData.getString(Params.removed, null);
+        String swap = m_metaData.getString(Params.swap, null);
         String autoConfigField = m_metaData.getString(Params.autoConfig, null);
         boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
         boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
@@ -108,13 +109,13 @@ public class DependencyBuilder
 
         Dependency dp = createServiceDependency(dm, serviceClass,
             serviceFilter, defaultServiceImplClass, added, changed,
-            removed, autoConfigField, timeout, required, propagate, dereference);
+            removed, swap, autoConfigField, timeout, required, propagate, dereference);
         return dp;
     }
 
     private Dependency createServiceDependency(DependencyManager dm, Class<?> serviceClass, 
         String serviceFilter, Class<?> defaultServiceImplClass, String added,
-        String changed, String removed, String autoConfigField, long timeout, boolean required,
+        String changed, String removed, String swap, String autoConfigField, long timeout, boolean required,
         boolean propagate, boolean dereference)
     {
         ServiceDependency sd = timeout != -1 ? dm.createTemporalServiceDependency(timeout)
@@ -124,7 +125,7 @@ public class DependencyBuilder
         {
             sd.setDefaultImplementation(defaultServiceImplClass);
         }
-        sd.setCallbacks(added, changed, removed);
+        sd.setCallbacks(added, changed, removed, swap);
         if (autoConfigField != null)
         {
             sd.setAutoConfig(autoConfigField);

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/JsonReader.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/JsonReader.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/JsonReader.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/JsonReader.java Wed Feb  8 22:35:05 2017
@@ -31,7 +31,7 @@ import java.util.regex.Pattern;
 /**
  * A very small JSON parser.
  * Code adapted from the org.apache.felix.serializer.impl.json.JsonParser.java, 
- * from the Apache Felix Converter proejct.
+ * from the Apache Felix Converter project.
  *
  * The JSON input is parsed into an object structure in the following way:
  * <ul>

Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java?rev=1782269&r1=1782268&r2=1782269&view=diff
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java (original)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java Wed Feb  8 22:35:05 2017
@@ -24,6 +24,42 @@ import org.osgi.framework.ServiceReferen
 /**
  * Service dependency that can track an OSGi service.
  * 
+ * When defining dependency method callbacks; for "add", "change", "remove" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Component comp, ServiceReference ref, Service service)
+ * (Component comp, ServiceReference ref, Object service)
+ * (Component comp, ServiceReference ref)
+ * (Component comp, Service service)
+ * (Component comp, Object service)
+ * (Component comp)
+ * (Component comp, Map properties, Service service)
+ * (ServiceReference ref, Service service)
+ * (ServiceReference ref, Object service)
+ * (ServiceReference ref)
+ * (Service service)
+ * (Service service, Map propeerties)
+ * (Map properties, Service, service)
+ * (Service service, Dictionary properties)
+ * (Dictionary properties, Service service)
+ * (Object service)
+ * }</pre>
+ * 
+ * <p> For "swap" callbacks, the following method signatures are supported:
+ * 
+ * <pre>{@code
+ * (Service old, Service replace)
+ * (Object old, Object replace)
+ * (ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (Component comp, Service old, Service replace)
+ * (Component comp, Object old, Object replace)
+ * (Component comp, ServiceReference old, Service old, ServiceReference replace, Service replace)
+ * (Component comp, ServiceReference old, Object old, ServiceReference replace, Object replace)
+ * (ServiceReference old, ServiceReference replace)
+ * (Component comp, ServiceReference old, ServiceReference replace)
+ * }</pre>
+ * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @ProviderType
@@ -296,6 +332,8 @@ public interface ServiceDependency exten
      * However, sometimes, your callback only needs the ServiceReference, and sometimes you don't want to dereference the service.
      * So, in this case you can use the <code>setDereference(false)</code> method in order to tell to DM 
      * that it should never internally dereference the service dependency internally. 
+     * 
+     * @return false if the service must never be dereferenced by dependency manager (internally).
      */
     public ServiceDependency setDereference(boolean dereferenceServiceInternally);
 }