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 2014/12/30 11:42:31 UTC

[15/29] camel git commit: CAMEL-7999: apt compiler to generate json schema documentation for the model, whcih we later use to enrich the xml xsd to include documentation. Work in progress.

CAMEL-7999: apt compiler to generate json schema documentation for the model, whcih we later use to enrich the xml xsd to include documentation. Work in progress.


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

Branch: refs/heads/master
Commit: 3201b2168520359fc42e5e1f1e571a366b4c3731
Parents: 042abb9
Author: Claus Ibsen <da...@apache.org>
Authored: Sat Dec 27 12:04:18 2014 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Dec 30 10:56:43 2014 +0100

----------------------------------------------------------------------
 .../org/apache/camel/model/RouteDefinition.java | 121 +++++++++++++----
 .../tools/apt/AbstractAnnotationProcessor.java  |  26 +++-
 .../ModelDocumentationAnnotationProcessor.java  | 136 ++++++++++++++++++-
 3 files changed, 256 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/3201b216/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
index b1d90bb..3b35236 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -56,53 +56,34 @@ import org.apache.camel.util.ObjectHelper;
 /**
  * Represents an XML &lt;route/&gt; element
  *
- * @version 
+ * @version
  */
 @XmlRootElement(name = "route")
 @XmlType(propOrder = {"inputs", "outputs"})
-@XmlAccessorType(XmlAccessType.FIELD)
+@XmlAccessorType(XmlAccessType.PROPERTY)
+// must use XmlAccessType.PROPERTY as there is some custom logic needed to be executed in the setter methods
 public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
-    @XmlTransient
     private final AtomicBoolean prepared = new AtomicBoolean(false);
-    @XmlElementRef
     private List<FromDefinition> inputs = new ArrayList<FromDefinition>();
-    @XmlElementRef
     private List<ProcessorDefinition<?>> outputs = new ArrayList<ProcessorDefinition<?>>();
-    @XmlAttribute
     private String group;
-    @XmlAttribute
     private String streamCache;
-    @XmlAttribute
     private String trace;
-    @XmlAttribute
     private String messageHistory;
-    @XmlAttribute
     private String handleFault;
-    @XmlAttribute
     private String delayer;
-    @XmlAttribute
     private String autoStartup;
-    @XmlAttribute
     private Integer startupOrder;
-    @XmlTransient
     private List<RoutePolicy> routePolicies;
-    @XmlAttribute
     private String routePolicyRef;
-    @XmlAttribute
     private ShutdownRoute shutdownRoute;
-    @XmlAttribute
     private ShutdownRunningTask shutdownRunningTask;
-    @XmlAttribute
     private String errorHandlerRef;
-    @XmlTransient
     private ErrorHandlerFactory errorHandlerBuilder;
     // keep state whether the error handler is context scoped or not
     // (will by default be context scoped of no explicit error handler configured)
-    @XmlTransient
     private boolean contextScopedErrorHandler = true;
-    @XmlAttribute
     private Boolean rest;
-    @XmlTransient
     private RestDefinition restDefinition;
 
     public RouteDefinition() {
@@ -216,7 +197,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         ObjectHelper.notNull(camelContext, "CamelContext");
         return CamelContextHelper.getMandatoryEndpoint(camelContext, uri);
     }
-    
+
     @Deprecated
     public RouteDefinition adviceWith(CamelContext camelContext, RouteBuilder builder) throws Exception {
         return adviceWith((ModelCamelContext)camelContext, builder);
@@ -597,6 +578,10 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return inputs;
     }
 
+    /**
+     * Input to the route.
+     */
+    @XmlElementRef
     public void setInputs(List<FromDefinition> inputs) {
         this.inputs = inputs;
     }
@@ -605,6 +590,10 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return outputs;
     }
 
+    /**
+     * Outputs are processors that determines how messages are processed by this route.
+     */
+    @XmlElementRef
     public void setOutputs(List<ProcessorDefinition<?>> outputs) {
         this.outputs = outputs;
 
@@ -629,50 +618,95 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return group;
     }
 
+    /**
+     * The group that this route belongs to; could be the name of the RouteBuilder class
+     * or be explicitly configured in the XML.
+     * <p/>
+     * May be null.
+     */
+    @XmlAttribute
     public void setGroup(String group) {
         this.group = group;
     }
 
+    /**
+     * Whether stream caching is enabled on this route.
+     */
     public String getStreamCache() {
         return streamCache;
     }
 
