LoadFromConfluence.java
package org.jbehave.core.io.rest.confluence;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.jbehave.core.io.ResourceLoader;
import org.jbehave.core.io.rest.RESTClient;
import org.jbehave.core.io.rest.RESTClient.Type;
import org.jbehave.core.io.rest.confluence.Confluence.Page;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
public class LoadFromConfluence implements ResourceLoader {
private final Confluence confluence;
private final Set<String> acceptedMacros = new HashSet<>(Arrays.asList("panel", "info"));
public LoadFromConfluence() {
this(null, null);
}
public LoadFromConfluence(String username, String password) {
this(new RESTClient(Type.XML, username, password));
}
public LoadFromConfluence(RESTClient client) {
this.confluence = new Confluence(client);
}
@Override
public String loadResourceAsText(String resourcePath) {
Page page = confluence.loadPage(resourcePath, false);
Document doc = Jsoup.parse(page.getBody());
StringBuilder builder = new StringBuilder();
addTitle(doc, builder);
addPanels(doc, builder);
addExamples(doc, builder);
return builder.toString();
}
protected void addTitle(Document doc, StringBuilder builder) {
Element element = doc.getElementsByTag("h1").first();
builder.append(element.text()).append("\n\n");
}
protected void addPanels(Document doc, StringBuilder builder) {
Elements elements = doc.getElementsByTag("ac:structured-macro");
for (Element element : elements) {
String name = element.attr("ac:name");
if (acceptedMacros.contains(name)) {
appendMacroTitle(builder, element);
appendMacroBody(builder, element);
}
}
}
private void appendMacroTitle(StringBuilder builder, Element element) {
Elements parameters = element.getElementsByTag("ac:parameter");
if (parameters.size() > 0) {
for (Element parameter : parameters) {
if ("title".equals(parameter.attr("ac:name"))) {
String text = parameter.text();
if (!text.contains(":")) {
text = text + ":";
}
builder.append(text).append("\n");
}
}
}
}
private void appendMacroBody(StringBuilder builder, Element element) {
Elements bodies = element.getElementsByTag("ac:rich-text-body");
if (!bodies.isEmpty()) {
Element body = bodies.first();
cleanNodes(body, "div");
cleanNodes(body, "p");
builder.append(body.text().replaceAll("<br/>", "\n")).append("\n");
}
}
protected void addExamples(Document doc, StringBuilder builder) {
Elements tables = doc.getElementsByTag("table");
if (!tables.isEmpty()) {
builder.append("Examples:\n");
Element table = tables.first();
Elements headers = table.select("tr").first().select("th");
for (Element header : headers) {
builder.append("|").append(header.text());
}
builder.append("|\n");
Elements data = table.select("tr");
for (int i = 1; i < data.size(); i++) {
for (Element cell : data.get(i).select("td")) {
builder.append("|").append(cell.text());
}
builder.append("|\n");
}
}
}
protected void cleanNodes(Element body, String tag) {
for (Element element : body.getElementsByTag(tag)) {
if (element == null || element.parent() == null) {
continue;
}
for (Element child : element.children().select(tag)) {
cleanNodes(child, tag);
}
element.replaceWith(new TextNode(element.text() + "<br/>"));
}
}
}