Camel apt improved html doc generation. And working on generating json schema 
as well.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/34230db8
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/34230db8
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/34230db8

Branch: refs/heads/master
Commit: 34230db8d5a4518eff8eeaf575333f6696339e74
Parents: 59322fd
Author: Claus Ibsen <davscl...@apache.org>
Authored: Thu Nov 6 08:44:32 2014 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Nov 7 13:25:17 2014 +0100

----------------------------------------------------------------------
 .../apache/camel/util/StringQuoteHelper.java    |   1 -
 .../tools/apt/EndpointAnnotationProcessor.java  | 113 ++++++++++------
 .../tools/apt/util/CollectionStringBuffer.java  |  59 +++++++++
 .../camel/tools/apt/util/JsonSchemaHelper.java  | 128 +++++++++++++++++++
 .../apache/camel/tools/apt/util/Strings.java    |  29 +++++
 5 files changed, 288 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/34230db8/camel-core/src/main/java/org/apache/camel/util/StringQuoteHelper.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/util/StringQuoteHelper.java 
b/camel-core/src/main/java/org/apache/camel/util/StringQuoteHelper.java
index 4a02dd1..8837c3a 100644
--- a/camel-core/src/main/java/org/apache/camel/util/StringQuoteHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/StringQuoteHelper.java
@@ -53,7 +53,6 @@ public final class StringQuoteHelper {
         return quote + text + quote;
     }
 
-
     /**
      * Splits the input safely honoring if values is enclosed in quotes.
      * <p/>

http://git-wip-us.apache.org/repos/asf/camel/blob/34230db8/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
----------------------------------------------------------------------
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
index 501527b..467070f 100644
--- 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
@@ -23,13 +23,9 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.net.URI;
-import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
 import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.Filer;
 import javax.annotation.processing.RoundEnvironment;
@@ -57,7 +53,7 @@ import org.apache.camel.tools.apt.util.Strings;
 import static org.apache.camel.tools.apt.util.Strings.canonicalClassName;
 
 /**
- * Processes all Camel endpoints
+ * Processes all Camel {@link UriEndpoint}s and generate json schema and html 
documentation for the endpoint/component.
  */
 @SupportedAnnotationTypes({"org.apache.camel.spi.*"})
 @SupportedSourceVersion(SourceVersion.RELEASE_7)
@@ -87,6 +83,7 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
                     @Override
                     public Void call(PrintWriter writer) {
                         writeHtmlDocumentation(writer, roundEnv, classElement, 
uriEndpoint);
+                        writeJSonSchemeDocumentation(writer, roundEnv, 
classElement, uriEndpoint);
                         return null;
                     }
                 };
@@ -95,6 +92,10 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
         }
     }
 
+    protected void writeJSonSchemeDocumentation(PrintWriter writer, 
RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint) {
+        // todo
+    }
+
     protected void writeHtmlDocumentation(PrintWriter writer, RoundEnvironment 
roundEnv, TypeElement classElement, UriEndpoint uriEndpoint) {
         writer.println("<html>");
         writer.println("<header>");
@@ -138,36 +139,33 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
     protected void showDocumentationAndFieldInjections(PrintWriter writer, 
RoundEnvironment roundEnv, TypeElement classElement, String prefix) {
         String classDoc = 
processingEnv.getElementUtils().getDocComment(classElement);
         if (!Strings.isNullOrEmpty(classDoc)) {
-            writer.println("<p>" + classDoc.trim() + "</p>");
+            // remove dodgy @version that we may have in class javadoc
+            classDoc = classDoc.replaceFirst("\\@version", "");
+            classDoc = classDoc.trim();
+            writer.println("<p>" + classDoc + "</p>");
         }
 
-        SortedMap<String, List<String>> sortedMap = new TreeMap<String, 
List<String>>();
-        findClassProperties(roundEnv, sortedMap, classElement, prefix);
-        if (!sortedMap.isEmpty()) {
+        Set<EndpointOption> endpointOptions = new LinkedHashSet<>();
+        findClassProperties(roundEnv, endpointOptions, classElement, prefix);
+        if (!endpointOptions.isEmpty()) {
             writer.println("<table class='table'>");
             writer.println("  <tr>");
             writer.println("    <th>Name</th>");
             writer.println("    <th>Type</th>");
             writer.println("    <th>Description</th>");
-            // see defaultValue above
-            // writer.println("    <th>Default Value</th>");
             writer.println("  </tr>");
-            Set<Map.Entry<String, List<String>>> entries = 
sortedMap.entrySet();
-            for (Map.Entry<String, List<String>> entry : entries) {
-                String name = entry.getKey();
-                List<String> values = entry.getValue();
+            for (EndpointOption option : endpointOptions) {
                 writer.println("  <tr>");
-                writer.println("    <td>" + name + "</td>");
-                for (String value : values) {
-                    writer.println(value);
-                }
+                writer.println("    <td>" + option.getName() + "</td>");
+                writer.println("    <td>" + option.getType() + "</td>");
+                writer.println("    <td>" + option.getDocumentation() + 
"</td>");
                 writer.println("  </tr>");
             }
             writer.println("</table>");
         }
     }
 
-    protected void findClassProperties(RoundEnvironment roundEnv, 
SortedMap<String, List<String>> sortedMap, TypeElement classElement, String 
prefix) {
+    protected void findClassProperties(RoundEnvironment roundEnv, 
Set<EndpointOption> endpointOptions, TypeElement classElement, String prefix) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
             List<VariableElement> fieldElements = 
ElementFilter.fieldsIn(classElement.getEnclosedElements());
@@ -197,7 +195,7 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
                         if (!Strings.isNullOrEmpty(extraPrefix)) {
                             nestedPrefix += extraPrefix;
                         }
-                        findClassProperties(roundEnv, sortedMap, 
fieldTypeElement, nestedPrefix);
+                        findClassProperties(roundEnv, endpointOptions, 
fieldTypeElement, nestedPrefix);
                     } else {
                         String docComment = 
elementUtils.getDocComment(fieldElement);
                         if (Strings.isNullOrEmpty(docComment)) {
@@ -221,21 +219,9 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
                         if (docComment == null) {
                             docComment = "";
                         }
-                        List<String> values = new ArrayList<String>();
-                        values.add("    <td>" + fieldTypeName + "</td>");
-                        values.add("    <td>" + docComment.trim() + "</td>");
-
-                        // TODO would be nice here to create a default 
endpoint/consumer object
-                        // and return the default value of the field so we can 
put it into the docs
-                        Object defaultValue = null;
-                        if (defaultValue != null) {
-                            values.add("    <td>" + defaultValue + "</td>");
-                        }
-                        if (sortedMap.containsKey(name)) {
-                            error("Duplicate parameter annotation named '" + 
name + "' on class " + classElement.getQualifiedName());
-                        } else {
-                            sortedMap.put(name, values);
-                        }
+
+                        EndpointOption option = new EndpointOption(name, 
fieldTypeName, docComment.trim());
+                        endpointOptions.add(option);
                     }
                 }
             }
@@ -253,7 +239,6 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
         }
     }
 
