Author: pderop
Date: Thu Dec 17 22:46:32 2015
New Revision: 1720692

URL: http://svn.apache.org/viewvc?rev=1720692&view=rev
Log:
- Added javadoc in FutureDependencyBuilder.                                     
                                                                                
                                 
- Removed thenRun methods in FutureDependencyBuilder.                           
                                                                                
                                 
- Added thenAccept methods in FutureDependencyBuilder which allow to specify 
action callbacks on component instances using BiConsumers.                      
                                    

Modified:
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/future.bndrun
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
    
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java?rev=1720692&r1=1720691&r2=1720692&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ServiceUpdateTest.java
 Thu Dec 17 22:46:32 2015
@@ -127,7 +127,8 @@ public class ServiceUpdateTest extends T
         void destroy() {
             System.out.println("destroy");
         }
-        void changed(Component component) {
+        @SuppressWarnings("unchecked")
+               void changed(Component component) {
             System.out.println("resource changed");
             m_ensure.step(3);
             

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/future.bndrun
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/future.bndrun?rev=1720692&r1=1720691&r2=1720692&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/future.bndrun
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/future.bndrun
 Thu Dec 17 22:46:32 2015
@@ -15,5 +15,3 @@
        org.apache.felix.dependencymanager;version=4.2.0,\
        org.apache.felix.dependencymanager.shell;version=4.0.3,\
        org.apache.felix.dependencymanager.lambda;version=latest
-
-       
\ No newline at end of file

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java?rev=1720692&r1=1720691&r2=1720692&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/SiteInfoImpl.java
 Thu Dec 17 22:46:32 2015
@@ -44,7 +44,7 @@ public class SiteInfoImpl implements Sit
                                CompletableFuture.supplyAsync(() -> 
downloadSite(m_url))
                                .thenApply(this::getSiteLinks);
                                                                
-        component(c, builder -> builder.withFuture(links, b -> 
b.thenAccept(this::setLinks)));
+        component(c, builder -> builder.withFuture(links, future -> 
future.thenAccept(this::setLinks)));
        }
        
        // Called when our future has completed.

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java?rev=1720692&r1=1720691&r2=1720692&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/FutureDependencyBuilder.java
 Thu Dec 17 22:46:32 2015
@@ -1,20 +1,92 @@
 package org.apache.felix.dm.builder.lambda;
 
 import java.util.concurrent.Executor;
-import java.util.function.Consumer;
 
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.builder.lambda.Functions.Consumer;
+import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
 
 /**
- * TODO javadoc
+ * Defines a builder for DependencyManager CompletableFuture dependency.
+ * Using such dependency allows your component to wait for the completion of a 
given asynchronous task
+ * represented by a standard jdk <code>CompletableFuture</code> object.
  * 
- *  @param <T>
+ * <h3>Usage Examples</h3>
+ * 
+ * <p> Here is an Activator which downloads a page from the web and inject the 
string result to a component.
+ * 
+ * <blockquote>
+ * <pre>
+ * 
+ * public class Activator extends DependencyActivatorBase {
+ * 
+ *   @Override
+ *   public void init() throws Exception {     
+ *      String url = "http://felix.apache.org/";;
+ *     CompletableFuture<String> felixFuture = 
CompletableFuture.supplyAsync(() -> downloadSite(url));                         
+ *
+ *     // The component depends on a log service and on the content of the 
Felix site.
+ *      component(comp -> comp
+ *             .impl(MyComponent.class)
+ *          .withService(LogService.class, srv -> 
srv.onAdd(SiteInfoImpl::bindLog))
+ *          .withFuture(felixFuture, future -> 
future.thenAccept(SiteInfoImpl::bindFelixPage)));
+ *     
+ *   }
+ * 
+ * }
+ * </pre>
+ * </blockquote>
+ * 
+ * @param <T> the type of the CompletableFuture result.
  */
 public interface FutureDependencyBuilder<T> extends 
DependencyBuilder<Dependency> {
-       FutureDependencyBuilder<T> thenRun(Runnable action);    
-       FutureDependencyBuilder<T> thenRunAsync(Runnable action);       
-       FutureDependencyBuilder<T> thenRunAsync(Runnable action, Executor 
executor);    
-       FutureDependencyBuilder<T> thenAccept(Consumer<? super T> block);
-       FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> block);
-       FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> block, 
Executor executor);
+       /**
+        * Sets the action to perform when the future task has completed. The 
action is a Consumer instance which accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @return this dependency
+        */
+       FutureDependencyBuilder<T> thenAccept(Consumer<? super T> action);
+       
+       /**
+        * Sets the action to perform when the future task has completed. The 
action is one of the Component instance method that accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @return this dependency
+        */
+       <I> FutureDependencyBuilder<T> thenAccept(Consumer2<I, ? super T> 
action);
+       
+       /**
+        * Sets the action to perform asynchronously when the future task has 
completed. The action is a Consumer instance which accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @return this dependency
+        */
+       FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> action);
+       
+       /**
+        * Sets the action to perform asynchronously when the future task has 
completed. The action is one of the Component instance method that accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @return this dependency
+        */
+       <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? super T> 
action);
+
+       /**
+        * Sets the action to perform asynchronously when the future task has 
completed. The action is a Consumer instance which accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @param executor the executor to use for asynchronous execution of 
the action.
+        * @return this dependency
+        */
+       FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> action, 
Executor executor);      
+       
+       /**
+        * Sets the action to perform asynchronously when the future task has 
completed. The action is one of the Component instance method that accepts the
+        * result of the completed future.
+        * @param action the action to perform when the future task as 
completed. 
+        * @param executor the executor to use for asynchronous execution of 
the action.
+        * @return this dependency
+        */
+       <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? super T> 
action, Executor executor);      
 }

