LoadFromConfluence.java

  1. package org.jbehave.core.io.rest.confluence;

  2. import java.util.Arrays;
  3. import java.util.HashSet;
  4. import java.util.Set;

  5. import org.jbehave.core.io.ResourceLoader;
  6. import org.jbehave.core.io.rest.RESTClient;
  7. import org.jbehave.core.io.rest.RESTClient.Type;
  8. import org.jbehave.core.io.rest.confluence.Confluence.Page;
  9. import org.jsoup.Jsoup;
  10. import org.jsoup.nodes.Document;
  11. import org.jsoup.nodes.Element;
  12. import org.jsoup.nodes.TextNode;
  13. import org.jsoup.select.Elements;

  14. public class LoadFromConfluence implements ResourceLoader {

  15.     private final Confluence confluence;
  16.     private final Set<String> acceptedMacros = new HashSet<>(Arrays.asList("panel", "info"));

  17.     public LoadFromConfluence() {
  18.         this(null, null);
  19.     }

  20.     public LoadFromConfluence(String username, String password) {
  21.         this(new RESTClient(Type.XML, username, password));
  22.     }

  23.     public LoadFromConfluence(RESTClient client) {
  24.         this.confluence = new Confluence(client);
  25.     }

  26.     @Override
  27.     public String loadResourceAsText(String resourcePath) {
  28.         Page page = confluence.loadPage(resourcePath, false);
  29.         Document doc = Jsoup.parse(page.getBody());
  30.         StringBuilder builder = new StringBuilder();
  31.         addTitle(doc, builder);
  32.         addPanels(doc, builder);
  33.         addExamples(doc, builder);
  34.         return builder.toString();
  35.     }

  36.     protected void addTitle(Document doc, StringBuilder builder) {
  37.         Element element = doc.getElementsByTag("h1").first();
  38.         builder.append(element.text()).append("\n\n");
  39.     }

  40.     protected void addPanels(Document doc, StringBuilder builder) {
  41.         Elements elements = doc.getElementsByTag("ac:structured-macro");
  42.         for (Element element : elements) {
  43.             String name = element.attr("ac:name");
  44.             if (acceptedMacros.contains(name)) {
  45.                 appendMacroTitle(builder, element);
  46.                 appendMacroBody(builder, element);
  47.             }
  48.         }
  49.     }

  50.     private void appendMacroTitle(StringBuilder builder, Element element) {
  51.         Elements parameters = element.getElementsByTag("ac:parameter");
  52.         if (parameters.size() > 0) {
  53.             for (Element parameter : parameters) {
  54.                 if ("title".equals(parameter.attr("ac:name"))) {
  55.                     String text = parameter.text();
  56.                     if (!text.contains(":")) {
  57.                         text = text + ":";
  58.                     }
  59.                     builder.append(text).append("\n");
  60.                 }
  61.             }
  62.         }
  63.     }

  64.     private void appendMacroBody(StringBuilder builder, Element element) {
  65.         Elements bodies = element.getElementsByTag("ac:rich-text-body");
  66.         if (!bodies.isEmpty()) {
  67.             Element body = bodies.first();
  68.             cleanNodes(body, "div");
  69.             cleanNodes(body, "p");
  70.             builder.append(body.text().replaceAll("<br/>", "\n")).append("\n");
  71.         }
  72.     }

  73.     protected void addExamples(Document doc, StringBuilder builder) {
  74.         Elements tables = doc.getElementsByTag("table");
  75.         if (!tables.isEmpty()) {
  76.             builder.append("Examples:\n");
  77.             Element table = tables.first();
  78.             Elements headers = table.select("tr").first().select("th");
  79.             for (Element header : headers) {
  80.                 builder.append("|").append(header.text());
  81.             }
  82.             builder.append("|\n");
  83.             Elements data = table.select("tr");
  84.             for (int i = 1; i < data.size(); i++) {
  85.                 for (Element cell : data.get(i).select("td")) {
  86.                     builder.append("|").append(cell.text());
  87.                 }
  88.                 builder.append("|\n");
  89.             }
  90.         }
  91.     }

  92.     protected void cleanNodes(Element body, String tag) {
  93.         for (Element element : body.getElementsByTag(tag)) {
  94.             if (element == null || element.parent() == null) {
  95.                 continue;
  96.             }
  97.             for (Element child : element.children().select(tag)) {
  98.                 cleanNodes(child, tag);
  99.             }
  100.             element.replaceWith(new TextNode(element.text() + "<br/>"));
  101.         }
  102.     }
  103. }