+    /**
+     * Whether stream caching is enabled on this route.
+     */
+    @XmlAttribute
     public void setStreamCache(String streamCache) {
         this.streamCache = streamCache;
     }
 
+    /**
+     * Whether tracing is enabled on this route.
+     */
     public String getTrace() {
         return trace;
     }
 
+    /**
+     * Whether tracing is enabled on this route.
+     */
+    @XmlAttribute
     public void setTrace(String trace) {
         this.trace = trace;
     }
 
+    /**
+     * Whether message history is enabled on this route.
+     */
     public String getMessageHistory() {
         return messageHistory;
     }
 
+    /**
+     * Whether message history is enabled on this route.
+     */
+    @XmlAttribute
     public void setMessageHistory(String messageHistory) {
         this.messageHistory = messageHistory;
     }
 
+    /**
+     * Whether handle fault is enabled on this route.
+     */
     public String getHandleFault() {
         return handleFault;
     }
 
+    /**
+     * Whether handle fault is enabled on this route.
+     */
+    @XmlAttribute
     public void setHandleFault(String handleFault) {
         this.handleFault = handleFault;
     }
 
+    /**
+     * Whether to slow down processing messages by a given delay in msec.
+     */
     public String getDelayer() {
         return delayer;
     }
 
+    /**
+     * Whether to slow down processing messages by a given delay in msec.
+     */
+    @XmlAttribute
     public void setDelayer(String delayer) {
         this.delayer = delayer;
     }
 
+    /**
+     * Whether to auto start this route
+     */
     public String getAutoStartup() {
         return autoStartup;
     }
@@ -686,14 +720,25 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return isAutoStartup != null && isAutoStartup;
     }
 
+    /**
+     * Whether to auto start this route
+     */
+    @XmlAttribute
     public void setAutoStartup(String autoStartup) {
         this.autoStartup = autoStartup;
     }
 
+    /**
+     * To configure the ordering of the routes being started
+     */
     public Integer getStartupOrder() {
         return startupOrder;
     }
 
+    /**
+     * To configure the ordering of the routes being started
+     */
+    @XmlAttribute
     public void setStartupOrder(Integer startupOrder) {
         this.startupOrder = startupOrder;
     }
@@ -701,6 +746,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
     /**
      * Sets the bean ref name of the error handler builder to use on this route
      */
+    @XmlAttribute
     public void setErrorHandlerRef(String errorHandlerRef) {
         this.errorHandlerRef = errorHandlerRef;
         // we use an specific error handler ref (from Spring DSL) then wrap that
@@ -708,6 +754,9 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         setErrorHandlerBuilder(new ErrorHandlerBuilderRef(errorHandlerRef));
     }
 
+    /**
+     * Sets the bean ref name of the error handler builder to use on this route
+     */
     public String getErrorHandlerRef() {
         return errorHandlerRef;
     }
@@ -721,10 +770,19 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         }
     }
 
+    /**
+     * Reference to custom {@link org.apache.camel.spi.RoutePolicy} to use by the route.
+     * Multiple policies can be configured by separating values using comma.
+     */
+    @XmlAttribute
     public void setRoutePolicyRef(String routePolicyRef) {
         this.routePolicyRef = routePolicyRef;
     }
 
+    /**
+     * Reference to custom {@link org.apache.camel.spi.RoutePolicy} to use by the route.
+     * Multiple policies can be configured by separating values using comma.
+     */
     public String getRoutePolicyRef() {
         return routePolicyRef;
     }
@@ -733,6 +791,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return routePolicies;
     }
 
+    @XmlTransient
     public void setRoutePolicies(List<RoutePolicy> routePolicies) {
         this.routePolicies = routePolicies;
     }
@@ -741,18 +800,29 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return shutdownRoute;
     }
 
+    /**
+     * To control how to shutdown the route.
+     */
+    @XmlAttribute
     public void setShutdownRoute(ShutdownRoute shutdownRoute) {
         this.shutdownRoute = shutdownRoute;
     }
 
+    /**
+     * To control how to shutdown the route.
+     */
     public ShutdownRunningTask getShutdownRunningTask() {
         return shutdownRunningTask;
     }
 
+    /**
+     * To control how to shutdown the route.
+     */
+    @XmlAttribute
     public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
         this.shutdownRunningTask = shutdownRunningTask;
     }
