felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1727453 - /felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/
Date Thu, 28 Jan 2016 23:22:21 GMT
Author: pderop
Date: Thu Jan 28 23:22:21 2016
New Revision: 1727453

URL: http://svn.apache.org/viewvc?rev=1727453&view=rev
Log:
Simplified "future" sample.

Added:
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinks.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinksImpl.java
Removed:
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/DisplayFelixLinks.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/FelixLinks.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/FelixLinksImpl.java
Modified:
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java
    felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.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/Activator.java?rev=1727453&r1=1727452&r2=1727453&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java
(original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/Activator.java
Thu Jan 28 23:22:21 2016
@@ -35,25 +35,33 @@ import org.osgi.service.log.LogService;
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Activator extends DependencyActivatorBase {
-        
+    volatile PageLinks m_siteInfo; // Injected
+    volatile LogService m_log; // Injected
+
     @Override
     public void init() throws Exception {
     	out.println("type \"log info\" to see the logs emitted by this test.");
     	    	
     	// Creates a future that asynchronously download Felix web site.
     	String felix = "http://felix.apache.org/";
-        CompletableFuture<List<String>> futureLinks = CompletableFuture.supplyAsync(()
-> FelixLinksImpl.download(felix))
-            .thenApply(FelixLinksImpl::parseLinks);
+        CompletableFuture<List<String>> futureLinks = CompletableFuture.supplyAsync(()
-> PageLinksImpl.download(felix))
+            .thenApply(PageLinksImpl::parseLinks);
 
-        // Create the FelixLink service, it will be started once our previous future has
completed.
+        // Create the PageLinks service, it will be started once our previous future has
completed.
         component(comp -> comp
-            .impl(FelixLinksImpl.class)
-            .provides(FelixLinks.class)
-            .withSrv(LogService.class, log -> log.cb(FelixLinksImpl::bind))
-            .withFuture(futureLinks, links -> links.cb(FelixLinksImpl::setLinks)));
+            .impl(PageLinksImpl.class)
+            .provides(PageLinks.class)
+            .withSrv(LogService.class, log -> log.cb(PageLinksImpl::bind))
+            .withFuture(futureLinks, links -> links.cb(PageLinksImpl::setLinks)));
+        
+        // Just wait for the PageLinks service and display all links found from the Felix
web site.
+        DisplayLinks displayLinks = new DisplayLinks();
+        component(comp -> comp.impl(displayLinks).withSrv(PageLinks.class, page ->
page.cbi(displayLinks::setPageLinks))); 
+    }
         
-        // Define a component that just displays the links found from the Felix web site.
-        // It depends on a log service and on the FelixLink service, which are both injected
in class fields.
-        component(comp -> comp.impl(DisplayFelixLinks.class).withSrv(LogService.class,
FelixLinks.class)); 
+    static class DisplayLinks {
+        void setPageLinks(PageLinks page) {
+            out.println("Felix site links: " + page.getLinks());
+        }
     }
 }

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinks.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/PageLinks.java?rev=1727453&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinks.java
(added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinks.java
Thu Jan 28 23:22:21 2016
@@ -0,0 +1,10 @@
+package org.apache.felix.dependencymanager.lambda.samples.future;
+
+import java.util.List;
+
+/**
+ * Service that displays all links found from a given web page.
+ */
+public interface PageLinks {
+    List<String> getLinks();
+}

Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinksImpl.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/PageLinksImpl.java?rev=1727453&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinksImpl.java
(added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/PageLinksImpl.java
Thu Jan 28 23:22:21 2016
@@ -0,0 +1,63 @@
+package org.apache.felix.dependencymanager.lambda.samples.future;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * Provides all hrefs found from a given web page.
+ */
+public class PageLinksImpl implements PageLinks {
+	private LogService m_log;
+	final static String HREF_PATTERN = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
+	List<String> m_links; // web page hrefs (links).
+
+	void bind(LogService log) {
+		m_log = log;
+	}
+		
+	// Called when our future has completed.
+	void setLinks(List<String> links) {
+		m_links = links;
+	}
+	
+	// once our future has completed, our component is started.
+	void start() {
+		m_log.log(LogService.LOG_INFO, "Service starting: number of links found from Felix web
site: " + m_links.size());
+	}
+	
+	@Override
+	public List<String> getLinks() {
+		return m_links;
+	}
+
+	public static String download(String url) {
+		try (Scanner in = new Scanner(new URL(url).openStream())) {
+			StringBuilder builder = new StringBuilder();
+			while (in.hasNextLine()) {
+				builder.append(in.nextLine());
+				builder.append("\n");
+			}
+			return builder.toString();
+		} catch (IOException ex) {
+			RuntimeException rex = new RuntimeException();
+			rex.initCause(ex);
+			throw rex;
+		}
+	}
+	
+	public static List<String> parseLinks(String content) {		 
+		Pattern pattern = Pattern.compile(HREF_PATTERN, Pattern.CASE_INSENSITIVE);
+		Matcher matcher = pattern.matcher(content);
+		List<String> result = new ArrayList<>();
+		while (matcher.find())
+			result.add(matcher.group(1));
+		return result;
+	}
+}

Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README
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/README?rev=1727453&r1=1727452&r2=1727453&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README
(original)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/dependencymanager/lambda/samples/future/README
Thu Jan 28 23:22:21 2016
@@ -1,54 +1,6 @@
 The purpose of this sample is to show an example usage of the new "CompletableFuture" dependency
that has been
 added in the dm-lambda library. CompletableFuture java8 class provides functional operations
and promotes an asynchronous event-driven model.
 
-when you go for asynchronous model, then in some situation you have to take care. For instance
assuming you want to 
-initialize a component from the init method using some asynchronous stuff, then the init
method may return before the async operations
-have completed; and the component.start() callback may then be called too early. And what
about if you want to add dependencies from the init() method 
-and you want to wait for the async operations before adding the dependency ? In this case
you would have to block on the CompletableFuture
-but this is something you don't want to do.
-
-So, to avoid blocking or some boilerplate code, a new (required) CompletableFuture dependency
has been added (in the dm-lambda library), 
-and you can use it to make sure that the component remains in the init state until a given
"CompletableFuture" completes.
-The new dependency is implemented as all other dependencies, and it extends the org.apache.felix.dm.context.AbstractDependency
class.
-
-Now, let's describe the sample: we have a "SiteInfoImpl" component that is using a CompletableFuture
from its init method
-in order to asynchronously download and parse an URL from the web. When the page content
is downloaded, then  the hrefs 
-(links) contained in the URL page are parsed. The component state remains in the init state
until the page is downloaded.
-
-Here is the activator:
-
-public class Activator extends DependencyActivatorBase {
-    @Override
-    public void init() throws Exception {    	
-    	// Define the SiteInfo component that provides some informations about the Felix web
site.
-        component(comp -> comp
-        	.provides(SiteInfo.class)
-        	.factory(() -> new SiteInfoImpl("http://felix.apache.org/"))
-            .withService(LogService.class, srv -> srv.onAdd(SiteInfoImpl::bind)));
-        
-        // Define a component that depends on the SiteInfo service
-        component(comp -> comp
-                .impl(DisplaySite.class)
-                .withService(LogService.class).withService(SiteInfo.class));
-    }
-}
-
-Nothing special so far.
-
-Now let's take a look at the SiteInfoImpl.init() method:
-
-	void init(Component c) {
-		// Asynchronously download and parse the links from the web page.
-		// We use a completable future that is then added as a dependency to our component, which
-		// will be started once the future has completed.
-		
-		CompletableFuture<List<String>> links = 
-				CompletableFuture.supplyAsync(() -> downloadSite(m_url))
-				.thenApply(this::getSiteLinks);
-								
-        component(c, builder -> builder.withFuture(links, b -> b.thenAccept(this::setLinks)));
-	}
-	
-So, the "builder.withFuture(links, b -> b.thenAccept(this::setLinks))" code simply defines
a "completable future" dependency that will be available once the 
-"links" future has completed, and the method reference passed to the b.thenAccept method
will be invoked exactly if you would have invoked
-the same method on the CompletableFuture "links" object.
+In this example, the Activator first asynchronously download the content of the Apache Felix
web site, using a CompletableFuture.
+And then a "PageLink" service is created, which will wait for the completion of the CompletableFuture
before being registered in the OSGi registry.
+Once the PageLink service is registered, it is then injected in the Activator, which then
displays the links (hrefs) found from the Felix web page.



Mime
View raw message