Modified: 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java?rev=1720692&r1=1720691&r2=1720692&view=diff
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
 (original)
+++ 
felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/CompletableFutureDependencyImpl.java
 Thu Dec 17 22:46:32 2015
@@ -2,10 +2,12 @@ package org.apache.felix.dm.builder.lamb
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
-import java.util.function.Consumer;
+import java.util.stream.Stream;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.builder.lambda.Functions.Consumer;
+import org.apache.felix.dm.builder.lambda.Functions.Consumer2;
 import org.apache.felix.dm.builder.lambda.FutureDependencyBuilder;
 import org.apache.felix.dm.context.AbstractDependency;
 import org.apache.felix.dm.context.DependencyContext;
@@ -17,8 +19,8 @@ public class CompletableFutureDependency
                implements FutureDependencyBuilder<T> {
 
        private final CompletableFuture<T> m_future;
-       private Runnable m_action;
-       private Consumer<T> m_accept;
+       private Consumer<? super T> m_accept;
+       private Consumer2<Object, ? super T> m_accept2;
        private Component m_comp;
        private boolean m_async;
        private Executor m_exec;
@@ -46,43 +48,47 @@ public class CompletableFutureDependency
                return this;
        }
 
+       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenRun(Runnable action) {
-               m_action = action;
+       public FutureDependencyBuilder<T> thenAccept(Consumer<? super T> 
consumer) {
+               m_accept = (Consumer<T>) consumer;
                return this;
        }
 
+       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenRunAsync(Runnable action) {
-               m_action = action;
-               m_async = true;
+       public <I> FutureDependencyBuilder<T> thenAccept(Consumer2<I, ? super 
T> consumer) {
+               m_accept2 = (Consumer2<Object, T>) consumer;
                return this;
        }
 
+       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenRunAsync(Runnable action, 
Executor executor) {
-               m_action = action;
+       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
consumer) {
+               m_accept = (Consumer<T>) consumer;
                m_async = true;
-               m_exec = executor;
                return this;
-       }
+       }       
 
        @Override
-       public FutureDependencyBuilder<T> thenAccept(Consumer<? super T> block) 
{
-               m_accept = (Consumer<T>) block;
+       public <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? 
super T> consumer) {
+               thenAccept(consumer);
+               m_async = true;
                return this;
-       }
+       }       
 
+       @SuppressWarnings("unchecked")
        @Override
-       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
block) {
-               m_accept = (Consumer<T>) block;
+       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
consumer, Executor executor) {
+               m_accept = (Consumer<T>) consumer;
                m_async = true;
+               m_exec = executor;
                return this;
        }
 
        @Override
-       public FutureDependencyBuilder<T> thenAcceptAsync(Consumer<? super T> 
block, Executor executor) {
-               m_accept = (Consumer<T>) block;
+       public <I> FutureDependencyBuilder<T> thenAcceptAsync(Consumer2<I, ? 
super T> consumer, Executor executor) {
+               thenAccept(consumer);
                m_async = true;
                m_exec = executor;
                return this;
@@ -110,7 +116,7 @@ public class CompletableFutureDependency
 
        @Override
        public DependencyContext createCopy() {
-               return new CompletableFutureDependencyImpl(m_comp, this);
+               return new CompletableFutureDependencyImpl<T>(m_comp, this);
        }
 
        @Override
@@ -146,10 +152,18 @@ public class CompletableFutureDependency
                        
super.getComponentContext().getLogger().log(LogService.LOG_ERROR, "completable 
future failed", error);
                } else {
                        try {
-                               if (m_action != null) {
-                                       m_action.run();
-                               } else if (m_accept != null) {
+                               if (m_accept != null) {
                                        m_accept.accept(result);
+                               } else if (m_accept2 != null) {
+                                       // If using a bi consumer, we need to 
find one of the component instance which type is compatible
+                                       // with the first type of the bi 
consumer method reference.
+                                       String type = 
Helpers.getLambdaGenericType(m_accept2);
+                                       Object componentInstance = 
Stream.of(getComponentContext().getInstances())
+                                               .filter(instance -> 
Helpers.getClassName(instance).equals(type))
+                                               .findFirst()
+                                               .orElseThrow(() -> new 
IllegalArgumentException("accept callback is not on one of the component 
instances: " + m_accept2 + " (type=" + type + ")"));
+                                       
+                                       m_accept2.accept(componentInstance, 
result);
                                }
                                m_component.handleEvent(this, EventType.ADDED, 
new Event(""));
                        }


Reply via email to