Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5A0701825B for ; Thu, 17 Dec 2015 22:46:36 +0000 (UTC) Received: (qmail 87363 invoked by uid 500); 17 Dec 2015 22:46:36 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 87229 invoked by uid 500); 17 Dec 2015 22:46:36 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 87208 invoked by uid 99); 17 Dec 2015 22:46:36 -0000 Received: from Unknown (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Dec 2015 22:46:36 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id B5205C8934 for ; Thu, 17 Dec 2015 22:46:35 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.79 X-Spam-Level: * X-Spam-Status: No, score=1.79 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id 0ZmZsGaS-Jxs for ; Thu, 17 Dec 2015 22:46:34 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTP id 1AD0D42A6A for ; Thu, 17 Dec 2015 22:46:34 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 7455AE0044 for ; Thu, 17 Dec 2015 22:46:33 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 0D4283A043D for ; Thu, 17 Dec 2015 22:46:33 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1720692 - in /felix/sandbox/pderop/dependencymanager-lambda: org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/ org.apache.felix.dependencymanager.lambda.samples/ org.apache.felix.dependencymanage... Date: Thu, 17 Dec 2015 22:46:32 -0000 To: commits@felix.apache.org From: pderop@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20151217224633.0D4283A043D@svn01-us-west.apache.org> 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 CompletableFuture object. * - * @param + *

Usage Examples

+ * + *

Here is an Activator which downloads a page from the web and inject the string result to a component. + * + *

+ *
+ * 
+ * public class Activator extends DependencyActivatorBase {
+ * 
+ *   @Override
+ *   public void init() throws Exception {    	
+ *      String url = "http://felix.apache.org/";
+ *  	CompletableFuture 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)));
+ *     
+ *   }
+ * 
+ * }
+ * 
+ *
+ * + * @param the type of the CompletableFuture result. */ public interface FutureDependencyBuilder extends DependencyBuilder { - FutureDependencyBuilder thenRun(Runnable action); - FutureDependencyBuilder thenRunAsync(Runnable action); - FutureDependencyBuilder thenRunAsync(Runnable action, Executor executor); - FutureDependencyBuilder thenAccept(Consumer block); - FutureDependencyBuilder thenAcceptAsync(Consumer block); - FutureDependencyBuilder thenAcceptAsync(Consumer 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 thenAccept(Consumer 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 + */ + FutureDependencyBuilder thenAccept(Consumer2 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 thenAcceptAsync(Consumer 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 + */ + FutureDependencyBuilder thenAcceptAsync(Consumer2 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 thenAcceptAsync(Consumer 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 + */ + FutureDependencyBuilder thenAcceptAsync(Consumer2 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 { private final CompletableFuture m_future; - private Runnable m_action; - private Consumer m_accept; + private Consumer m_accept; + private Consumer2 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 thenRun(Runnable action) { - m_action = action; + public FutureDependencyBuilder thenAccept(Consumer consumer) { + m_accept = (Consumer) consumer; return this; } + @SuppressWarnings("unchecked") @Override - public FutureDependencyBuilder thenRunAsync(Runnable action) { - m_action = action; - m_async = true; + public FutureDependencyBuilder thenAccept(Consumer2 consumer) { + m_accept2 = (Consumer2) consumer; return this; } + @SuppressWarnings("unchecked") @Override - public FutureDependencyBuilder thenRunAsync(Runnable action, Executor executor) { - m_action = action; + public FutureDependencyBuilder thenAcceptAsync(Consumer consumer) { + m_accept = (Consumer) consumer; m_async = true; - m_exec = executor; return this; - } + } @Override - public FutureDependencyBuilder thenAccept(Consumer block) { - m_accept = (Consumer) block; + public FutureDependencyBuilder thenAcceptAsync(Consumer2 consumer) { + thenAccept(consumer); + m_async = true; return this; - } + } + @SuppressWarnings("unchecked") @Override - public FutureDependencyBuilder thenAcceptAsync(Consumer block) { - m_accept = (Consumer) block; + public FutureDependencyBuilder thenAcceptAsync(Consumer consumer, Executor executor) { + m_accept = (Consumer) consumer; m_async = true; + m_exec = executor; return this; } @Override - public FutureDependencyBuilder thenAcceptAsync(Consumer block, Executor executor) { - m_accept = (Consumer) block; + public FutureDependencyBuilder thenAcceptAsync(Consumer2 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(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("")); }