Repository: camel Updated Branches: refs/heads/master 59322fdab -> 4b218f18d
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/7bba4656 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7bba4656 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7bba4656 Branch: refs/heads/master Commit: 7bba46564cdb7782ee3ddc9e8c711c2f8ed80834 Parents: 34230db Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Nov 6 10:05:38 2014 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Nov 7 13:25:17 2014 +0100 ---------------------------------------------------------------------- .../tools/apt/EndpointAnnotationProcessor.java | 55 ++++++++++++- .../camel/tools/apt/util/JsonSchemaHelper.java | 84 ++++++++++++++++++-- 2 files changed, 127 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/7bba4656/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 467070f..a4bd197 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 @@ -25,7 +25,9 @@ import java.io.Writer; import java.net.URI; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.SortedMap; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.RoundEnvironment; @@ -48,6 +50,7 @@ import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.tools.apt.util.Func1; +import org.apache.camel.tools.apt.util.JsonSchemaHelper; import org.apache.camel.tools.apt.util.Strings; import static org.apache.camel.tools.apt.util.Strings.canonicalClassName; @@ -76,6 +79,7 @@ public class EndpointAnnotationProcessor extends AbstractProcessor { if (uriEndpoint != null) { String scheme = uriEndpoint.scheme(); if (!Strings.isNullOrEmpty(scheme)) { + // write html documentation String name = canonicalClassName(classElement.getQualifiedName().toString()); String packageName = name.substring(0, name.lastIndexOf(".")); String fileName = scheme + ".html"; @@ -83,19 +87,26 @@ public class EndpointAnnotationProcessor extends AbstractProcessor { @Override public Void call(PrintWriter writer) { writeHtmlDocumentation(writer, roundEnv, classElement, uriEndpoint); + return null; + } + }; + processFile(packageName, scheme, fileName, handler); + + // write json schema + fileName = scheme + ".json"; + handler = new Func1<PrintWriter, Void>() { + @Override + public Void call(PrintWriter writer) { writeJSonSchemeDocumentation(writer, roundEnv, classElement, uriEndpoint); return null; } }; +// packageName = "META-INF.services.org.apache.camel.schema"; processFile(packageName, scheme, fileName, handler); } } } - 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>"); @@ -135,6 +146,42 @@ public class EndpointAnnotationProcessor extends AbstractProcessor { writer.println("</html>"); } + protected void writeJSonSchemeDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint) { + String scheme = uriEndpoint.scheme(); + + String classDoc = processingEnv.getElementUtils().getDocComment(classElement); + if (!Strings.isNullOrEmpty(classDoc)) { + // remove dodgy @version that we may have in class javadoc + classDoc = classDoc.replaceFirst("\\@version", ""); + classDoc = classDoc.trim(); + } + + // TODO: add some top details about component scheme name, and documentation + + Set<EndpointOption> endpointOptions = new LinkedHashSet<>(); + findClassProperties(roundEnv, endpointOptions, classElement, ""); + if (!endpointOptions.isEmpty()) { + String json = createParameterJsonSchema(endpointOptions); + writer.println(json); + } + } + + + public String createParameterJsonSchema(Set<EndpointOption> options) { + StringBuilder buffer = new StringBuilder("{\n \"properties\": {"); + boolean first = true; + for (EndpointOption entry : options) { + if (first) { + first = false; + } else { + buffer.append(","); + } + buffer.append("\n "); + buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getType(), entry.getDocumentation())); + } + buffer.append("\n }\n}\n"); + return buffer.toString(); + } protected void showDocumentationAndFieldInjections(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, String prefix) { String classDoc = processingEnv.getElementUtils().getDocComment(classElement); http://git-wip-us.apache.org/repos/asf/camel/blob/7bba4656/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 index 6a4f4c4..9f8ad26 100644 --- 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 @@ -27,6 +27,27 @@ public final class JsonSchemaHelper { } public static String toJson(String name, String type, String description) { + String typeName = JsonSchemaHelper.getType(type); + + // TODO: add support for enum and array + + StringBuilder sb = new StringBuilder(); + sb.append(doubleQuote(name)); + sb.append(": { \"type\":"); + sb.append(doubleQuote(typeName)); + if (!Strings.isNullOrEmpty(description)) { + sb.append(", \"description\":"); + String text = sanitizeDescription(description); + sb.append(doubleQuote(text)); + } + + if ("object".equals(typeName)) { + // for object then include the javaType as a description so we know that + sb.append(", \"properties\": { \"javaType\": { \"description\": \"" + type + "\", \"type\": \"string\" } }"); + } + sb.append(" }"); + return sb.toString(); + // if (type.isEnum()) { // String typeName = "string"; // CollectionStringBuffer sb = new CollectionStringBuffer(); @@ -38,14 +59,13 @@ public final class JsonSchemaHelper { // 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) + " }"; - } +// 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) + " }"; +// } // } } @@ -125,4 +145,52 @@ public final class JsonSchemaHelper { return null; } + /** + * Sanitizes the javadoc to removed invalid characters so it can be used as json description + * + * @param javadoc the javadoc + * @return the text that is valid as json + */ + public static String sanitizeDescription(String javadoc) { + // lets just use what java accepts as identifiers + StringBuilder sb = new StringBuilder(); + + // split into lines + String[] lines = javadoc.split("\n"); + + boolean first = true; + for (String line : lines) { + line = line.trim(); + + // skip lines that are javadoc references + if (line.startsWith("@")) { + continue; + } + + // replace some known html tags + javadoc = javadoc.replaceAll("\\<tt\\>", ""); + javadoc = javadoc.replaceAll("\\</tt\\>", ""); + javadoc = javadoc.replaceAll("\\<code\\>", ""); + javadoc = javadoc.replaceAll("\\</code\\>", ""); + + // we are starting from a new line, so add a whitespace + if (!first) { + sb.append(' '); + } + + for (char c : line.toCharArray()) { + if (Character.isJavaIdentifierPart(c) || '.' == c) { + sb.append(c); + } else if (Character.isWhitespace(c)) { + // always use space as whitespace, also for line feeds etc + sb.append(' '); + } + } + + first = false; + } + + return sb.toString(); + } + }