-    
+
     private ErrorHandlerFactory createErrorHandlerBuilder() {
         if (errorHandlerRef != null) {
             return new ErrorHandlerBuilderRef(errorHandlerRef);
@@ -762,6 +832,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return new ErrorHandlerBuilderRef(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER);
     }
 
+    @XmlTransient
     public ErrorHandlerFactory getErrorHandlerBuilder() {
         if (errorHandlerBuilder == null) {
             errorHandlerBuilder = createErrorHandlerBuilder();
@@ -776,6 +847,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         this.errorHandlerBuilder = errorHandlerBuilder;
     }
 
+    @XmlAttribute
     public Boolean isRest() {
         return rest;
     }
@@ -784,6 +856,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
         return restDefinition;
     }
 
+    @XmlTransient
     public void setRestDefinition(RestDefinition restDefinition) {
         this.restDefinition = restDefinition;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/3201b216/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 169d182..66df71a 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
@@ -33,7 +33,6 @@ import javax.lang.model.element.Element;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.Elements;
@@ -51,7 +50,10 @@ import static org.apache.camel.tools.apt.Strings.isNullOrEmpty;
 public abstract class AbstractAnnotationProcessor extends AbstractProcessor {
 
     protected String findJavaDoc(Elements elementUtils, Element element, String fieldName, TypeElement classElement, boolean builderPattern) {
-        String answer = elementUtils.getDocComment(element);
+        String answer = null;
+        if (element != null) {
+            answer = elementUtils.getDocComment(element);
+        }
         if (isNullOrEmpty(answer)) {
             String setter = "set" + fieldName.substring(0, 1).toUpperCase();
             if (fieldName.length() > 1) {
@@ -175,6 +177,26 @@ public abstract class AbstractAnnotationProcessor extends AbstractProcessor {
         }
     }
 
+    protected boolean hasSuperClass(RoundEnvironment roundEnv, TypeElement classElement, String superClassName) {
+        String aRootName = canonicalClassName(classElement.getQualifiedName().toString());
+
+        if (isNullOrEmpty(aRootName) || "java.lang.Object".equals(aRootName)) {
+            return false;
+        }
+
+        String aSuperClassName = canonicalClassName(classElement.getSuperclass().toString());
+        if (superClassName.equals(aSuperClassName)) {
+            return true;
+        }
+
+        TypeElement aSuperClass = findTypeElement(roundEnv, aSuperClassName);
+        if (aSuperClass != null) {
+            return hasSuperClass(roundEnv, aSuperClass, superClassName);
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Helper method to produce class output text file using the given handler
      */

http://git-wip-us.apache.org/repos/asf/camel/blob/3201b216/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java
index 7846538..39afad6 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java
@@ -42,7 +42,6 @@ import static org.apache.camel.tools.apt.Strings.canonicalClassName;
 import static org.apache.camel.tools.apt.Strings.isNullOrEmpty;
 
 // TODO: add support for label so we can categorize the eips
-// TODO: add support for id/description which uses @XmlAttribute on methods
 
 /**
  * Process all camel-core's model classes (EIPs and DSL) and generate json schema documentation
@@ -288,6 +287,13 @@ public class ModelDocumentationAnnotationProcessor extends AbstractAnnotationPro
                 }
             }
 
+            // special when we process these nodes as they do not use JAXB annotations on fields, but on methods
+            if ("OptionalIdentifiedDefinition".equals(classElement.getSimpleName().toString())) {
+                processIdentified(roundEnv, originalClassType, classElement, eipOptions, prefix);
+            } else if ("RouteDefinition".equals(classElement.getSimpleName().toString())) {
+                processRoute(roundEnv, originalClassType, classElement, eipOptions, prefix);
+            }
+
             // check super classes which may also have fields
             TypeElement baseTypeElement = null;
             TypeMirror superclass = classElement.getSuperclass();
@@ -303,6 +309,134 @@ public class ModelDocumentationAnnotationProcessor extends AbstractAnnotationPro
         }
     }
 
+    private void processRoute(RoundEnvironment roundEnv, TypeElement originalClassType, TypeElement classElement,
+                              Set<EipOption> eipOptions, String prefix) {
+
+        Elements elementUtils = processingEnv.getElementUtils();
+
+        // group
+        String docComment = findJavaDoc(elementUtils, null, "group", classElement, true);
+        EipOption ep = new EipOption("group", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // group
+        docComment = findJavaDoc(elementUtils, null, "streamCache", classElement, true);
+        ep = new EipOption("streamCache", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // trace
+        docComment = findJavaDoc(elementUtils, null, "trace", classElement, true);
+        ep = new EipOption("trace", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // trace
+        docComment = findJavaDoc(elementUtils, null, "messageHistory", classElement, true);
+        ep = new EipOption("messageHistory", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // trace
+        docComment = findJavaDoc(elementUtils, null, "handleFault", classElement, true);
+        ep = new EipOption("handleFault", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // delayer
+        docComment = findJavaDoc(elementUtils, null, "delayer", classElement, true);
+        ep = new EipOption("delayer", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // autoStartup
+        docComment = findJavaDoc(elementUtils, null, "autoStartup", classElement, true);
+        ep = new EipOption("autoStartup", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // startupOrder
+        docComment = findJavaDoc(elementUtils, null, "startupOrder", classElement, true);
+        ep = new EipOption("startupOrder", "attribute", "java.lang.Integer", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // errorHandlerRef
+        docComment = findJavaDoc(elementUtils, null, "errorHandlerRef", classElement, true);
+        ep = new EipOption("errorHandlerRef", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // routePolicyRef
+        docComment = findJavaDoc(elementUtils, null, "routePolicyRef", classElement, true);
+        ep = new EipOption("routePolicyRef", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // shutdownRoute
+        Set<String> enums = new LinkedHashSet<String>();
+        enums.add("Default");
+        enums.add("Defer");
+        docComment = findJavaDoc(elementUtils, null, "shutdownRoute", classElement, true);
+        ep = new EipOption("shutdownRoute", "attribute", "org.apache.camel.ShutdownRoute", false, "", docComment, true, enums, false, null);
+        eipOptions.add(ep);
+
+        // shutdownRunningTask
+        enums = new LinkedHashSet<String>();
+        enums.add("CompleteCurrentTaskOnly");
+        enums.add("CompleteAllTasks");
+        docComment = findJavaDoc(elementUtils, null, "shutdownRunningTask", classElement, true);
+        ep = new EipOption("shutdownRunningTask", "attribute", "org.apache.camel.ShutdownRunningTask", false, "", docComment, true, enums, false, null);
+        eipOptions.add(ep);
+
+        // inputs
+        Set<String> oneOfTypes = new TreeSet<String>();
+        oneOfTypes.add("from");
+        docComment = findJavaDoc(elementUtils, null, "inputs", classElement, true);
+        ep = new EipOption("inputs", "element", "java.util.List<org.apache.camel.model.FromDefinition>", true, "", docComment, false, null, true, oneOfTypes);
+        eipOptions.add(ep);
+
+        // outputs
+        // gather oneOf which extends any of the output base classes
+        oneOfTypes = new TreeSet<String>();
+        // find all classes that has that superClassName
+        Set<TypeElement> children = new LinkedHashSet<TypeElement>();
+        for (String superclass : ONE_OF_OUTPUTS) {
+            findTypeElementChildren(roundEnv, children, superclass);
+        }
+        for (TypeElement child : children) {
+            XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
+            if (rootElement != null) {
+                String childName = rootElement.name();
+                if (childName != null) {
+                    oneOfTypes.add(childName);
+                }
+            }
+        }
+
+        // remove some types which are not intended as an output in eips
+        oneOfTypes.remove("route");
+
+        docComment = findJavaDoc(elementUtils, null, "outputs", classElement, true);
+        ep = new EipOption("outputs", "element", "java.util.List<org.apache.camel.model.ProcessorDefinition<?>>", true, "", docComment, false, null, true, oneOfTypes);
+        eipOptions.add(ep);
+    }
+
+    /**
+     * Special for process the OptionalIdentifiedDefinition
+     */
+    private void processIdentified(RoundEnvironment roundEnv, TypeElement originalClassType, TypeElement classElement,
+                                   Set<EipOption> eipOptions, String prefix) {
+
+        Elements elementUtils = processingEnv.getElementUtils();
+
+        // id
+        String docComment = findJavaDoc(elementUtils, classElement, "id", classElement, true);
+        EipOption ep = new EipOption("id", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // description
+        docComment = findJavaDoc(elementUtils, classElement, "description", classElement, true);
+        ep = new EipOption("description", "element", "org.apache.camel.model.DescriptionDefinition", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+
+        // custom id
+        docComment = findJavaDoc(elementUtils, classElement, "customId", classElement, true);
+        ep = new EipOption("customId", "attribute", "java.lang.String", false, "", docComment, false, null, false, null);
+        eipOptions.add(ep);
+    }
+
     /**
      * Special for processing an @XmlElementRef expression field
      */