blob: b78e4693ec46950cd5bd7916135bce6d2d15be51 [file] [log] [blame]
Pierre De Ropfaca2892016-01-31 23:27:05 +00001package org.apache.felix.dm.lambda.samples.future;
2
3import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
4
5import java.io.IOException;
6import java.net.URL;
7import java.util.ArrayList;
8import java.util.List;
9import java.util.Scanner;
10import java.util.concurrent.CompletableFuture;
11import java.util.regex.Matcher;
12import java.util.regex.Pattern;
13
14import org.apache.felix.dm.Component;
15import org.osgi.service.log.LogService;
16
17/**
18 * Provides all hrefs found from a given web page.
19 */
20public class PageLinksImpl implements PageLinks {
21 private LogService m_log;
22 private final static String HREF_PATTERN = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
23 private List<String> m_links; // web page hrefs (links).
24 private String m_url;
25
26 PageLinksImpl(String url) {
27 m_url = url;
28 }
29
30 void bind(LogService log) {
31 m_log = log;
32 }
33
34 void init(Component c) {
35 // asynchronously download the content of the URL specified in the constructor.
36 CompletableFuture<List<String>> futureLinks = CompletableFuture.supplyAsync(() -> download(m_url))
37 .thenApply(this::parseLinks);
38
39 // Add the future dependency so we'll be started once the CompletableFuture "futureLinks" has completed.
Pierre De Rop11527502016-02-18 21:07:16 +000040 component(c, comp -> comp.withFuture(futureLinks, future -> future.complete(this::setLinks)));
Pierre De Ropfaca2892016-01-31 23:27:05 +000041 }
42
43 // Called when our future has completed.
44 void setLinks(List<String> links) {
45 m_links = links;
46 }
47
48 // once our future has completed, our component is started.
49 void start() {
Pierre De Rop11527502016-02-18 21:07:16 +000050 m_log.log(LogService.LOG_WARNING, "Service starting: number of links found from Felix web site: " + m_links.size());
Pierre De Ropfaca2892016-01-31 23:27:05 +000051 }
52
53 @Override
54 public List<String> getLinks() {
55 return m_links;
56 }
57
58 private String download(String url) {
59 try (Scanner in = new Scanner(new URL(url).openStream())) {
60 StringBuilder builder = new StringBuilder();
61 while (in.hasNextLine()) {
62 builder.append(in.nextLine());
63 builder.append("\n");
64 }
65 return builder.toString();
66 } catch (IOException ex) {
67 RuntimeException rex = new RuntimeException();
68 rex.initCause(ex);
69 throw rex;
70 }
71 }
72
73 private List<String> parseLinks(String content) {
74 Pattern pattern = Pattern.compile(HREF_PATTERN, Pattern.CASE_INSENSITIVE);
75 Matcher matcher = pattern.matcher(content);
76 List<String> result = new ArrayList<>();
77 while (matcher.find())
78 result.add(matcher.group(1));
79 return result;
80 }
81}