-
     protected TypeElement findTypeElement(RoundEnvironment roundEnv, String 
className) {
         if (!Strings.isNullOrEmpty(className) && 
!"java.lang.Object".equals(className)) {
             Set<? extends Element> rootElements = roundEnv.getRootElements();
@@ -270,20 +255,19 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
         return null;
     }
 
-
     /**
      * Helper method to produce class output text file using the given handler
      */
     protected void processFile(String packageName, String scheme, String 
fileName, Func1<PrintWriter, Void> handler) {
         PrintWriter writer = null;
         try {
-            Writer out = null;
+            Writer out;
             Filer filer = processingEnv.getFiler();
             FileObject resource;
             try {
                 resource = filer.getResource(StandardLocation.CLASS_OUTPUT, 
packageName, fileName);
             } catch (Throwable e) {
-                resource = filer.createResource(StandardLocation.CLASS_OUTPUT, 
packageName, fileName, new Element[0]);
+                resource = filer.createResource(StandardLocation.CLASS_OUTPUT, 
packageName, fileName);
             }
             URI uri = resource.toUri();
             File file = null;
@@ -330,6 +314,53 @@ public class EndpointAnnotationProcessor extends 
AbstractProcessor {
         e.printStackTrace(writer);
         writer.close();
         processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
buffer.toString());
+    }
+
+    private static final class EndpointOption {
+
+        private String name;
+        private String type;
+        private String documentation;
+
+        private EndpointOption(String name, String type, String documentation) 
{
+            this.name = name;
+            this.type = type;
+            this.documentation = documentation;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public String getDocumentation() {
+            return documentation;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
 
+            EndpointOption that = (EndpointOption) o;
+
+            if (!name.equals(that.name)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/34230db8/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/CollectionStringBuffer.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/CollectionStringBuffer.java
new file mode 100644
index 0000000..01fbddd
--- /dev/null
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/CollectionStringBuffer.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.camel.tools.apt.util;
+
+/**
+ /**
+ * A little helper class for converting a collection of values to a (usually 
comma separated) string.
+ */
+public class CollectionStringBuffer {
+
+    private final StringBuilder buffer = new StringBuilder();
+    private String separator;
+    private boolean first = true;
+
+    public CollectionStringBuffer() {
+        this(", ");
+    }
+
+    public CollectionStringBuffer(String separator) {
+        this.separator = separator;
+    }
+
+    @Override
+    public String toString() {
+        return buffer.toString();
+    }
+
+    public void append(Object value) {
+        if (first) {
+            first = false;
+        } else {
+            buffer.append(separator);
+        }
+        buffer.append(value);
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
+
+    public void setSeparator(String separator) {
+        this.separator = separator;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/34230db8/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/JsonSchemaHelper.java
----------------------------------------------------------------------
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/JsonSchemaHelper.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/JsonSchemaHelper.java
new file mode 100644
index 0000000..6a4f4c4
--- /dev/null
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/JsonSchemaHelper.java
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.camel.tools.apt.util;
+
+import static org.apache.camel.tools.apt.util.Strings.doubleQuote;
+
+/**
+ * A helper class for <a href="http://json-schema.org/";>JSON schema</a>.
+ */
+public final class JsonSchemaHelper {
+
+    private JsonSchemaHelper() {
+    }
+
+    public static String toJson(String name, String type, String description) {
+//        if (type.isEnum()) {
+//            String typeName = "string";
+//            CollectionStringBuffer sb = new CollectionStringBuffer();
+//            for (Object value : parameterType.getEnumConstants()) {
+//                sb.append(doubleQuote(value.toString()));
+//            }
+//            return doubleQuote(name) + ": { \"type\": " + doubleQuote(type) 
+ ", \"enum\": [ " + sb.toString() + " ] }";
+//        } else if (parameterType.isArray()) {
+//            String typeName = "array";
+//            return doubleQuote(name) + ": { \"type\": " + doubleQuote(type) 
+ " }";
+//        } else {
+        String typeName = JsonSchemaHelper.getType(type);
+        if ("object".equals(typeName)) {
+            // for object then include the javaType as a description so we 
know that
+            return doubleQuote(name) + ": { \"type\": " + doubleQuote(typeName)
+                    + ", \"properties\": { \"javaType\": { \"description\": 
\"" + type + "\", \"type\": \"string\" } } }";
+        } else {
+            return doubleQuote(name) + ": { \"type\": " + 
doubleQuote(typeName) + " }";
+        }
+//        }
+
+    }
+
+    /**
+     * Gets the JSon schema type.
+     *
+     * @param   type the java type
+     * @return  the json schema type, is never null, but returns 
<tt>object</tt> as the generic type
+     */
+    public static String getType(String type) {
+        // TODO:
+//        if (type.isEnum()) {
+//            return "enum";
+//        } else if (type.isArray()) {
+//            return "array";
+//        }
+
+        String primitive = getPrimitiveType(type);
+        if (primitive != null) {
+            return primitive;
+        }
+
+        return "object";
+    }
+
+    /**
+     * Gets the JSon schema primitive type.
+     *
+     * @param   name the java type
+     * @return  the json schema primitive type, or <tt>null</tt> if not a 
primitive
+     */
+    public static String getPrimitiveType(String name) {
+
+        // special for byte[] or Object[] as its common to use
+        if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
+            return "string";
+        } else if ("java.lang.Byte[]".equals(name) || "Byte[]".equals(name)) {
+            return "array";
+        } else if ("java.lang.Object[]".equals(name) || 
"Object[]".equals(name)) {
+            return "array";
+        } else if ("java.lang.String[]".equals(name) || 
"String[]".equals(name)) {
+            return "array";
+            // and these is common as well
+        } else if ("java.lang.String".equals(name) || "String".equals(name)) {
+            return "string";
+        } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name)) 
{
+            return "boolean";
+        } else if ("boolean".equals(name)) {
+            return "boolean";
+        } else if ("java.lang.Integer".equals(name) || "Integer".equals(name)) 
{
+            return "integer";
+        } else if ("int".equals(name)) {
+            return "integer";
+        } else if ("java.lang.Long".equals(name) || "Long".equals(name)) {
+            return "integer";
+        } else if ("long".equals(name)) {
+            return "integer";
+        } else if ("java.lang.Short".equals(name) || "Short".equals(name)) {
+            return "integer";
+        } else if ("short".equals(name)) {
+            return "integer";
+        } else if ("java.lang.Byte".equals(name) || "Byte".equals(name)) {
+            return "integer";
+        } else if ("byte".equals(name)) {
+            return "integer";
+        } else if ("java.lang.Float".equals(name) || "Float".equals(name)) {
+            return "number";
+        } else if ("float".equals(name)) {
+            return "number";
+        } else if ("java.lang.Double".equals(name) || "Double".equals(name)) {
+            return "number";
+        } else if ("double".equals(name)) {
+            return "number";
+        }
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/34230db8/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
----------------------------------------------------------------------
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
index bfa8c6b..f07bb79 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
@@ -20,9 +20,11 @@ package org.apache.camel.tools.apt.util;
  * Some String helper methods
  */
 public final class Strings {
+
     private Strings() {
         //Helper class
     }
+
     /**
      * Returns true if the given text is null or empty string
      */
@@ -49,4 +51,31 @@ public final class Strings {
             return className;
         }
     }
+
+    /**
+     * Returns the text wrapped double quotes
+     */
+    public static String doubleQuote(String text) {
+        return quote(text, "\"");
+    }
+
+    /**
+     * Returns the text wrapped single quotes
+     */
+    public static String singleQuote(String text) {
+        return quote(text, "'");
+    }
+
+    /**
+     * Wraps the text in the given quote text
+     *
+     * @param text the text to wrap in quotes
+     * @param quote the quote text added to the prefix and postfix of the text
+     *
+     * @return the text wrapped in the given quotes
+     */
+    public static String quote(String text, String quote) {
+        return quote + text + quote;
+    }
+
 }

Reply via email to