Adding a Confluence to DocBook converter to the plugin
git-svn-id: https://svn.apache.org/repos/asf/servicemix/sandbox/gertv/documentation/trunk@938975 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/docs/jbi/src/confluence/servicemix-camel.wiki b/docs/jbi/src/confluence/servicemix-camel.wiki
new file mode 100644
index 0000000..5c43c5b
--- /dev/null
+++ b/docs/jbi/src/confluence/servicemix-camel.wiki
@@ -0,0 +1,45 @@
+h1. servicemix-camel
+
+h2. Overview
+The servicemix-camel component provides support for using Apache Camel to provide a full set of Enterprise Integration Patterns and flexible routing and transformation in both Java code or Spring XML to route services on the Normalized Message Router.
+
+h3. Namespace and camel-context.xml
+When creating a servicemix-camel service unit, we reuse the default Camel namespace {{http://camel.apache.org/schema/spring}}.
+
+This is an example {{camel-context.xml}} which uses the Spring DSL to define the Camel routes
+{code}
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ http://camel.apache.org/schema/spring
+ http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+ <route>
+ <!-- route defined in the Spring DSL -->
+ </route>
+ </camelContext>
+
+</beans>
+{code}
+
+It is also possible to use the Java DSL inside a servicemix-camel service unit by referring to the package that contains the {{RouteBuilder}} classes. An example: this {{camel-context.xml}} file will activate all routes defined by {{RouteBuilder}}s in the {{org.apache.servicemix.example.camel}} package.
+{code}
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ http://camel.apache.org/schema/spring
+ http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+ <packages>org.apache.servicemix.examples.camel</packages>
+ </camelContext>
+
+</beans>
+{code}
\ No newline at end of file
diff --git a/docs/jbi/src/docbkx/index.xml b/docs/jbi/src/docbkx/index.xml
index 5f1ae2c..6a566bd 100644
--- a/docs/jbi/src/docbkx/index.xml
+++ b/docs/jbi/src/docbkx/index.xml
@@ -50,6 +50,7 @@
<part>
<title>ServiceMix JBI Components</title>
<xi:include href="servicemix-bean.xml" parse="xml"/>
+ <xi:include href="servicemix-camel.wiki.xml" parse="xml"/>
<xi:include href="servicemix-saxon.xml" parse="xml"/>
diff --git a/docs/pom.xml b/docs/pom.xml
index 317b918..3d309d0 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -158,14 +158,21 @@
<groupId>org.apache.servicemix.docs</groupId>
<artifactId>tools</artifactId>
<version>${pom.version}</version>
- <inherited>false</inherited> <!-- URL handlers only have to be registered once -->
<executions>
<execution>
- <phase>initialize</phase>
+ <id>configure-snippet-handler</id>
+ <inherited>false</inherited> <!-- URL handlers only have to be registered once -->
<goals>
<goal>snippet</goal>
</goals>
</execution>
+ <execution>
+ <id>confluence-to-docbook</id>
+ <inherited>true</inherited>
+ <goals>
+ <goal>confluence-to-docbook</goal>
+ </goals>
+ </execution>
</executions>
<configuration>
<snippetBase>http://svn.apache.org/repos/asf/servicemix/</snippetBase>
diff --git a/tools/pom.xml b/tools/pom.xml
index f94f4db..8d34688 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -24,6 +24,11 @@
<version>2.0.9</version>
</dependency>
<dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
diff --git a/tools/src/main/java/org/apache/servicemix/docs/ConfluenceToDocbookMojo.java b/tools/src/main/java/org/apache/servicemix/docs/ConfluenceToDocbookMojo.java
new file mode 100644
index 0000000..1209556
--- /dev/null
+++ b/tools/src/main/java/org/apache/servicemix/docs/ConfluenceToDocbookMojo.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.docs;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.servicemix.docs.confluence.ConfluenceConverter;
+import org.apache.servicemix.docs.snippet.SnippetHandler;
+
+/**
+ * Convert pages in Confluence wiki markup to Docbook syntax
+ *
+ * @goal confluence-to-docbook
+ * @phase generate-resources
+ */
+public class ConfluenceToDocbookMojo extends AbstractMojo {
+
+ /**
+ * Location of the snippet cache
+ * @parameter default-value="${basedir}/src/confluence"
+ */
+ protected File input;
+
+ /**
+ * Output directory for the Docbook sources
+ * @parameter default-value="${project.build.directory}/docbkx/sources"
+ */
+ protected File output;
+
+ public void execute() throws MojoExecutionException {
+ if (!output.exists()) {
+ output.mkdirs();
+ }
+ if (input.exists() && input.isDirectory()) {
+ for (File file : input.listFiles()) {
+ getLog().info("Creating DocBook from " + file.getAbsolutePath());
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(new File(output, file.getName() + ".xml"));
+
+ ConfluenceConverter converter =
+ new ConfluenceConverter(new FileReader(file), writer);
+
+ converter.convert();
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to convert " + file, e);
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ // ignore this
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/src/main/java/org/apache/servicemix/docs/SnippetMojo.java b/tools/src/main/java/org/apache/servicemix/docs/SnippetMojo.java
index ff82f8e..841ae7c 100644
--- a/tools/src/main/java/org/apache/servicemix/docs/SnippetMojo.java
+++ b/tools/src/main/java/org/apache/servicemix/docs/SnippetMojo.java
@@ -30,6 +30,7 @@
*
* @goal snippet
* @phase initialize
+ * @inheritByDefault false
*/
public class SnippetMojo extends AbstractMojo {
diff --git a/tools/src/main/java/org/apache/servicemix/docs/confluence/ConfluenceConverter.java b/tools/src/main/java/org/apache/servicemix/docs/confluence/ConfluenceConverter.java
new file mode 100644
index 0000000..b5f0548
--- /dev/null
+++ b/tools/src/main/java/org/apache/servicemix/docs/confluence/ConfluenceConverter.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.docs.confluence;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a document in Confluence wiki markup
+ */
+public class ConfluenceConverter {
+
+ private static Pattern CHAPTER = Pattern.compile("^h1\\. .*");
+ private static Pattern CHAPTER_OR_SECTION = Pattern.compile("^h[1-6]\\. .*");
+
+ private BufferedReader reader;
+ private PrintWriter writer;
+
+ private int currentLevel = 0;
+
+ private Stack<String> elements = new Stack<String>();
+
+ public ConfluenceConverter(Reader reader, Writer writer) {
+ if (reader instanceof BufferedReader) {
+ this.reader = (BufferedReader) reader;
+ } else {
+ this.reader = new BufferedReader(reader);
+ }
+ if (writer instanceof PrintWriter) {
+ this.writer = (PrintWriter) writer;
+ } else {
+ this.writer = new PrintWriter(writer);
+ }
+ }
+
+ public void convert() throws IOException {
+ String line = null;
+
+ while ((line = reader.readLine()) != null) {
+ if (CHAPTER_OR_SECTION.matcher(line).matches()) {
+ writeChapterOrSection(line);
+ } else if ("{code}".equals(line.trim())) {
+ writeProgramListing();
+ } else {
+ writePara(line);
+ }
+ }
+
+ // let's close everying that was opened
+ closeElements();
+
+ }
+
+ private void writeProgramListing() throws IOException {
+ writeText("<programlisting><![CDATA[");
+
+ String line = null;
+ while ((line = reader.readLine()) != null && !line.equals("{code}")) {
+ writeText(line, "");
+ }
+
+ writeText("]]></programlisting>");
+ }
+
+ private void writePara(String line) {
+ if (line.trim().length() == 0) {
+ if (elements.contains("para")) {
+ closeElement("para");
+ }
+ } else {
+ if (!elements.peek().equals("para")) {
+ openElement("para");
+ }
+ writeText(filter(line));
+ }
+ }
+
+ private String filter(String line) {
+ return line.replaceAll("[\\{]{2}", "<code>").replaceAll("[\\}]{2}", "</code>");
+ }
+
+ private void writeText(String text) {
+ writeText(text, indent());
+ }
+
+ private void writeText(String text, String indent) {
+ writer.printf("%s%s%n", indent, text);
+ }
+
+ private void writeChapterOrSection(String line) {
+ int level = Integer.parseInt(line.substring(1, 2));
+ while (currentLevel >= level) {
+ closeElement("section");
+ currentLevel--;
+ }
+ if (CHAPTER.matcher(line).matches()) {
+ openElement("chapter");
+ } else {
+ openElement("section");
+ }
+ writeElement("title", line.substring(3).trim());
+ currentLevel = level;
+ }
+
+ private void writeElement(String element, String value) {
+ writer.printf("%s<%s>%s</%s>%n", indent(), element, value, element);
+ }
+
+ private void openElement(String element) {
+ writer.printf("%s<%s>%n", indent(), element);
+ elements.push(element);
+ }
+
+ private void closeElements() {
+ while (!elements.isEmpty()) {
+ closeElement(elements.peek());
+ }
+ }
+
+ private void closeElement(String element) {
+ String next = elements.pop();
+ writer.printf("%s</%s>%n", indent(), next);
+ if (!element.equals(next)) {
+ // recursive call to close everything down to the required element
+ closeElement(element);
+ }
+ }
+
+ private String indent() {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0 ; i < elements.size(); i++) {
+ buffer.append(" ");
+ }
+ return buffer.toString();
+ }
+}
diff --git a/tools/src/main/java/org/apache/servicemix/docs/snippet/SnippetHandler.java b/tools/src/main/java/org/apache/servicemix/docs/snippet/SnippetHandler.java
index 627d1e4..f589034 100644
--- a/tools/src/main/java/org/apache/servicemix/docs/snippet/SnippetHandler.java
+++ b/tools/src/main/java/org/apache/servicemix/docs/snippet/SnippetHandler.java
@@ -83,7 +83,11 @@
copy(in, out, id);
}
} catch (IOException e) {
- mojo.getLog().warn("Unable to include snippet " + url.toExternalForm(), e);
+ out.println("missing snippet: " + url);
+
+ // summary warning message and full detail debug logging
+ mojo.getLog().warn("Unable to include snippet " + url.toExternalForm());
+ mojo.getLog().debug("Unable to include snippet " + url.toExternalForm(), e);
}
out.println("]]></programlisting>");
@@ -141,8 +145,9 @@
copy(in, out);
out.flush();
} catch (IOException e) {
- mojo.getLog().warn("Unable to cache data for " + name, e);
- throw e;
+ // summary warning message and full detail debug message
+ mojo.getLog().warn("Unable to cache data for " + name + " : " + e.getMessage());
+ mojo.getLog().debug("Unable to cache data for " + name + " : " + e.getMessage(), e);
} finally {
if (in != null) {
in.close();
diff --git a/tools/src/test/java/org/apache/servicemix/docs/SnippetMojoTest.java b/tools/src/test/java/org/apache/servicemix/docs/SnippetMojoTest.java
index 9248913..dd00f95 100644
--- a/tools/src/test/java/org/apache/servicemix/docs/SnippetMojoTest.java
+++ b/tools/src/test/java/org/apache/servicemix/docs/SnippetMojoTest.java
@@ -24,6 +24,7 @@
import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
@@ -34,10 +35,10 @@
*/
public class SnippetMojoTest {
- private SnippetMojo mojo;
+ private static SnippetMojo mojo;
- @Before
- public void setUp() throws MojoExecutionException, MalformedURLException {
+ @BeforeClass
+ public static void setUp() throws MojoExecutionException, MalformedURLException {
mojo = new SnippetMojo();
mojo.snippetCache = new File("target/tests/snippets-" + System.currentTimeMillis());
mojo.snippetBase = new File("src/test/resources").toURI().toURL();
diff --git a/tools/src/test/java/org/apache/servicemix/docs/confluence/ConfluenceDocumentTest.java b/tools/src/test/java/org/apache/servicemix/docs/confluence/ConfluenceDocumentTest.java
new file mode 100644
index 0000000..6b39d55
--- /dev/null
+++ b/tools/src/test/java/org/apache/servicemix/docs/confluence/ConfluenceDocumentTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.docs.confluence;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * Test cases for {@link ConfluenceConverter}
+ */
+public class ConfluenceDocumentTest {
+
+ @org.junit.Test
+ public void generateChapterAndSections() throws Exception {
+ assertDocBook("document1");
+ }
+
+ @org.junit.Test
+ public void generateChapterSectionsAndParagraphs() throws Exception {
+ assertDocBook("document2");
+ }
+
+ @org.junit.Test
+ public void generateProgramListingBlock() throws Exception {
+ assertDocBook("code-blocks");
+ }
+
+ private void assertDocBook(String name) throws IOException {
+ StringWriter writer = new StringWriter();
+
+ List<String> expected = IOUtils.readLines(getClass().getResourceAsStream(name + ".xml"));
+
+ ConfluenceConverter document =
+ new ConfluenceConverter(new InputStreamReader(getClass().getResourceAsStream(name + ".wiki")),
+ writer);
+
+ document.convert();
+ writer.flush();
+ writer.close();
+
+ String[] results = writer.toString().split("\\r?\\n\\r?");
+ int i = 0;
+
+ for (String result : results) {
+ System.out.println(result);
+ if (result.trim().length() > 0) {
+
+ assertEquals("Line " + (i +1) + " should match the expected DocBook XML output",
+ expected.get(i).trim(), result.trim());
+ i++;
+ }
+ }
+ }
+}
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.wiki b/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.wiki
new file mode 100644
index 0000000..37830ed
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.wiki
@@ -0,0 +1,11 @@
+h1. Chapter
+
+h2. Section 1
+This section contains a piece of {{code text}}.
+
+{code}
+<?xml version="1.0"?>
+<hello>
+ <world/>
+</hello>
+{code}
\ No newline at end of file
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.xml b/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.xml
new file mode 100644
index 0000000..8684e42
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/code-blocks.xml
@@ -0,0 +1,15 @@
+<chapter>
+ <title>Chapter</title>
+ <section>
+ <title>Section 1</title>
+ <para>
+ This section contains a piece of <code>code text</code>.
+ </para>
+ <programlisting><![CDATA[
+ <?xml version="1.0"?>
+ <hello>
+ <world/>
+ </hello>
+ ]]></programlisting>
+ </section>
+</chapter>
\ No newline at end of file
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.wiki b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.wiki
new file mode 100644
index 0000000..c7245a9
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.wiki
@@ -0,0 +1,7 @@
+h1. Chapter
+
+h2. Section 1
+
+h3. Section 1.1
+
+h2. Section 2
\ No newline at end of file
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.xml b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.xml
new file mode 100644
index 0000000..670d844
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document1.xml
@@ -0,0 +1,12 @@
+<chapter>
+ <title>Chapter</title>
+ <section>
+ <title>Section 1</title>
+ <section>
+ <title>Section 1.1</title>
+ </section>
+ </section>
+ <section>
+ <title>Section 2</title>
+ </section>
+</chapter>
\ No newline at end of file
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.wiki b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.wiki
new file mode 100644
index 0000000..976cf38
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.wiki
@@ -0,0 +1,9 @@
+h1. Chapter
+
+h2. Section 1
+Paragraph 1 starts here...
+
+Paragraph 2 starts here...
+
+h3. Section 1.1
+And one more paragraph
\ No newline at end of file
diff --git a/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.xml b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.xml
new file mode 100644
index 0000000..8de779c
--- /dev/null
+++ b/tools/src/test/resources/org/apache/servicemix/docs/confluence/document2.xml
@@ -0,0 +1,18 @@
+<chapter>
+ <title>Chapter</title>
+ <section>
+ <title>Section 1</title>
+ <para>
+ Paragraph 1 starts here...
+ </para>
+ <para>
+ Paragraph 2 starts here...
+ </para>
+ <section>
+ <title>Section 1.1</title>
+ <para>
+ And one more paragraph
+ </para>
+ </section>
+ </section>
+</chapter>
\ No newline at end of file