You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/11/12 09:18:13 UTC

[02/33] camel git commit: Camel component docs. Add group as a way of combining the options in a number of coheret groups based on their labels.

Camel component docs. Add group as a way of combining the options in a number of coheret groups based on their labels.


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

Branch: refs/heads/master
Commit: c850a6e0ec291dd04ec925eaeb387ee073aaa091
Parents: 0471a55
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Nov 11 20:08:02 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Nov 12 09:19:11 2015 +0100

----------------------------------------------------------------------
 .../tools/apt/AbstractAnnotationProcessor.java  |   6 +-
 .../camel/tools/apt/CollectionStringBuffer.java |  58 ---
 .../camel/tools/apt/DocumentationHelper.java    |   4 +-
 .../camel/tools/apt/EipAnnotationProcessor.java |  12 +-
 .../tools/apt/EndpointAnnotationProcessor.java  | 498 ++-----------------
 .../java/org/apache/camel/tools/apt/Func1.java  |   2 +
 .../org/apache/camel/tools/apt/IOHelper.java    |  82 ---
 .../camel/tools/apt/JsonSchemaHelper.java       | 361 --------------
 .../org/apache/camel/tools/apt/Strings.java     | 103 ----
 .../apt/helper/CollectionStringBuffer.java      |  58 +++
 .../camel/tools/apt/helper/EndpointHelper.java  | 127 +++++
 .../apache/camel/tools/apt/helper/IOHelper.java |  82 +++
 .../tools/apt/helper/JsonSchemaHelper.java      | 367 ++++++++++++++
 .../apache/camel/tools/apt/helper/Strings.java  | 103 ++++
 .../camel/tools/apt/model/ComponentModel.java   | 129 +++++
 .../camel/tools/apt/model/ComponentOption.java  | 137 +++++
 .../camel/tools/apt/model/EndpointOption.java   | 137 +++++
 .../camel/tools/apt/model/EndpointPath.java     | 122 +++++
 .../tools/apt/EndpointOptionComparatorTest.java |  61 +++
 19 files changed, 1388 insertions(+), 1061 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java
index 051b5e2..9a49110 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java
@@ -41,9 +41,9 @@ import javax.tools.Diagnostic;
 import javax.tools.FileObject;
 import javax.tools.StandardLocation;
 
-import static org.apache.camel.tools.apt.IOHelper.loadText;
-import static org.apache.camel.tools.apt.Strings.canonicalClassName;
-import static org.apache.camel.tools.apt.Strings.isNullOrEmpty;
+import static org.apache.camel.tools.apt.helper.IOHelper.loadText;
+import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName;
+import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty;
 
 /**
  * Abstract class for Camel apt plugins.

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CollectionStringBuffer.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CollectionStringBuffer.java
deleted file mode 100644
index 21daf95..0000000
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CollectionStringBuffer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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;
-
-/**
- * A little helper class for converting a collection of values to a (usually comma separated) string.
- */
-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/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/DocumentationHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/DocumentationHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/DocumentationHelper.java
index 6de021d..c3e72c5 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/DocumentationHelper.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/DocumentationHelper.java
@@ -26,7 +26,9 @@ import java.io.LineNumberReader;
 import java.util.List;
 import java.util.Map;
 
