1 | |
package org.jbehave.core.io.rest.confluence; |
2 | |
|
3 | |
import java.util.Arrays; |
4 | |
import java.util.HashSet; |
5 | |
import java.util.Set; |
6 | |
|
7 | |
import org.jbehave.core.io.ResourceLoader; |
8 | |
import org.jbehave.core.io.rest.RESTClient; |
9 | |
import org.jbehave.core.io.rest.RESTClient.Type; |
10 | |
import org.jbehave.core.io.rest.confluence.Confluence.Page; |
11 | |
import org.jsoup.Jsoup; |
12 | |
import org.jsoup.nodes.Document; |
13 | |
import org.jsoup.nodes.Element; |
14 | |
import org.jsoup.nodes.TextNode; |
15 | |
import org.jsoup.select.Elements; |
16 | |
|
17 | |
public class LoadFromConfluence implements ResourceLoader { |
18 | |
|
19 | |
private final Confluence confluence; |
20 | 1 | private final Set<String> acceptedMacros = new HashSet<String>(Arrays.asList("panel", "info")); |
21 | |
|
22 | |
public LoadFromConfluence() { |
23 | 0 | this(null, null); |
24 | 0 | } |
25 | |
|
26 | |
public LoadFromConfluence(String username, String password) { |
27 | 0 | this(new RESTClient(Type.XML, username, password)); |
28 | 0 | } |
29 | |
|
30 | 1 | public LoadFromConfluence(RESTClient client) { |
31 | 1 | this.confluence = new Confluence(client); |
32 | 1 | } |
33 | |
|
34 | |
public String loadResourceAsText(String resourcePath) { |
35 | 1 | Page page = confluence.loadPage(resourcePath, false); |
36 | 1 | Document doc = Jsoup.parse(page.getBody()); |
37 | 1 | StringBuilder builder = new StringBuilder(); |
38 | 1 | addTitle(doc, builder); |
39 | 1 | addPanels(doc, builder); |
40 | 1 | addExamples(doc, builder); |
41 | 1 | return builder.toString(); |
42 | |
} |
43 | |
|
44 | |
protected void addTitle(Document doc, StringBuilder builder) { |
45 | 1 | Element element = doc.getElementsByTag("h1").first(); |
46 | 1 | builder.append(element.text()).append("\n\n"); |
47 | 1 | } |
48 | |
|
49 | |
protected void addPanels(Document doc, StringBuilder builder) { |
50 | 1 | Elements elements = doc.getElementsByTag("ac:structured-macro"); |
51 | 1 | for (Element element : elements) { |
52 | 5 | String name = element.attr("ac:name"); |
53 | 5 | if (acceptedMacros.contains(name)) { |
54 | 4 | appendMacroTitle(builder, element); |
55 | 4 | appendMacroBody(builder, element); |
56 | |
} |
57 | 5 | } |
58 | 1 | } |
59 | |
|
60 | |
private void appendMacroTitle(StringBuilder builder, Element element) { |
61 | 4 | Elements parameters = element.getElementsByTag("ac:parameter"); |
62 | 4 | if (parameters.size() > 0) { |
63 | 4 | for (Element parameter : parameters) { |
64 | 4 | if ("title".equals(parameter.attr("ac:name"))) { |
65 | 4 | String text = parameter.text(); |
66 | 4 | if (!text.contains(":")) { |
67 | 2 | text = text + ":"; |
68 | |
} |
69 | 4 | builder.append(text).append("\n"); |
70 | |
} |
71 | 4 | } |
72 | |
} |
73 | 4 | } |
74 | |
|
75 | |
private void appendMacroBody(StringBuilder builder, Element element) { |
76 | 4 | Elements bodies = element.getElementsByTag("ac:rich-text-body"); |
77 | 4 | if (!bodies.isEmpty()) { |
78 | 4 | Element body = bodies.first(); |
79 | 4 | cleanNodes(body, "div"); |
80 | 4 | cleanNodes(body, "p"); |
81 | 4 | builder.append(body.text().replaceAll("<br/>", "\n")).append("\n"); |
82 | |
} |
83 | 4 | } |
84 | |
|
85 | |
protected void addExamples(Document doc, StringBuilder builder) { |
86 | 1 | Elements tables = doc.getElementsByTag("table"); |
87 | 1 | if (!tables.isEmpty()) { |
88 | 1 | builder.append("Examples:\n"); |
89 | 1 | Element table = tables.first(); |
90 | 1 | Elements headers = table.select("tr").first().select("th"); |
91 | 1 | for (Element header : headers) { |
92 | 2 | builder.append("|").append(header.text()); |
93 | 2 | } |
94 | 1 | builder.append("|\n"); |
95 | 1 | Elements data = table.select("tr"); |
96 | 3 | for (int i = 1; i < data.size(); i++) { |
97 | 2 | for (Element cell : data.get(i).select("td")) { |
98 | 4 | builder.append("|").append(cell.text()); |
99 | 4 | } |
100 | 2 | builder.append("|\n"); |
101 | |
} |
102 | |
} |
103 | 1 | } |
104 | |
|
105 | |
protected void cleanNodes(Element body, String tag) { |
106 | 11 | for (Element element : body.getElementsByTag(tag)) { |
107 | 17 | if (element == null || element.parent() == null) { |
108 | 3 | continue; |
109 | |
} |
110 | 14 | for (Element child : element.children().select(tag)) { |
111 | 3 | cleanNodes(child, tag); |
112 | 3 | } |
113 | 14 | element.replaceWith(new TextNode(element.text() + "<br/>", "")); |
114 | 14 | } |
115 | 11 | } |
116 | |
} |