-import static org.apache.camel.tools.apt.JsonSchemaHelper.parseJsonSchema;
+import org.apache.camel.tools.apt.helper.IOHelper;
+
+import static org.apache.camel.tools.apt.helper.JsonSchemaHelper.parseJsonSchema;
 
 /**
  * Helper to find documentation for inherited options when a component extends another.

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java
index 53bc12d..bab6360 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java
@@ -44,11 +44,13 @@ import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.tools.apt.helper.JsonSchemaHelper;
+import org.apache.camel.tools.apt.helper.Strings;
 
-import static org.apache.camel.tools.apt.JsonSchemaHelper.sanitizeDescription;
-import static org.apache.camel.tools.apt.Strings.canonicalClassName;
-import static org.apache.camel.tools.apt.Strings.isNullOrEmpty;
-import static org.apache.camel.tools.apt.Strings.safeNull;
+import static org.apache.camel.tools.apt.helper.JsonSchemaHelper.sanitizeDescription;
+import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName;
+import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty;
+import static org.apache.camel.tools.apt.helper.Strings.safeNull;
 
 /**
  * Process all camel-core's model classes (EIPs and DSL) and generate json schema documentation
@@ -201,7 +203,7 @@ public class EipAnnotationProcessor extends AbstractAnnotationProcessor {
             String doc = entry.getDocumentation();
             doc = sanitizeDescription(doc, false);
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc,
-                    entry.isDeprecated(), null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes()));
+                    entry.isDeprecated(), null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes()));
         }
         buffer.append("\n  }");
 

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/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 00a35e7..c04c628 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
@@ -17,6 +17,8 @@
 package org.apache.camel.tools.apt;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -42,12 +44,19 @@ import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
 import org.apache.camel.spi.UriPath;
-
-import static org.apache.camel.tools.apt.JsonSchemaHelper.sanitizeDescription;
-import static org.apache.camel.tools.apt.Strings.canonicalClassName;
-import static org.apache.camel.tools.apt.Strings.getOrElse;
-import static org.apache.camel.tools.apt.Strings.isNullOrEmpty;
-import static org.apache.camel.tools.apt.Strings.safeNull;
+import org.apache.camel.tools.apt.helper.EndpointHelper;
+import org.apache.camel.tools.apt.helper.JsonSchemaHelper;
+import org.apache.camel.tools.apt.helper.Strings;
+import org.apache.camel.tools.apt.model.ComponentModel;
+import org.apache.camel.tools.apt.model.ComponentOption;
+import org.apache.camel.tools.apt.model.EndpointOption;
+import org.apache.camel.tools.apt.model.EndpointPath;
+
+import static org.apache.camel.tools.apt.helper.JsonSchemaHelper.sanitizeDescription;
+import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName;
+import static org.apache.camel.tools.apt.helper.Strings.getOrElse;
+import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty;
+import static org.apache.camel.tools.apt.helper.Strings.safeNull;
 
 /**
  * Processes all Camel {@link UriEndpoint}s and generate json schema and html documentation for the endpoint/component.
@@ -95,7 +104,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
                     Func1<PrintWriter, Void> handler = new Func1<PrintWriter, Void>() {
                         @Override
                         public Void call(PrintWriter writer) {
-                            writeHtmlDocumentation(writer, roundEnv, classElement, uriEndpoint, aliasTitle, alias, label);
+                            writeHtmlDocumentation(writer, roundEnv, classElement, uriEndpoint, aliasTitle, alias, extendsAlias, label);
                             return null;
                         }
                     };
@@ -117,7 +126,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
     }
 
     protected void writeHtmlDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint,
-                                          String title, String scheme, String label) {
+                                          String title, String scheme, String extendsScheme, String label) {
         writer.println("<html>");
         writer.println("<header>");
         writer.println("<title>" + title  + "</title>");
@@ -135,7 +144,10 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
             writer.println("</ul>");
         }
 
-        showDocumentationAndFieldInjections(writer, roundEnv, classElement, "");
+        // gather component information
+        ComponentModel componentModel = findComponentProperties(roundEnv, uriEndpoint, title, scheme, extendsScheme, label);
+
+        writeHtmlDocumentationAndFieldInjections(writer, roundEnv, componentModel, classElement, "");
 
         // This code is not my fault, it seems to honestly be the hacky way to find a class name in APT :)
         TypeMirror consumerType = null;
@@ -153,7 +165,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
             TypeElement consumerElement = findTypeElement(roundEnv, consumerClassName);
             if (consumerElement != null) {
                 writer.println("<h2>" + scheme + " consumer" + "</h2>");
-                showDocumentationAndFieldInjections(writer, roundEnv, consumerElement, consumerPrefix);
+                writeHtmlDocumentationAndFieldInjections(writer, roundEnv, componentModel, consumerElement, consumerPrefix);
                 found = true;
             }
         }
@@ -165,7 +177,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
     }
 
     protected void writeJSonSchemeDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint,
-                                                String title, String scheme, final String extendsScheme, String label) {
+                                                String title, String scheme, String extendsScheme, String label) {
         // gather component information
         ComponentModel componentModel = findComponentProperties(roundEnv, uriEndpoint, title, scheme, extendsScheme, label);
 
@@ -176,10 +188,10 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
 
         TypeElement componentClassElement = findTypeElement(roundEnv, componentModel.getJavaType());
         if (componentClassElement != null) {
-            findComponentClassProperties(writer, roundEnv, componentOptions, componentClassElement, "");
+            findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "");
         }
 
-        findClassProperties(writer, roundEnv, endpointPaths, endpointOptions, classElement, "");
+        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "");
 
         String json = createParameterJsonSchema(componentModel, componentOptions, endpointPaths, endpointOptions);
         writer.println(json);
@@ -235,7 +247,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
             }
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), "property", required, entry.getType(), defaultValue, doc,
-                    entry.isDeprecated(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null));
+                    entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null));
         }
         buffer.append("\n  },");
 
@@ -275,11 +287,16 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
             }
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), "path", required, entry.getType(), defaultValue, doc,
-                    entry.isDeprecated(), label, entry.isEnumType(), entry.getEnums(), false, null));
+                    entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null));
         }
 
+        // sort the endpoint options in the standard order we prefer
+        List<EndpointOption> options = new ArrayList<EndpointOption>();
+        options.addAll(endpointOptions);
+        Collections.sort(options, EndpointHelper.createGroupAndLabelComparator());
+
         // and then regular parameter options
-        for (EndpointOption entry : endpointOptions) {
+        for (EndpointOption entry : options) {
             String label = entry.getLabel();
             if (label != null) {
                 // skip options which are either consumer or producer labels but the component does not support them
@@ -311,7 +328,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
             }
 
             buffer.append(JsonSchemaHelper.toJson(entry.getName(), "parameter", required, entry.getType(), defaultValue,
-                    doc, entry.isDeprecated(), label, entry.isEnumType(), entry.getEnums(), false, null));
+                    doc, entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null));
         }
         buffer.append("\n  }");
 
@@ -319,7 +336,8 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
         return buffer.toString();
     }
 
-    protected void showDocumentationAndFieldInjections(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, String prefix) {
+    protected void writeHtmlDocumentationAndFieldInjections(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel,
+                                                            TypeElement classElement, String prefix) {
         String classDoc = processingEnv.getElementUtils().getDocComment(classElement);
         if (!isNullOrEmpty(classDoc)) {
             // remove dodgy @version that we may have in class javadoc
@@ -330,7 +348,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
 
         Set<EndpointPath> endpointPaths = new LinkedHashSet<EndpointPath>();
         Set<EndpointOption> endpointOptions = new LinkedHashSet<EndpointOption>();
-        findClassProperties(writer, roundEnv, endpointPaths, endpointOptions, classElement, prefix);
+        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, prefix);
 
         if (!endpointOptions.isEmpty() || !endpointPaths.isEmpty()) {
             writer.println("<table class='table'>");
@@ -442,7 +460,8 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
         return model;
     }
 
-    protected void findComponentClassProperties(PrintWriter writer, RoundEnvironment roundEnv, Set<ComponentOption> componentOptions, TypeElement classElement, String prefix) {
+    protected void findComponentClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel,
+                                                Set<ComponentOption> componentOptions, TypeElement classElement, String prefix) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
             List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements());
@@ -515,8 +534,9 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
                     }
                 }
 
+                String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                 ComponentOption option = new ComponentOption(name, fieldTypeName, required, defaultValue, defaultValueNote,
-                        docComment.trim(), deprecated, label, isEnum, enums);
+                        docComment.trim(), deprecated, group, label, isEnum, enums);
                 componentOptions.add(option);
             }
 
@@ -535,7 +555,9 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
         }
     }
 
-    protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, Set<EndpointPath> endpointPaths, Set<EndpointOption> endpointOptions, TypeElement classElement, String prefix) {
+    protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel,
+                                       Set<EndpointPath> endpointPaths, Set<EndpointOption> endpointOptions,
+                                       TypeElement classElement, String prefix) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
             List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
@@ -598,7 +620,8 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
                         }
                     }
 
-                    EndpointPath ep = new EndpointPath(name, fieldTypeName, required, defaultValue, docComment, deprecated, label, isEnum, enums);
+                    String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
+                    EndpointPath ep = new EndpointPath(name, fieldTypeName, required, defaultValue, docComment, deprecated, group, label, isEnum, enums);
                     endpointPaths.add(ep);
                 }
 
@@ -636,7 +659,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
                         if (!isNullOrEmpty(extraPrefix)) {
                             nestedPrefix += extraPrefix;
                         }
-                        findClassProperties(writer, roundEnv, endpointPaths, endpointOptions, fieldTypeElement, nestedPrefix);
+                        findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, fieldTypeElement, nestedPrefix);
                     } else {
                         String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, false);
                         if (isNullOrEmpty(docComment)) {
@@ -668,8 +691,10 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
                             }
                         }
 
+
+                        String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                         EndpointOption option = new EndpointOption(name, fieldTypeName, required, defaultValue, defaultValueNote,
-                                docComment.trim(), deprecated, label, isEnum, enums);
+                                docComment.trim(), deprecated, group, label, isEnum, enums);
                         endpointOptions.add(option);
                     }
                 }
@@ -704,427 +729,4 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor {
         return answer;
     }
 
-    private static final class ComponentModel {
-
-        private String scheme;
-        private String extendsScheme;
-        private String syntax;
-        private String javaType;
-        private String title;
-        private String description;
-        private String groupId;
-        private String artifactId;
-        private String versionId;
-        private String label;
-        private boolean consumerOnly;
-        private boolean producerOnly;
-
-        private ComponentModel(String scheme) {
-            this.scheme = scheme;
-        }
-
-        public String getScheme() {
-            return scheme;
-        }
-
-        public String getExtendsScheme() {
-            return extendsScheme;
-        }
-
-        public void setExtendsScheme(String extendsScheme) {
-            this.extendsScheme = extendsScheme;
-        }
-
-        public String getSyntax() {
-            return syntax;
-        }
-
-        public void setSyntax(String syntax) {
-            this.syntax = syntax;
-        }
-
-        public String getJavaType() {
-            return javaType;
-        }
-
-        public void setJavaType(String javaType) {
-            this.javaType = javaType;
-        }
-
-        public String getTitle() {
-            return title;
-        }
-
-        public void setTitle(String title) {
-            this.title = title;
-        }
-
-        public String getDescription() {
-            return description;
-        }
-
-        public void setDescription(String description) {
-            this.description = description;
-        }
-
-        public String getGroupId() {
-            return groupId;
-        }
-
-        public void setGroupId(String groupId) {
-            this.groupId = groupId;
-        }
-
-        public String getArtifactId() {
-            return artifactId;
-        }
-
-        public void setArtifactId(String artifactId) {
-            this.artifactId = artifactId;
-        }
-
-        public String getVersionId() {
-            return versionId;
-        }
-
-        public void setVersionId(String versionId) {
-            this.versionId = versionId;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        public void setLabel(String label) {
-            this.label = label;
-        }
-
-        public boolean isConsumerOnly() {
-            return consumerOnly;
-        }
-
-        public void setConsumerOnly(boolean consumerOnly) {
-            this.consumerOnly = consumerOnly;
-        }
-
-        public boolean isProducerOnly() {
-            return producerOnly;
-        }
-
-        public void setProducerOnly(boolean producerOnly) {
-            this.producerOnly = producerOnly;
-        }
-    }
-
-    private static final class ComponentOption {
-
-        private String name;
-        private String type;
-        private String required;
-        private String defaultValue;
-        private String defaultValueNote;
-        private String documentation;
-        private boolean deprecated;
-        private String label;
-        private boolean enumType;
-        private Set<String> enums;
-
-        private ComponentOption(String name, String type, String required, String defaultValue, String defaultValueNote,
-                                String documentation, boolean deprecated, String label, boolean enumType, Set<String> enums) {
-            this.name = name;
-            this.type = type;
-            this.required = required;
-            this.defaultValue = defaultValue;
-            this.defaultValueNote = defaultValueNote;
-            this.documentation = documentation;
-            this.deprecated = deprecated;
-            this.label = label;
-            this.enumType = enumType;
-            this.enums = enums;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getRequired() {
-            return required;
-        }
-
-        public String getDefaultValue() {
-            return defaultValue;
-        }
-
-        public String getDocumentation() {
-            return documentation;
-        }
-
-        public boolean isDeprecated() {
-            return deprecated;
-        }
-
-        public String getEnumValuesAsHtml() {
-            CollectionStringBuffer csb = new CollectionStringBuffer("<br/>");
-            if (enums != null && enums.size() > 0) {
-                for (String e : enums) {
-                    csb.append(e);
-                }
-            }
-            return csb.toString();
-        }
-
-        public String getDocumentationWithNotes() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(documentation);
-
-            if (!isNullOrEmpty(defaultValueNote)) {
-                sb.append(". Default value notice: ").append(defaultValueNote);
-            }
-
-            return sb.toString();
-        }
-
-        public boolean isEnumType() {
-            return enumType;
-        }
-
-        public Set<String> getEnums() {
-            return enums;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            ComponentOption that = (ComponentOption) o;
-
-            if (!name.equals(that.name)) {
-                return false;
-            }
-
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-    }
-
-    private static final class EndpointOption {
-
-        private String name;
-        private String type;
-        private String required;
-        private String defaultValue;
-        private String defaultValueNote;
-        private String documentation;
-        private boolean deprecated;
-        private String label;
-        private boolean enumType;
-        private Set<String> enums;
-
-        private EndpointOption(String name, String type, String required, String defaultValue, String defaultValueNote,
-                               String documentation, boolean deprecated, String label, boolean enumType, Set<String> enums) {
-            this.name = name;
-            this.type = type;
-            this.required = required;
-            this.defaultValue = defaultValue;
-            this.defaultValueNote = defaultValueNote;
-            this.documentation = documentation;
-            this.deprecated = deprecated;
-            this.label = label;
-            this.enumType = enumType;
-            this.enums = enums;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getRequired() {
-            return required;
-        }
-
-        public String getDefaultValue() {
-            return defaultValue;
-        }
-
-        public String getDocumentation() {
-            return documentation;
-        }
-
-        public boolean isDeprecated() {
-            return deprecated;
-        }
-
-        public String getEnumValuesAsHtml() {
-            CollectionStringBuffer csb = new CollectionStringBuffer("<br/>");
-            if (enums != null && enums.size() > 0) {
-                for (String e : enums) {
-                    csb.append(e);
-                }
-            }
-            return csb.toString();
-        }
-
-        public String getDocumentationWithNotes() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(documentation);
-
-            if (!isNullOrEmpty(defaultValueNote)) {
-                sb.append(". Default value notice: ").append(defaultValueNote);
-            }
-
-            return sb.toString();
-        }
-
-        public boolean isEnumType() {
-            return enumType;
-        }
-
-        public Set<String> getEnums() {
-            return enums;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        @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();
-        }
-    }
-
-    private static final class EndpointPath {
-
-        private String name;
-        private String type;
-        private String required;
-        private String defaultValue;
-        private String documentation;
-        private boolean deprecated;
-        private String label;
-        private boolean enumType;
-        private Set<String> enums;
-
-        private EndpointPath(String name, String type, String required, String defaultValue, String documentation, boolean deprecated,
-                             String label, boolean enumType, Set<String> enums) {
-            this.name = name;
-            this.type = type;
-            this.required = required;
-            this.defaultValue = defaultValue;
-            this.documentation = documentation;
-            this.deprecated = deprecated;
-            this.label = label;
-            this.enumType = enumType;
-            this.enums = enums;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getRequired() {
-            return required;
-        }
-
-        public String getDefaultValue() {
-            return defaultValue;
-        }
-
-        public String getDocumentation() {
-            return documentation;
-        }
-
-        public boolean isDeprecated() {
-            return deprecated;
-        }
-
-        public String getEnumValuesAsHtml() {
-            CollectionStringBuffer csb = new CollectionStringBuffer("<br/>");
-            if (enums != null && enums.size() > 0) {
-                for (String e : enums) {
-                    csb.append(e);
-                }
-            }
-            return csb.toString();
-        }
-
-        public boolean isEnumType() {
-            return enumType;
-        }
-
-        public Set<String> getEnums() {
-            return enums;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            EndpointPath that = (EndpointPath) 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/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/Func1.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/Func1.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/Func1.java
index 59830ae..6c6ab8d 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/Func1.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/Func1.java
@@ -20,5 +20,7 @@ package org.apache.camel.tools.apt;
  * Represents a function with 1 argument
  */
 interface Func1<T1, R> {
+
     R call(T1 t1);
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/IOHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/IOHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/IOHelper.java
deleted file mode 100644
index d4c1717..0000000
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/IOHelper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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;
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-final class IOHelper {
-
-    private IOHelper() {
-    }
-
-    /**
-     * Loads the entire stream into memory as a String and returns it.
-     * <p/>
-     * <b>Notice:</b> This implementation appends a <tt>\n</tt> as line
-     * terminator at the of the text.
-     * <p/>
-     * Warning, don't use for crazy big streams :)
-     */
-    public static String loadText(InputStream in, boolean skipCommentOrEmptyLines) throws IOException {
-        StringBuilder builder = new StringBuilder();
-        InputStreamReader isr = new InputStreamReader(in);
-        try {
-            BufferedReader reader = new BufferedReader(isr);
-            while (true) {
-                String line = reader.readLine();
-                if (line != null) {
-
-                    boolean empty = Strings.isNullOrEmpty(line);
-                    boolean comment = line.trim().startsWith("#");
-                    if (skipCommentOrEmptyLines && (empty || comment)) {
-                        continue;
-                    }
-
-                    builder.append(line);
-                    builder.append("\n");
-                } else {
-                    break;
-                }
-            }
-            return builder.toString();
-        } finally {
-            close(isr, in);
-        }
-    }
-
-    /**
-     * Closes the given resources if they are available.
-     *
-     * @param closeables the objects to close
-     */
-    public static void close(Closeable... closeables) {
-        for (Closeable closeable : closeables) {
-            try {
-                closeable.close();
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-    }
-
-
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/JsonSchemaHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/JsonSchemaHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/JsonSchemaHelper.java
deleted file mode 100644
index 0df1eb1..0000000
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/JsonSchemaHelper.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/**
- * 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;
-
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A helper class for <a href="http://json-schema.org/">JSON schema</a>.
- */
-final class JsonSchemaHelper {
-
-    private static final String VALID_CHARS = ".-='/\\!&():;";
-    private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]");
-    private static final String QUOT = "&quot;";
-
-    private JsonSchemaHelper() {
-    }
-
-    public static String toJson(String name, String kind, Boolean required, String type, String defaultValue, String description,
-                                Boolean deprecated, String label, boolean enumType, Set<String> enums, boolean oneOfType, Set<String> oneOffTypes) {
-        String typeName = JsonSchemaHelper.getType(type, enumType);
-
-        StringBuilder sb = new StringBuilder();
-        sb.append(Strings.doubleQuote(name));
-        sb.append(": { \"kind\": ");
-        sb.append(Strings.doubleQuote(kind));
-
-        // we want label early so its easier to spot
-        if (!Strings.isNullOrEmpty(label)) {
-            sb.append(", \"label\": ");
-            sb.append(Strings.doubleQuote(label));
-        }
-
-        if (required != null) {
-            sb.append(", \"required\": ");
-            sb.append(Strings.doubleQuote(required.toString()));
-        }
-
-        sb.append(", \"type\": ");
-        if ("enum".equals(typeName)) {
-            sb.append(Strings.doubleQuote("string"));
-            sb.append(", \"javaType\": \"" + type + "\"");
-            CollectionStringBuffer enumValues = new CollectionStringBuffer();
-            for (Object value : enums) {
-                enumValues.append(Strings.doubleQuote(value.toString()));
-            }
-            sb.append(", \"enum\": [ ");
-            sb.append(enumValues.toString());
-            sb.append(" ]");
-        } else if (oneOfType) {
-            sb.append(Strings.doubleQuote(typeName));
-            sb.append(", \"javaType\": \"" + type + "\"");
-            CollectionStringBuffer oneOfValues = new CollectionStringBuffer();
-            for (Object value : oneOffTypes) {
-                oneOfValues.append(Strings.doubleQuote(value.toString()));
-            }
-            sb.append(", \"oneOf\": [ ");
-            sb.append(oneOfValues.toString());
-            sb.append(" ]");
-        } else if ("array".equals(typeName)) {
-            sb.append(Strings.doubleQuote("array"));
-            sb.append(", \"javaType\": \"" + type + "\"");
-        } else {
-            sb.append(Strings.doubleQuote(typeName));
-            sb.append(", \"javaType\": \"" + type + "\"");
-        }
-
-        if (deprecated != null) {
-            sb.append(", \"deprecated\": ");
-            sb.append(Strings.doubleQuote(deprecated.toString()));
-        }
-
-        if (!Strings.isNullOrEmpty(defaultValue)) {
-            sb.append(", \"defaultValue\": ");
-            String text = safeDefaultValue(defaultValue);
-            sb.append(Strings.doubleQuote(text));
-        }
-
-        if (!Strings.isNullOrEmpty(description)) {
-            sb.append(", \"description\": ");
-            String text = sanitizeDescription(description, false);
-            sb.append(Strings.doubleQuote(text));
-        }
-
-        sb.append(" }");
-        return sb.toString();
-    }
-
-    /**
-     * 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, boolean enumType) {
-        if (enumType) {
-            return "enum";
-        } else if (type == null) {
-            // return generic type for unknown type
-            return "object";
-        } else if (type.equals(URI.class.getName()) || type.equals(URL.class.getName())) {
-            return "string";
-        } else if (type.startsWith("java.lang.Class")) {
-            return "string";
-        } else if (type.startsWith("java.util.List") || type.startsWith("java.util.Collection")) {
-            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;
-    }
-
-    /**
-     * 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, boolean summary) {
-        if (Strings.isNullOrEmpty(javadoc)) {
-            return null;
-        }
-
-        // 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();
-
-            // terminate if we reach @param, @return or @deprecated as we only want the javadoc summary
-            if (line.startsWith("@param") || line.startsWith("@return") || line.startsWith("@deprecated")) {
-                break;
-            }
-
-            // skip lines that are javadoc references
-            if (line.startsWith("@")) {
-                continue;
-            }
-
-            // remove all HTML tags
-            line = line.replaceAll("<.*?>", "");
-
-            // remove all inlined javadoc links, eg such as {@link org.apache.camel.spi.Registry}
-            line = line.replaceAll("\\{\\@\\w+\\s([\\w.]+)\\}", "$1");
-
-            // we are starting from a new line, so add a whitespace
-            if (!first) {
-                sb.append(' ');
-            }
-
-            // create a new line
-            StringBuilder cb = new StringBuilder();
-            for (char c : line.toCharArray()) {
-                if (Character.isJavaIdentifierPart(c) || VALID_CHARS.indexOf(c) != -1) {
-                    cb.append(c);
-                } else if (Character.isWhitespace(c)) {
-                    // always use space as whitespace, also for line feeds etc
-                    cb.append(' ');
-                }
-            }
-
-            // append data
-            String s = cb.toString().trim();
-            sb.append(s);
-
-            boolean empty = Strings.isNullOrEmpty(s);
-            boolean endWithDot = s.endsWith(".");
-            boolean haveText = sb.length() > 0;
-
-            if (haveText && summary && (empty || endWithDot)) {
-                // if we only want a summary, then skip at first empty line we encounter, or if the sentence ends with a dot
-                break;
-            }
-
-            first = false;
-        }
-
-        // remove double whitespaces, and trim
-        String s = sb.toString();
-        s = s.replaceAll("\\s+", " ");
-        return s.trim();
-    }
-
-    /**
-     * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
-     *
-     * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
-     * @param json the json
-     * @return a list of all the rows, where each row is a set of key value pairs with metadata
-     */
-    public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) {
-        List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
-        if (json == null) {
-            return answer;
-        }
-
-        boolean found = false;
-
-        // parse line by line
-        String[] lines = json.split("\n");
-        for (String line : lines) {
-            // we need to find the group first
-            if (!found) {
-                String s = line.trim();
-                found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
-                continue;
-            }
-
-            // we should stop when we end the group
-            if (line.equals("  },") || line.equals("  }")) {
-                break;
-            }
-
-            // need to safe encode \" so we can parse the line
-            line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
-
-            Map<String, String> row = new LinkedHashMap<String, String>();
-            Matcher matcher = PATTERN.matcher(line);
-
-            String key;
-            if (parseProperties) {
-                // when parsing properties the first key is given as name, so the first parsed token is the value of the name
-                key = "name";
-            } else {
-                key = null;
-            }
-            while (matcher.find()) {
-                if (key == null) {
-                    key = matcher.group(1);
-                } else {
-                    String value = matcher.group(1);
-                    if (value == null) {
-                        value = matcher.group(2);
-                        // its an enum so strip out " and trim spaces after comma
-                        value = value.replaceAll("\"", "");
-                        value = value.replaceAll(", ", ",");
-                    }
-                    if (value != null) {
-                        value = value.trim();
-                        // decode
-                        value = value.replaceAll(QUOT, "\"");
-                        value = decodeJson(value);
-                    }
-                    row.put(key, value);
-                    // reset
-                    key = null;
-                }
-            }
-            if (!row.isEmpty()) {
-                answer.add(row);
-            }
-        }
-
-        return answer;
-    }
-
-    private static String decodeJson(String value) {
-        // json encodes a \ as \\ so we need to decode from \\ back to \
-        if ("\\\\".equals(value)) {
-            value = "\\";
-        }
-        return value;
-    }
-
-    /**
-     * The default value may need to be escaped to be safe for json
-     */
-    private static String safeDefaultValue(String value) {
-        if ("\"".equals(value)) {
-            return "\\\"";
-        } else if ("\\".equals(value)) {
-            return "\\\\";
-        } else {
-            return value;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/Strings.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/Strings.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/Strings.java
deleted file mode 100644
index 3e0747b..0000000
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/Strings.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * 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;
-
-/**
- * Some String helper methods
- */
-final class Strings {
-
-    private Strings() {
-        //Helper class
-    }
-
-    /**
-     * Returns true if the given text is null or empty string or has <tt>null</tt> as the value
-     */
-    public static boolean isNullOrEmpty(String text) {
-        return text == null || text.length() == 0 || "null".equals(text);
-    }
-
-    public static String safeNull(String text) {
-        if (isNullOrEmpty(text)) {
-            return "";
-        } else {
-            return text;
-        }
-    }
-
-    /**
-     * Returns the value or the defaultValue if it is null
-     */
-    public static String getOrElse(String text, String defaultValue) {
-        return (text != null) ? text : defaultValue;
-    }
-
-    /**
-     * Returns the string after the given token
-     *
-     * @param text  the text
-     * @param after the token
-     * @return the text after the token, or <tt>null</tt> if text does not contain the token
-     */
-    public static String after(String text, String after) {
-        if (!text.contains(after)) {
-            return null;
-        }
-        return text.substring(text.indexOf(after) + after.length());
-    }
-
-    /**
-     * Returns the canonical class name by removing any generic type information.
-     */
-    public static String canonicalClassName(String className) {
-        // remove generics
-        int pos = className.indexOf('<');
-        if (pos != -1) {
-            return className.substring(0, pos);
-        } else {
-            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;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/CollectionStringBuffer.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/CollectionStringBuffer.java
new file mode 100644
index 0000000..ed89ad8
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/CollectionStringBuffer.java
@@ -0,0 +1,58 @@
+/**
+ * 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.helper;
+
+/**
+ * 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/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/EndpointHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/EndpointHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/EndpointHelper.java
new file mode 100644
index 0000000..b9c6eb6
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/EndpointHelper.java
@@ -0,0 +1,127 @@
+/**
+ * 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.helper;
+
+import java.util.Comparator;
+
+import org.apache.camel.tools.apt.model.EndpointOption;
+
+public final class EndpointHelper {
+
+    private EndpointHelper() {
+    }
+
+    /**
+     * Returns the group name from the given label.
+     * <p/>
+     * The group name is a single name deducted from the label. The label can contain multiple names separated by comma.
+     * The group is the best guess as a group of those labels, so similar labels can be combined into the same group.
+     *
+     * @param label          the label
+     * @param consumerOnly   whether the component is consumer only
+     * @param producerOnly   whether the component is producer only
+     * @return the group name
+     */
+    public static String labelAsGroupName(String label, boolean consumerOnly, boolean producerOnly) {
+        // if there is no label then use common as fallback
+        String answer = "common";
+        if (consumerOnly) {
+            answer = "consumer";
+        } else if (producerOnly) {
+            answer = "producer";
+        }
+
+        String value = label;
+        if (!Strings.isNullOrEmpty(value)) {
+
+            // we want to put advanced into own group, so look for a label that has advanced as prefix x,advanced => x (advanced)
+            value = value.replaceFirst("(\\w),(advanced)", "$1 (advanced)");
+
+            String[] array = value.split(",");
+            // grab last label which is the most specific label we want to use for the tab
+            answer = array[array.length - 1];
+            // if we are in consumer/producer only mode, then enrich the advanced label to indicate its advanced of those
+            if (answer.equals("advanced") && consumerOnly) {
+                answer = "consumer (advanced)";
+            } else if (answer.equals("advanced") && producerOnly) {
+                answer = "producer (advanced)";
+            }
+        }
+
+        return answer;
+    }
+
+    /**
+     * A comparator to sort the endpoint/component options according to group and label.
+     */
+    public static EndpointOptionGroupAndLabelComparator createGroupAndLabelComparator() {
+        return new EndpointOptionGroupAndLabelComparator();
+    }
+
+    private static final class EndpointOptionGroupAndLabelComparator implements Comparator<EndpointOption> {
+
+        @Override
+        public int compare(EndpointOption o1, EndpointOption o2) {
+            String name1 = o1.getName();
+            String name2 = o2.getName();
+            String label1 = o1.getLabel() != null ? o1.getLabel() : "common";
+            String label2 = o2.getLabel() != null ? o2.getLabel() : "common";
+            String group1 = o1.getGroup();
+            String group2 = o2.getGroup();
+
+            // if same label or group then sort by name
+            if (label1.equalsIgnoreCase(label2) || group1.equalsIgnoreCase(group2)) {
+                return name1.compareToIgnoreCase(name2);
+            }
+
+            int score1 = groupScore(group1);
+            int score2 = groupScore(group2);
+
+            if (score1 < score2) {
+                return -1;
+            } else if (score2 < score1) {
+                return 1;
+            } else {
+                // compare by full label and name
+                int score = label1.compareToIgnoreCase(label2);
+                if (score == 0) {
+                    score = name1.compareToIgnoreCase(name2);
+                }
+                return score;
+            }
+        }
+    }
+
+    private static int groupScore(String group) {
+        if ("common".equals(group)) {
+            return 1;
+        } else if ("common (advanced)".equals(group)) {
+            return 2;
+        } else if ("consumer".equals(group)) {
+            return 3;
+        } else if ("consumer (advanced)".equals(group)) {
+            return 4;
+        } else if ("producer".equals(group)) {
+            return 5;
+        } else if ("producer (advanced)".equals(group)) {
+            return 6;
+        } else {
+            return 9;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/IOHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/IOHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/IOHelper.java
new file mode 100644
index 0000000..32c1518
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/IOHelper.java
@@ -0,0 +1,82 @@
+/**
+ * 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.helper;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public final class IOHelper {
+
+    private IOHelper() {
+    }
+
+    /**
+     * Loads the entire stream into memory as a String and returns it.
+     * <p/>
+     * <b>Notice:</b> This implementation appends a <tt>\n</tt> as line
+     * terminator at the of the text.
+     * <p/>
+     * Warning, don't use for crazy big streams :)
+     */
+    public static String loadText(InputStream in, boolean skipCommentOrEmptyLines) throws IOException {
+        StringBuilder builder = new StringBuilder();
+        InputStreamReader isr = new InputStreamReader(in);
+        try {
+            BufferedReader reader = new BufferedReader(isr);
+            while (true) {
+                String line = reader.readLine();
+                if (line != null) {
+
+                    boolean empty = Strings.isNullOrEmpty(line);
+                    boolean comment = line.trim().startsWith("#");
+                    if (skipCommentOrEmptyLines && (empty || comment)) {
+                        continue;
+                    }
+
+                    builder.append(line);
+                    builder.append("\n");
+                } else {
+                    break;
+                }
+            }
+            return builder.toString();
+        } finally {
+            close(isr, in);
+        }
+    }
+
+    /**
+     * Closes the given resources if they are available.
+     *
+     * @param closeables the objects to close
+     */
+    public static void close(Closeable... closeables) {
+        for (Closeable closeable : closeables) {
+            try {
+                closeable.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
new file mode 100644
index 0000000..73f8a3b
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
@@ -0,0 +1,367 @@
+/**
+ * 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.helper;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A helper class for <a href="http://json-schema.org/">JSON schema</a>.
+ */
+public final class JsonSchemaHelper {
+
+    private static final String VALID_CHARS = ".-='/\\!&():;";
+    private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]");
+    private static final String QUOT = "&quot;";
+
+    private JsonSchemaHelper() {
+    }
+
+    public static String toJson(String name, String kind, Boolean required, String type, String defaultValue, String description,
+                                Boolean deprecated, String group, String label, boolean enumType, Set<String> enums, boolean oneOfType, Set<String> oneOffTypes) {
+        String typeName = JsonSchemaHelper.getType(type, enumType);
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(Strings.doubleQuote(name));
+        sb.append(": { \"kind\": ");
+        sb.append(Strings.doubleQuote(kind));
+
+        // we want group early so its easier to spot
+        if (!Strings.isNullOrEmpty(group)) {
+            sb.append(", \"group\": ");
+            sb.append(Strings.doubleQuote(group));
+        }
+
+        // we want label early so its easier to spot
+        if (!Strings.isNullOrEmpty(label)) {
+            sb.append(", \"label\": ");
+            sb.append(Strings.doubleQuote(label));
+        }
+
+        if (required != null) {
+            sb.append(", \"required\": ");
+            sb.append(Strings.doubleQuote(required.toString()));
+        }
+
+        sb.append(", \"type\": ");
+        if ("enum".equals(typeName)) {
+            sb.append(Strings.doubleQuote("string"));
+            sb.append(", \"javaType\": \"" + type + "\"");
+            CollectionStringBuffer enumValues = new CollectionStringBuffer();
+            for (Object value : enums) {
+                enumValues.append(Strings.doubleQuote(value.toString()));
+            }
+            sb.append(", \"enum\": [ ");
+            sb.append(enumValues.toString());
+            sb.append(" ]");
+        } else if (oneOfType) {
+            sb.append(Strings.doubleQuote(typeName));
+            sb.append(", \"javaType\": \"" + type + "\"");
+            CollectionStringBuffer oneOfValues = new CollectionStringBuffer();
+            for (Object value : oneOffTypes) {
+                oneOfValues.append(Strings.doubleQuote(value.toString()));
+            }
+            sb.append(", \"oneOf\": [ ");
+            sb.append(oneOfValues.toString());
+            sb.append(" ]");
+        } else if ("array".equals(typeName)) {
+            sb.append(Strings.doubleQuote("array"));
+            sb.append(", \"javaType\": \"" + type + "\"");
+        } else {
+            sb.append(Strings.doubleQuote(typeName));
+            sb.append(", \"javaType\": \"" + type + "\"");
+        }
+
+        if (deprecated != null) {
+            sb.append(", \"deprecated\": ");
+            sb.append(Strings.doubleQuote(deprecated.toString()));
+        }
+
+        if (!Strings.isNullOrEmpty(defaultValue)) {
+            sb.append(", \"defaultValue\": ");
+            String text = safeDefaultValue(defaultValue);
+            sb.append(Strings.doubleQuote(text));
+        }
+
+        if (!Strings.isNullOrEmpty(description)) {
+            sb.append(", \"description\": ");
+            String text = sanitizeDescription(description, false);
+            sb.append(Strings.doubleQuote(text));
+        }
+
+        sb.append(" }");
+        return sb.toString();
+    }
+
+    /**
+     * 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, boolean enumType) {
+        if (enumType) {
+            return "enum";
+        } else if (type == null) {
+            // return generic type for unknown type
+            return "object";
+        } else if (type.equals(URI.class.getName()) || type.equals(URL.class.getName())) {
+            return "string";
+        } else if (type.startsWith("java.lang.Class")) {
+            return "string";
+        } else if (type.startsWith("java.util.List") || type.startsWith("java.util.Collection")) {
+            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;
+    }
+
+    /**
+     * 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, boolean summary) {
+        if (Strings.isNullOrEmpty(javadoc)) {
+            return null;
+        }
+
+        // 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();
+
+            // terminate if we reach @param, @return or @deprecated as we only want the javadoc summary
+            if (line.startsWith("@param") || line.startsWith("@return") || line.startsWith("@deprecated")) {
+                break;
+            }
+
+            // skip lines that are javadoc references
+            if (line.startsWith("@")) {
+                continue;
+            }
+
+            // remove all HTML tags
+            line = line.replaceAll("<.*?>", "");
+
+            // remove all inlined javadoc links, eg such as {@link org.apache.camel.spi.Registry}
+            line = line.replaceAll("\\{\\@\\w+\\s([\\w.]+)\\}", "$1");
+
+            // we are starting from a new line, so add a whitespace
+            if (!first) {
+                sb.append(' ');
+            }
+
+            // create a new line
+            StringBuilder cb = new StringBuilder();
+            for (char c : line.toCharArray()) {
+                if (Character.isJavaIdentifierPart(c) || VALID_CHARS.indexOf(c) != -1) {
+                    cb.append(c);
+                } else if (Character.isWhitespace(c)) {
+                    // always use space as whitespace, also for line feeds etc
+                    cb.append(' ');
+                }
+            }
+
+            // append data
+            String s = cb.toString().trim();
+            sb.append(s);
+
+            boolean empty = Strings.isNullOrEmpty(s);
+            boolean endWithDot = s.endsWith(".");
+            boolean haveText = sb.length() > 0;
+
+            if (haveText && summary && (empty || endWithDot)) {
+                // if we only want a summary, then skip at first empty line we encounter, or if the sentence ends with a dot
+                break;
+            }
+
+            first = false;
+        }
+
+        // remove double whitespaces, and trim
+        String s = sb.toString();
+        s = s.replaceAll("\\s+", " ");
+        return s.trim();
+    }
+
+    /**
+     * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
+     *
+     * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
+     * @param json the json
+     * @return a list of all the rows, where each row is a set of key value pairs with metadata
+     */
+    public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) {
+        List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+        if (json == null) {
+            return answer;
+        }
+
+        boolean found = false;
+
+        // parse line by line
+        String[] lines = json.split("\n");
+        for (String line : lines) {
+            // we need to find the group first
+            if (!found) {
+                String s = line.trim();
+                found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
+                continue;
+            }
+
+            // we should stop when we end the group
+            if (line.equals("  },") || line.equals("  }")) {
+                break;
+            }
+
+            // need to safe encode \" so we can parse the line
+            line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
+
+            Map<String, String> row = new LinkedHashMap<String, String>();
+            Matcher matcher = PATTERN.matcher(line);
+
+            String key;
+            if (parseProperties) {
+                // when parsing properties the first key is given as name, so the first parsed token is the value of the name
+                key = "name";
+            } else {
+                key = null;
+            }
+            while (matcher.find()) {
+                if (key == null) {
+                    key = matcher.group(1);
+                } else {
+                    String value = matcher.group(1);
+                    if (value == null) {
+                        value = matcher.group(2);
+                        // its an enum so strip out " and trim spaces after comma
+                        value = value.replaceAll("\"", "");
+                        value = value.replaceAll(", ", ",");
+                    }
+                    if (value != null) {
+                        value = value.trim();
+                        // decode
+                        value = value.replaceAll(QUOT, "\"");
+                        value = decodeJson(value);
+                    }
+                    row.put(key, value);
+                    // reset
+                    key = null;
+                }
+            }
+            if (!row.isEmpty()) {
+                answer.add(row);
+            }
+        }
+
+        return answer;
+    }
+
+    private static String decodeJson(String value) {
+        // json encodes a \ as \\ so we need to decode from \\ back to \
+        if ("\\\\".equals(value)) {
+            value = "\\";
+        }
+        return value;
+    }
+
+    /**
+     * The default value may need to be escaped to be safe for json
+     */
+    private static String safeDefaultValue(String value) {
+        if ("\"".equals(value)) {
+            return "\\\"";
+        } else if ("\\".equals(value)) {
+            return "\\\\";
+        } else {
+            return value;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/Strings.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/Strings.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/Strings.java
new file mode 100644
index 0000000..30b826f
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/Strings.java
@@ -0,0 +1,103 @@
+/**
+ * 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.helper;
+
+/**
+ * Some String helper methods
+ */
+public final class Strings {
+
+    private Strings() {
+        //Helper class
+    }
+
+    /**
+     * Returns true if the given text is null or empty string or has <tt>null</tt> as the value
+     */
+    public static boolean isNullOrEmpty(String text) {
+        return text == null || text.length() == 0 || "null".equals(text);
+    }
+
+    public static String safeNull(String text) {
+        if (isNullOrEmpty(text)) {
+            return "";
+        } else {
+            return text;
+        }
+    }
+
+    /**
+     * Returns the value or the defaultValue if it is null
+     */
+    public static String getOrElse(String text, String defaultValue) {
+        return (text != null) ? text : defaultValue;
+    }
+
+    /**
+     * Returns the string after the given token
+     *
+     * @param text  the text
+     * @param after the token
+     * @return the text after the token, or <tt>null</tt> if text does not contain the token
+     */
+    public static String after(String text, String after) {
+        if (!text.contains(after)) {
+            return null;
+        }
+        return text.substring(text.indexOf(after) + after.length());
+    }
+
+    /**
+     * Returns the canonical class name by removing any generic type information.
+     */
+    public static String canonicalClassName(String className) {
+        // remove generics
+        int pos = className.indexOf('<');
+        if (pos != -1) {
+            return className.substring(0, pos);
+        } else {
+            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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/c850a6e0/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java
new file mode 100644
index 0000000..56810ec
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java
@@ -0,0 +1,129 @@
+/**
+ * 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.model;
+
+public final class ComponentModel {
+
+    private String scheme;
+    private String extendsScheme;
+    private String syntax;
+    private String javaType;
+    private String title;
+    private String description;
+    private String groupId;
+    private String artifactId;
+    private String versionId;
+    private String label;
+    private boolean consumerOnly;
+    private boolean producerOnly;
+
+    public ComponentModel(String scheme) {
+        this.scheme = scheme;
+    }
+
+    public String getScheme() {
+        return scheme;
+    }
+
+    public String getExtendsScheme() {
+        return extendsScheme;
+    }
+
+    public void setExtendsScheme(String extendsScheme) {
+        this.extendsScheme = extendsScheme;
+    }
+
+    public String getSyntax() {
+        return syntax;
+    }
+
+    public void setSyntax(String syntax) {
+        this.syntax = syntax;
+    }
+
+    public String getJavaType() {
+        return javaType;
+    }
+
+    public void setJavaType(String javaType) {
+        this.javaType = javaType;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    public String getArtifactId() {
+        return artifactId;
+    }
+
+    public void setArtifactId(String artifactId) {
+        this.artifactId = artifactId;
+    }
+
+    public String getVersionId() {
+        return versionId;
+    }
+
+    public void setVersionId(String versionId) {
+        this.versionId = versionId;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public boolean isConsumerOnly() {
+        return consumerOnly;
+    }
+
+    public void setConsumerOnly(boolean consumerOnly) {
+        this.consumerOnly = consumerOnly;
+    }
+
+    public boolean isProducerOnly() {
+        return producerOnly;
+    }
+
+    public void setProducerOnly(boolean producerOnly) {
+        this.producerOnly = producerOnly;
+    }
+}