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/31 08:59:31 UTC
[1/2] 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.
Repository: camel
Updated Branches:
refs/heads/master 4c130488c -> 92a351e34
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/e5bdc179
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e5bdc179
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e5bdc179
Branch: refs/heads/master
Commit: e5bdc179bf7887dff79f814f91791c1a9bb593b9
Parents: 4c13048
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Dec 31 08:35:16 2014 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Dec 31 08:35:16 2014 +0100
----------------------------------------------------------------------
.../camel/tools/apt/EipAnnotationProcessor.java | 708 +++++++++++++++++++
.../ModelDocumentationAnnotationProcessor.java | 708 -------------------
.../javax.annotation.processing.Processor | 2 +-
3 files changed, 709 insertions(+), 709 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/e5bdc179/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
new file mode 100644
index 0000000..8805c1b
--- /dev/null
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java
@@ -0,0 +1,708 @@
+/**
+ * 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.PrintWriter;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.spi.Label;
+
+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;
+
+// TODO: figure out a way to specify default value in the model classes which this APT can read
+
+// TODO: add support for @XmlElements which a few EIPs uses such as resequence
+//@XmlElements({
+// @XmlElement(name = "batch-config", type = BatchResequencerConfig.class),
+// @XmlElement(name = "stream-config", type = StreamResequencerConfig.class)}
+//)
+
+
+/**
+ * Process all camel-core's model classes (EIPs and DSL) and generate json schema documentation
+ */
+@SupportedAnnotationTypes({"javax.xml.bind.annotation.*", "org.apache.camel.spi.Label"})
+@SupportedSourceVersion(SourceVersion.RELEASE_7)
+public class EipAnnotationProcessor extends AbstractAnnotationProcessor {
+
+ // special when using expression/predicates in the model
+ private static final String ONE_OF_TYPE_NAME = "org.apache.camel.model.ExpressionSubElementDefinition";
+ private static final String ONE_OF_LANGUAGES = "org.apache.camel.model.language.ExpressionDefinition";
+ // special for outputs (these classes have sub classes, so we use this to find all classes)
+ private static final String[] ONE_OF_OUTPUTS = new String[]{
+ "org.apache.camel.model.ProcessorDefinition",
+ "org.apache.camel.model.NoOutputDefinition",
+ "org.apache.camel.model.OutputDefinition",
+ "org.apache.camel.model.ExpressionNode",
+ "org.apache.camel.model.NoOutputExpressionNode",
+ "org.apache.camel.model.SendDefinition",
+ "org.apache.camel.model.InterceptDefinition",
+ "org.apache.camel.model.WhenDefinition",
+ };
+
+ private boolean skipUnwanted = true;
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
+ return true;
+ }
+
+ Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(XmlRootElement.class);
+ for (Element element : elements) {
+ if (element instanceof TypeElement) {
+ processModelClass(roundEnv, (TypeElement) element);
+ }
+ }
+ return true;
+ }
+
+ protected void processModelClass(final RoundEnvironment roundEnv, final TypeElement classElement) {
+ // must be from org.apache.camel.model
+ final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
+ String packageName = javaTypeName.substring(0, javaTypeName.lastIndexOf("."));
+ if (!javaTypeName.startsWith("org.apache.camel.model")) {
+ return;
+ }
+
+ // skip abstract classes
+ if (classElement.getModifiers().contains(Modifier.ABSTRACT)) {
+ return;
+ }
+
+ // skip unwanted classes which are "abstract" holders
+ if (skipUnwanted) {
+ if (classElement.getQualifiedName().toString().equals(ONE_OF_TYPE_NAME)) {
+ return;
+ }
+ }
+
+ final XmlRootElement rootElement = classElement.getAnnotation(XmlRootElement.class);
+ String aName = rootElement.name();
+ if (isNullOrEmpty(aName) || "##default".equals(aName)) {
+ XmlType typeElement = classElement.getAnnotation(XmlType.class);
+ aName = typeElement.name();
+ }
+ final String name = aName;
+
+ // lets use the xsd name as the file name
+ String fileName;
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ fileName = classElement.getSimpleName().toString() + ".json";
+ } else {
+ fileName = name + ".json";
+ }
+
+ // write json schema
+ Func1<PrintWriter, Void> handler = new Func1<PrintWriter, Void>() {
+ @Override
+ public Void call(PrintWriter writer) {
+ writeJSonSchemeDocumentation(writer, roundEnv, classElement, rootElement, javaTypeName, name);
+ return null;
+ }
+ };
+ processFile(packageName, fileName, handler);
+ }
+
+ protected void writeJSonSchemeDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, XmlRootElement rootElement,
+ String javaTypeName, String name) {
+ // gather eip information
+ EipModel eipModel = findEipModelProperties(roundEnv, classElement, javaTypeName, name);
+
+ // get endpoint information which is divided into paths and options (though there should really only be one path)
+ Set<EipOption> eipOptions = new LinkedHashSet<EipOption>();
+ findClassProperties(writer, roundEnv, eipOptions, classElement, classElement, "");
+
+ String json = createParameterJsonSchema(eipModel, eipOptions);
+ writer.println(json);
+ }
+
+ public String createParameterJsonSchema(EipModel eipModel, Set<EipOption> options) {
+ StringBuilder buffer = new StringBuilder("{");
+ // eip model
+ buffer.append("\n \"model\": {");
+ buffer.append("\n \"name\": \"").append(eipModel.getName()).append("\",");
+ buffer.append("\n \"description\": \"").append(safeNull(eipModel.getDescription())).append("\",");
+ buffer.append("\n \"javaType\": \"").append(eipModel.getJavaType()).append("\",");
+ buffer.append("\n \"label\": \"").append(safeNull(eipModel.getLabel())).append("\",");
+ buffer.append("\n },");
+
+ buffer.append("\n \"properties\": {");
+ boolean first = true;
+ for (EipOption entry : options) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.append(",");
+ }
+ buffer.append("\n ");
+ // as its json we need to sanitize the docs
+ String doc = entry.getDocumentation();
+ doc = sanitizeDescription(doc, false);
+ buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc,
+ entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes()));
+ }
+ buffer.append("\n }");
+
+ buffer.append("\n}\n");
+ return buffer.toString();
+ }
+
+ protected EipModel findEipModelProperties(RoundEnvironment roundEnv, TypeElement classElement, String javaTypeName, String name) {
+ EipModel model = new EipModel();
+ model.setJavaType(javaTypeName);
+ model.setName(name);
+
+ Label label = classElement.getAnnotation(Label.class);
+ if (label != null) {
+ model.setLabel(label.value());
+ }
+
+ // favor to use class javadoc of component as description
+ if (model.getJavaType() != null) {
+ Elements elementUtils = processingEnv.getElementUtils();
+ TypeElement typeElement = findTypeElement(roundEnv, model.getJavaType());
+ if (typeElement != null) {
+ String doc = elementUtils.getDocComment(typeElement);
+ if (doc != null) {
+ // need to sanitize the description first (we only want a summary)
+ doc = sanitizeDescription(doc, true);
+ // the javadoc may actually be empty, so only change the doc if we got something
+ if (!Strings.isNullOrEmpty(doc)) {
+ model.setDescription(doc);
+ }
+ }
+ }
+ }
+
+ return model;
+ }
+
+ protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, Set<EipOption> eipOptions,
+ TypeElement originalClassType, TypeElement classElement, String prefix) {
+ Elements elementUtils = processingEnv.getElementUtils();
+ while (true) {
+ List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
+ for (VariableElement fieldElement : fieldElements) {
+
+ XmlAttribute attribute = fieldElement.getAnnotation(XmlAttribute.class);
+ String fieldName = fieldElement.getSimpleName().toString();
+ if (attribute != null) {
+ String name = attribute.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+
+ // lets skip some unwanted attributes
+ if (skipUnwanted) {
+ // we want to skip inheritErrorHandler which is only applicable for the load-balancer
+ boolean loadBalancer = "LoadBalanceDefinition".equals(originalClassType.getSimpleName().toString());
+ if (!loadBalancer && "inheritErrorHandler".equals(name)) {
+ continue;
+ }
+ }
+
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+ TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
+
+ String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
+ boolean required = attribute.required();
+
+ // gather enums
+ Set<String> enums = new TreeSet<String>();
+ boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
+ if (isEnum) {
+ TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
+ // find all the enum constants which has the possible enum value that can be used
+ List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+ for (VariableElement var : fields) {
+ if (var.getKind() == ElementKind.ENUM_CONSTANT) {
+ String val = var.toString();
+ enums.add(val);
+ }
+ }
+ }
+
+ EipOption ep = new EipOption(name, "attribute", fieldTypeName, required, "", docComment, isEnum, enums, false, null);
+ eipOptions.add(ep);
+ }
+
+ XmlElement element = fieldElement.getAnnotation(XmlElement.class);
+ fieldName = fieldElement.getSimpleName().toString();
+ if (element != null) {
+ String kind = "element";
+ String name = element.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+ TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
+
+ String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
+ boolean required = element.required();
+
+ // gather enums
+ Set<String> enums = new LinkedHashSet<String>();
+ boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
+ if (isEnum) {
+ TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
+ // find all the enum constants which has the possible enum value that can be used
+ List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+ for (VariableElement var : fields) {
+ if (var.getKind() == ElementKind.ENUM_CONSTANT) {
+ String val = var.toString();
+ enums.add(val);
+ }
+ }
+ }
+
+ // gather oneOf expression/predicates which uses language
+ Set<String> oneOfTypes = new TreeSet<String>();
+ boolean isOneOf = ONE_OF_TYPE_NAME.equals(fieldTypeName);
+ if (isOneOf) {
+ TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
+ String superClassName = canonicalClassName(languages.toString());
+ // find all classes that has that superClassName
+ Set<TypeElement> children = new LinkedHashSet<TypeElement>();
+ findTypeElementChildren(roundEnv, children, superClassName);
+ for (TypeElement child : children) {
+ XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
+ if (rootElement != null) {
+ String childName = rootElement.name();
+ if (childName != null) {
+ oneOfTypes.add(childName);
+ }
+ }
+ }
+ }
+
+ EipOption ep = new EipOption(name, kind, fieldTypeName, required, "", docComment, isEnum, enums, isOneOf, oneOfTypes);
+ eipOptions.add(ep);
+ }
+
+ // special for eips which has outputs or requires an expressions
+ XmlElementRef elementRef = fieldElement.getAnnotation(XmlElementRef.class);
+ fieldName = fieldElement.getSimpleName().toString();
+ if (elementRef != null) {
+
+ // special for outputs
+ processOutputs(roundEnv, originalClassType, elementRef, fieldElement, fieldName, eipOptions, prefix);
+
+ // special for expression
+ processExpression(roundEnv, elementRef, fieldElement, fieldName, eipOptions, prefix);
+ }
+ }
+
+ // 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();
+ if (superclass != null) {
+ String superClassName = canonicalClassName(superclass.toString());
+ baseTypeElement = findTypeElement(roundEnv, superClassName);
+ }
+ if (baseTypeElement != null) {
+ classElement = baseTypeElement;
+ } else {
+ break;
+ }
+ }
+ }
+
+ 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, null, "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, null, "description", classElement, true);
+ ep = new EipOption("description", "element", "org.apache.camel.model.DescriptionDefinition", false, "", docComment, false, null, false, null);
+ eipOptions.add(ep);
+
+ // lets skip custom id as it has no value for end users to configure
+ if (!skipUnwanted) {
+ // custom id
+ docComment = findJavaDoc(elementUtils, null, "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
+ */
+ private void processExpression(RoundEnvironment roundEnv, XmlElementRef elementRef, VariableElement fieldElement,
+ String fieldName, Set<EipOption> eipOptions, String prefix) {
+ if ("expression".equals(fieldName)) {
+ String kind = "element";
+ String name = elementRef.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+
+ // gather oneOf expression/predicates which uses language
+ Set<String> oneOfTypes = new TreeSet<String>();
+ TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
+ String superClassName = canonicalClassName(languages.toString());
+ // find all classes that has that superClassName
+ Set<TypeElement> children = new LinkedHashSet<TypeElement>();
+ findTypeElementChildren(roundEnv, children, superClassName);
+ for (TypeElement child : children) {
+ XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
+ if (rootElement != null) {
+ String childName = rootElement.name();
+ if (childName != null) {
+ oneOfTypes.add(childName);
+ }
+ }
+ }
+
+ EipOption ep = new EipOption(name, kind, fieldTypeName, true, "", "", false, null, true, oneOfTypes);
+ eipOptions.add(ep);
+ }
+ }
+
+ /**
+ * Special for processing an @XmlElementRef outputs field
+ */
+ private void processOutputs(RoundEnvironment roundEnv, TypeElement originalClassType, XmlElementRef elementRef,
+ VariableElement fieldElement, String fieldName, Set<EipOption> eipOptions, String prefix) {
+ if ("outputs".equals(fieldName) && supportOutputs(originalClassType)) {
+ String kind = "element";
+ String name = elementRef.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+
+ // gather oneOf which extends any of the output base classes
+ Set<String> 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");
+
+ EipOption ep = new EipOption(name, kind, fieldTypeName, true, "", "", false, null, true, oneOfTypes);
+ eipOptions.add(ep);
+ }
+ }
+
+ /**
+ * Whether the class supports outputs.
+ * <p/>
+ * There are some classes which does not support outputs, even though they have a outputs element.
+ */
+ private boolean supportOutputs(TypeElement classElement) {
+ String superclass = canonicalClassName(classElement.getSuperclass().toString());
+ return !"org.apache.camel.model.NoOutputExpressionNode".equals(superclass);
+ }
+
+ private static final class EipModel {
+
+ private String name;
+ private String javaType;
+ private String label;
+ private String description;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ }
+
+ private static final class EipOption {
+
+ private String name;
+ private String kind;
+ private String type;
+ private boolean required;
+ private String defaultValue;
+ private String documentation;
+ private boolean enumType;
+ private Set<String> enums;
+ private boolean oneOf;
+ private Set<String> oneOfTypes;
+
+ private EipOption(String name, String kind, String type, boolean required, String defaultValue, String documentation,
+ boolean enumType, Set<String> enums, boolean oneOf, Set<String> oneOfTypes) {
+ this.name = name;
+ this.kind = kind;
+ this.type = type;
+ this.required = required;
+ this.defaultValue = defaultValue;
+ this.documentation = documentation;
+ this.enumType = enumType;
+ this.enums = enums;
+ this.oneOf = oneOf;
+ this.oneOfTypes = oneOfTypes;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public String getDocumentation() {
+ return documentation;
+ }
+
+ public boolean isEnumType() {
+ return enumType;
+ }
+
+ public Set<String> getEnums() {
+ return enums;
+ }
+
+ public boolean isOneOf() {
+ return oneOf;
+ }
+
+ public Set<String> getOneOfTypes() {
+ return oneOfTypes;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ EipOption that = (EipOption) o;
+
+ if (!name.equals(that.name)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/e5bdc179/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
deleted file mode 100644
index 7015061..0000000
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ModelDocumentationAnnotationProcessor.java
+++ /dev/null
@@ -1,708 +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.PrintWriter;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.Elements;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-import org.apache.camel.spi.Label;
-
-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;
-
-// TODO: figure out a way to specify default value in the model classes which this APT can read
-
-// TODO: add support for @XmlElements which a few EIPs uses such as resequence
-//@XmlElements({
-// @XmlElement(name = "batch-config", type = BatchResequencerConfig.class),
-// @XmlElement(name = "stream-config", type = StreamResequencerConfig.class)}
-//)
-
-
-/**
- * Process all camel-core's model classes (EIPs and DSL) and generate json schema documentation
- */
-@SupportedAnnotationTypes({"javax.xml.bind.annotation.*", "org.apache.camel.spi.Label"})
-@SupportedSourceVersion(SourceVersion.RELEASE_7)
-public class ModelDocumentationAnnotationProcessor extends AbstractAnnotationProcessor {
-
- // special when using expression/predicates in the model
- private static final String ONE_OF_TYPE_NAME = "org.apache.camel.model.ExpressionSubElementDefinition";
- private static final String ONE_OF_LANGUAGES = "org.apache.camel.model.language.ExpressionDefinition";
- // special for outputs (these classes have sub classes, so we use this to find all classes)
- private static final String[] ONE_OF_OUTPUTS = new String[]{
- "org.apache.camel.model.ProcessorDefinition",
- "org.apache.camel.model.NoOutputDefinition",
- "org.apache.camel.model.OutputDefinition",
- "org.apache.camel.model.ExpressionNode",
- "org.apache.camel.model.NoOutputExpressionNode",
- "org.apache.camel.model.SendDefinition",
- "org.apache.camel.model.InterceptDefinition",
- "org.apache.camel.model.WhenDefinition",
- };
-
- private boolean skipUnwanted = true;
-
- @Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- if (roundEnv.processingOver()) {
- return true;
- }
-
- Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(XmlRootElement.class);
- for (Element element : elements) {
- if (element instanceof TypeElement) {
- processModelClass(roundEnv, (TypeElement) element);
- }
- }
- return true;
- }
-
- protected void processModelClass(final RoundEnvironment roundEnv, final TypeElement classElement) {
- // must be from org.apache.camel.model
- final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString());
- String packageName = javaTypeName.substring(0, javaTypeName.lastIndexOf("."));
- if (!javaTypeName.startsWith("org.apache.camel.model")) {
- return;
- }
-
- // skip abstract classes
- if (classElement.getModifiers().contains(Modifier.ABSTRACT)) {
- return;
- }
-
- // skip unwanted classes which are "abstract" holders
- if (skipUnwanted) {
- if (classElement.getQualifiedName().toString().equals(ONE_OF_TYPE_NAME)) {
- return;
- }
- }
-
- final XmlRootElement rootElement = classElement.getAnnotation(XmlRootElement.class);
- String aName = rootElement.name();
- if (isNullOrEmpty(aName) || "##default".equals(aName)) {
- XmlType typeElement = classElement.getAnnotation(XmlType.class);
- aName = typeElement.name();
- }
- final String name = aName;
-
- // lets use the xsd name as the file name
- String fileName;
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- fileName = classElement.getSimpleName().toString() + ".json";
- } else {
- fileName = name + ".json";
- }
-
- // write json schema
- Func1<PrintWriter, Void> handler = new Func1<PrintWriter, Void>() {
- @Override
- public Void call(PrintWriter writer) {
- writeJSonSchemeDocumentation(writer, roundEnv, classElement, rootElement, javaTypeName, name);
- return null;
- }
- };
- processFile(packageName, fileName, handler);
- }
-
- protected void writeJSonSchemeDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, XmlRootElement rootElement,
- String javaTypeName, String name) {
- // gather eip information
- EipModel eipModel = findEipModelProperties(roundEnv, classElement, javaTypeName, name);
-
- // get endpoint information which is divided into paths and options (though there should really only be one path)
- Set<EipOption> eipOptions = new LinkedHashSet<EipOption>();
- findClassProperties(writer, roundEnv, eipOptions, classElement, classElement, "");
-
- String json = createParameterJsonSchema(eipModel, eipOptions);
- writer.println(json);
- }
-
- public String createParameterJsonSchema(EipModel eipModel, Set<EipOption> options) {
- StringBuilder buffer = new StringBuilder("{");
- // eip model
- buffer.append("\n \"model\": {");
- buffer.append("\n \"name\": \"").append(eipModel.getName()).append("\",");
- buffer.append("\n \"description\": \"").append(safeNull(eipModel.getDescription())).append("\",");
- buffer.append("\n \"javaType\": \"").append(eipModel.getJavaType()).append("\",");
- buffer.append("\n \"label\": \"").append(safeNull(eipModel.getLabel())).append("\",");
- buffer.append("\n },");
-
- buffer.append("\n \"properties\": {");
- boolean first = true;
- for (EipOption entry : options) {
- if (first) {
- first = false;
- } else {
- buffer.append(",");
- }
- buffer.append("\n ");
- // as its json we need to sanitize the docs
- String doc = entry.getDocumentation();
- doc = sanitizeDescription(doc, false);
- buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc,
- entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes()));
- }
- buffer.append("\n }");
-
- buffer.append("\n}\n");
- return buffer.toString();
- }
-
- protected EipModel findEipModelProperties(RoundEnvironment roundEnv, TypeElement classElement, String javaTypeName, String name) {
- EipModel model = new EipModel();
- model.setJavaType(javaTypeName);
- model.setName(name);
-
- Label label = classElement.getAnnotation(Label.class);
- if (label != null) {
- model.setLabel(label.value());
- }
-
- // favor to use class javadoc of component as description
- if (model.getJavaType() != null) {
- Elements elementUtils = processingEnv.getElementUtils();
- TypeElement typeElement = findTypeElement(roundEnv, model.getJavaType());
- if (typeElement != null) {
- String doc = elementUtils.getDocComment(typeElement);
- if (doc != null) {
- // need to sanitize the description first (we only want a summary)
- doc = sanitizeDescription(doc, true);
- // the javadoc may actually be empty, so only change the doc if we got something
- if (!Strings.isNullOrEmpty(doc)) {
- model.setDescription(doc);
- }
- }
- }
- }
-
- return model;
- }
-
- protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, Set<EipOption> eipOptions,
- TypeElement originalClassType, TypeElement classElement, String prefix) {
- Elements elementUtils = processingEnv.getElementUtils();
- while (true) {
- List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
- for (VariableElement fieldElement : fieldElements) {
-
- XmlAttribute attribute = fieldElement.getAnnotation(XmlAttribute.class);
- String fieldName = fieldElement.getSimpleName().toString();
- if (attribute != null) {
- String name = attribute.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
-
- // lets skip some unwanted attributes
- if (skipUnwanted) {
- // we want to skip inheritErrorHandler which is only applicable for the load-balancer
- boolean loadBalancer = "LoadBalanceDefinition".equals(originalClassType.getSimpleName().toString());
- if (!loadBalancer && "inheritErrorHandler".equals(name)) {
- continue;
- }
- }
-
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
- TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
-
- String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
- boolean required = attribute.required();
-
- // gather enums
- Set<String> enums = new TreeSet<String>();
- boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
- if (isEnum) {
- TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
- // find all the enum constants which has the possible enum value that can be used
- List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
- for (VariableElement var : fields) {
- if (var.getKind() == ElementKind.ENUM_CONSTANT) {
- String val = var.toString();
- enums.add(val);
- }
- }
- }
-
- EipOption ep = new EipOption(name, "attribute", fieldTypeName, required, "", docComment, isEnum, enums, false, null);
- eipOptions.add(ep);
- }
-
- XmlElement element = fieldElement.getAnnotation(XmlElement.class);
- fieldName = fieldElement.getSimpleName().toString();
- if (element != null) {
- String kind = "element";
- String name = element.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
- TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
-
- String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
- boolean required = element.required();
-
- // gather enums
- Set<String> enums = new LinkedHashSet<String>();
- boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
- if (isEnum) {
- TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
- // find all the enum constants which has the possible enum value that can be used
- List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
- for (VariableElement var : fields) {
- if (var.getKind() == ElementKind.ENUM_CONSTANT) {
- String val = var.toString();
- enums.add(val);
- }
- }
- }
-
- // gather oneOf expression/predicates which uses language
- Set<String> oneOfTypes = new TreeSet<String>();
- boolean isOneOf = ONE_OF_TYPE_NAME.equals(fieldTypeName);
- if (isOneOf) {
- TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
- String superClassName = canonicalClassName(languages.toString());
- // find all classes that has that superClassName
- Set<TypeElement> children = new LinkedHashSet<TypeElement>();
- findTypeElementChildren(roundEnv, children, superClassName);
- for (TypeElement child : children) {
- XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
- if (rootElement != null) {
- String childName = rootElement.name();
- if (childName != null) {
- oneOfTypes.add(childName);
- }
- }
- }
- }
-
- EipOption ep = new EipOption(name, kind, fieldTypeName, required, "", docComment, isEnum, enums, isOneOf, oneOfTypes);
- eipOptions.add(ep);
- }
-
- // special for eips which has outputs or requires an expressions
- XmlElementRef elementRef = fieldElement.getAnnotation(XmlElementRef.class);
- fieldName = fieldElement.getSimpleName().toString();
- if (elementRef != null) {
-
- // special for outputs
- processOutputs(roundEnv, originalClassType, elementRef, fieldElement, fieldName, eipOptions, prefix);
-
- // special for expression
- processExpression(roundEnv, elementRef, fieldElement, fieldName, eipOptions, prefix);
- }
- }
-
- // 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();
- if (superclass != null) {
- String superClassName = canonicalClassName(superclass.toString());
- baseTypeElement = findTypeElement(roundEnv, superClassName);
- }
- if (baseTypeElement != null) {
- classElement = baseTypeElement;
- } else {
- break;
- }
- }
- }
-
- 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, null, "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, null, "description", classElement, true);
- ep = new EipOption("description", "element", "org.apache.camel.model.DescriptionDefinition", false, "", docComment, false, null, false, null);
- eipOptions.add(ep);
-
- // lets skip custom id as it has no value for end users to configure
- if (!skipUnwanted) {
- // custom id
- docComment = findJavaDoc(elementUtils, null, "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
- */
- private void processExpression(RoundEnvironment roundEnv, XmlElementRef elementRef, VariableElement fieldElement,
- String fieldName, Set<EipOption> eipOptions, String prefix) {
- if ("expression".equals(fieldName)) {
- String kind = "element";
- String name = elementRef.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
-
- // gather oneOf expression/predicates which uses language
- Set<String> oneOfTypes = new TreeSet<String>();
- TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
- String superClassName = canonicalClassName(languages.toString());
- // find all classes that has that superClassName
- Set<TypeElement> children = new LinkedHashSet<TypeElement>();
- findTypeElementChildren(roundEnv, children, superClassName);
- for (TypeElement child : children) {
- XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
- if (rootElement != null) {
- String childName = rootElement.name();
- if (childName != null) {
- oneOfTypes.add(childName);
- }
- }
- }
-
- EipOption ep = new EipOption(name, kind, fieldTypeName, true, "", "", false, null, true, oneOfTypes);
- eipOptions.add(ep);
- }
- }
-
- /**
- * Special for processing an @XmlElementRef outputs field
- */
- private void processOutputs(RoundEnvironment roundEnv, TypeElement originalClassType, XmlElementRef elementRef,
- VariableElement fieldElement, String fieldName, Set<EipOption> eipOptions, String prefix) {
- if ("outputs".equals(fieldName) && supportOutputs(originalClassType)) {
- String kind = "element";
- String name = elementRef.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
-
- // gather oneOf which extends any of the output base classes
- Set<String> 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");
-
- EipOption ep = new EipOption(name, kind, fieldTypeName, true, "", "", false, null, true, oneOfTypes);
- eipOptions.add(ep);
- }
- }
-
- /**
- * Whether the class supports outputs.
- * <p/>
- * There are some classes which does not support outputs, even though they have a outputs element.
- */
- private boolean supportOutputs(TypeElement classElement) {
- String superclass = canonicalClassName(classElement.getSuperclass().toString());
- return !"org.apache.camel.model.NoOutputExpressionNode".equals(superclass);
- }
-
- private static final class EipModel {
-
- private String name;
- private String javaType;
- private String label;
- private String description;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getJavaType() {
- return javaType;
- }
-
- public void setJavaType(String javaType) {
- this.javaType = javaType;
- }
-
- public String getLabel() {
- return label;
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
- }
-
- private static final class EipOption {
-
- private String name;
- private String kind;
- private String type;
- private boolean required;
- private String defaultValue;
- private String documentation;
- private boolean enumType;
- private Set<String> enums;
- private boolean oneOf;
- private Set<String> oneOfTypes;
-
- private EipOption(String name, String kind, String type, boolean required, String defaultValue, String documentation,
- boolean enumType, Set<String> enums, boolean oneOf, Set<String> oneOfTypes) {
- this.name = name;
- this.kind = kind;
- this.type = type;
- this.required = required;
- this.defaultValue = defaultValue;
- this.documentation = documentation;
- this.enumType = enumType;
- this.enums = enums;
- this.oneOf = oneOf;
- this.oneOfTypes = oneOfTypes;
- }
-
- public String getName() {
- return name;
- }
-
- public String getKind() {
- return kind;
- }
-
- public String getType() {
- return type;
- }
-
- public boolean isRequired() {
- return required;
- }
-
- public String getDefaultValue() {
- return defaultValue;
- }
-
- public String getDocumentation() {
- return documentation;
- }
-
- public boolean isEnumType() {
- return enumType;
- }
-
- public Set<String> getEnums() {
- return enums;
- }
-
- public boolean isOneOf() {
- return oneOf;
- }
-
- public Set<String> getOneOfTypes() {
- return oneOfTypes;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- EipOption that = (EipOption) o;
-
- if (!name.equals(that.name)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/e5bdc179/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
----------------------------------------------------------------------
diff --git a/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index 68f577f..5148414 100644
--- a/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -14,5 +14,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+org.apache.camel.tools.apt.EipAnnotationProcessor
org.apache.camel.tools.apt.EndpointAnnotationProcessor
-org.apache.camel.tools.apt.ModelDocumentationAnnotationProcessor
[2/2] 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.
Posted by da...@apache.org.
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/92a351e3
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/92a351e3
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/92a351e3
Branch: refs/heads/master
Commit: 92a351e34ab1759aa012449b5487b9a3b2ffaefa
Parents: e5bdc17
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Dec 31 08:58:23 2014 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Dec 31 08:58:23 2014 +0100
----------------------------------------------------------------------
.../apache/camel/model/MarshalDefinition.java | 9 +-
.../apache/camel/model/UnmarshalDefinition.java | 9 +-
.../camel/tools/apt/EipAnnotationProcessor.java | 244 +++++++++++--------
3 files changed, 157 insertions(+), 105 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/92a351e3/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java b/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
index ac317d2..b520d92 100644
--- a/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
@@ -71,11 +71,8 @@ import org.apache.camel.spi.RouteContext;
@XmlAccessorType(XmlAccessType.FIELD)
public class MarshalDefinition extends NoOutputDefinition<MarshalDefinition> {
- // TODO: Camel 3.0, ref attribute should be removed as RefDataFormat is to be used instead
+ // TODO: Camel 3.0, ref attribute should be removed as CustomDataFormat is to be used instead
- @XmlAttribute
- @Deprecated
- private String ref;
// cannot use @XmlElementRef as it doesn't allow optional properties
@XmlElements({
@XmlElement(required = false, name = "avro", type = AvroDataFormat.class),
@@ -113,6 +110,10 @@ public class MarshalDefinition extends NoOutputDefinition<MarshalDefinition> {
)
private DataFormatDefinition dataFormatType;
+ @XmlAttribute
+ @Deprecated
+ private String ref;
+
public MarshalDefinition() {
}
http://git-wip-us.apache.org/repos/asf/camel/blob/92a351e3/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java b/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
index 2d2a7b3..a4a91e5 100644
--- a/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
@@ -71,11 +71,8 @@ import org.apache.camel.spi.RouteContext;
@XmlAccessorType(XmlAccessType.FIELD)
public class UnmarshalDefinition extends NoOutputDefinition<UnmarshalDefinition> {
- // TODO: Camel 3.0, ref attribute should be removed as RefDataFormat is to be used instead
+ // TODO: Camel 3.0, ref attribute should be removed as UnmarshalDataFormat is to be used instead
- @XmlAttribute
- @Deprecated
- private String ref;
// cannot use @XmlElementRef as it doesn't allow optional properties
@XmlElements({
@XmlElement(required = false, name = "avro", type = AvroDataFormat.class),
@@ -113,6 +110,10 @@ public class UnmarshalDefinition extends NoOutputDefinition<UnmarshalDefinition>
)
private DataFormatDefinition dataFormatType;
+ @XmlAttribute
+ @Deprecated
+ private String ref;
+
public UnmarshalDefinition() {
}
http://git-wip-us.apache.org/repos/asf/camel/blob/92a351e3/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 8805c1b..a4aa927 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
@@ -36,6 +36,7 @@ import javax.lang.model.util.Elements;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@@ -48,12 +49,7 @@ import static org.apache.camel.tools.apt.Strings.safeNull;
// TODO: figure out a way to specify default value in the model classes which this APT can read
-// TODO: add support for @XmlElements which a few EIPs uses such as resequence
-//@XmlElements({
-// @XmlElement(name = "batch-config", type = BatchResequencerConfig.class),
-// @XmlElement(name = "stream-config", type = StreamResequencerConfig.class)}
-//)
-
+// TODO: add support for @deprecated
/**
* Process all camel-core's model classes (EIPs and DSL) and generate json schema documentation
@@ -217,113 +213,32 @@ public class EipAnnotationProcessor extends AbstractAnnotationProcessor {
protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, Set<EipOption> eipOptions,
TypeElement originalClassType, TypeElement classElement, String prefix) {
- Elements elementUtils = processingEnv.getElementUtils();
while (true) {
List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
for (VariableElement fieldElement : fieldElements) {
- XmlAttribute attribute = fieldElement.getAnnotation(XmlAttribute.class);
String fieldName = fieldElement.getSimpleName().toString();
- if (attribute != null) {
- String name = attribute.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
- // lets skip some unwanted attributes
- if (skipUnwanted) {
- // we want to skip inheritErrorHandler which is only applicable for the load-balancer
- boolean loadBalancer = "LoadBalanceDefinition".equals(originalClassType.getSimpleName().toString());
- if (!loadBalancer && "inheritErrorHandler".equals(name)) {
- continue;
- }
- }
-
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
- TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
-
- String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
- boolean required = attribute.required();
-
- // gather enums
- Set<String> enums = new TreeSet<String>();
- boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
- if (isEnum) {
- TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
- // find all the enum constants which has the possible enum value that can be used
- List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
- for (VariableElement var : fields) {
- if (var.getKind() == ElementKind.ENUM_CONSTANT) {
- String val = var.toString();
- enums.add(val);
- }
- }
+ XmlAttribute attribute = fieldElement.getAnnotation(XmlAttribute.class);
+ if (attribute != null) {
+ boolean skip = processAttribute(roundEnv, originalClassType, classElement, fieldElement, fieldName, attribute, eipOptions, prefix);
+ if (skip) {
+ continue;
}
+ }
- EipOption ep = new EipOption(name, "attribute", fieldTypeName, required, "", docComment, isEnum, enums, false, null);
- eipOptions.add(ep);
+ XmlElements elements = fieldElement.getAnnotation(XmlElements.class);
+ if (elements != null) {
+ processElements(roundEnv, classElement, elements, fieldElement, eipOptions, prefix);
}
XmlElement element = fieldElement.getAnnotation(XmlElement.class);
- fieldName = fieldElement.getSimpleName().toString();
if (element != null) {
- String kind = "element";
- String name = element.name();
- if (isNullOrEmpty(name) || "##default".equals(name)) {
- name = fieldName;
- }
- name = prefix + name;
- TypeMirror fieldType = fieldElement.asType();
- String fieldTypeName = fieldType.toString();
- TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
-
- String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
- boolean required = element.required();
-
- // gather enums
- Set<String> enums = new LinkedHashSet<String>();
- boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
- if (isEnum) {
- TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
- // find all the enum constants which has the possible enum value that can be used
- List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
- for (VariableElement var : fields) {
- if (var.getKind() == ElementKind.ENUM_CONSTANT) {
- String val = var.toString();
- enums.add(val);
- }
- }
- }
-
- // gather oneOf expression/predicates which uses language
- Set<String> oneOfTypes = new TreeSet<String>();
- boolean isOneOf = ONE_OF_TYPE_NAME.equals(fieldTypeName);
- if (isOneOf) {
- TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
- String superClassName = canonicalClassName(languages.toString());
- // find all classes that has that superClassName
- Set<TypeElement> children = new LinkedHashSet<TypeElement>();
- findTypeElementChildren(roundEnv, children, superClassName);
- for (TypeElement child : children) {
- XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
- if (rootElement != null) {
- String childName = rootElement.name();
- if (childName != null) {
- oneOfTypes.add(childName);
- }
- }
- }
- }
-
- EipOption ep = new EipOption(name, kind, fieldTypeName, required, "", docComment, isEnum, enums, isOneOf, oneOfTypes);
- eipOptions.add(ep);
+ processElement(roundEnv, classElement, element, fieldElement, eipOptions, prefix);
}
// special for eips which has outputs or requires an expressions
XmlElementRef elementRef = fieldElement.getAnnotation(XmlElementRef.class);
- fieldName = fieldElement.getSimpleName().toString();
if (elementRef != null) {
// special for outputs
@@ -356,6 +271,141 @@ public class EipAnnotationProcessor extends AbstractAnnotationProcessor {
}
}
+ private boolean processAttribute(RoundEnvironment roundEnv, TypeElement originalClassType, TypeElement classElement, VariableElement fieldElement, String fieldName, XmlAttribute attribute, Set<EipOption> eipOptions, String prefix) {
+ Elements elementUtils = processingEnv.getElementUtils();
+
+ String name = attribute.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+
+ // lets skip some unwanted attributes
+ if (skipUnwanted) {
+ // we want to skip inheritErrorHandler which is only applicable for the load-balancer
+ boolean loadBalancer = "LoadBalanceDefinition".equals(originalClassType.getSimpleName().toString());
+ if (!loadBalancer && "inheritErrorHandler".equals(name)) {
+ return true;
+ }
+ }
+
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+ TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
+
+ String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
+ boolean required = attribute.required();
+
+ // gather enums
+ Set<String> enums = new TreeSet<String>();
+ boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
+ if (isEnum) {
+ TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
+ // find all the enum constants which has the possible enum value that can be used
+ List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+ for (VariableElement var : fields) {
+ if (var.getKind() == ElementKind.ENUM_CONSTANT) {
+ String val = var.toString();
+ enums.add(val);
+ }
+ }
+ }
+
+ EipOption ep = new EipOption(name, "attribute", fieldTypeName, required, "", docComment, isEnum, enums, false, null);
+ eipOptions.add(ep);
+
+ return false;
+ }
+
+ private void processElement(RoundEnvironment roundEnv, TypeElement classElement, XmlElement element, VariableElement fieldElement,
+ Set<EipOption> eipOptions, String prefix) {
+ Elements elementUtils = processingEnv.getElementUtils();
+
+ String fieldName;
+ fieldName = fieldElement.getSimpleName().toString();
+ if (element != null) {
+ String kind = "element";
+ String name = element.name();
+ if (isNullOrEmpty(name) || "##default".equals(name)) {
+ name = fieldName;
+ }
+ name = prefix + name;
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+ TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
+
+ String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
+ boolean required = element.required();
+
+ // gather enums
+ Set<String> enums = new LinkedHashSet<String>();
+ boolean isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
+ if (isEnum) {
+ TypeElement enumClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString());
+ // find all the enum constants which has the possible enum value that can be used
+ List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+ for (VariableElement var : fields) {
+ if (var.getKind() == ElementKind.ENUM_CONSTANT) {
+ String val = var.toString();
+ enums.add(val);
+ }
+ }
+ }
+
+ // gather oneOf expression/predicates which uses language
+ Set<String> oneOfTypes = new TreeSet<String>();
+ boolean isOneOf = ONE_OF_TYPE_NAME.equals(fieldTypeName);
+ if (isOneOf) {
+ TypeElement languages = findTypeElement(roundEnv, ONE_OF_LANGUAGES);
+ String superClassName = canonicalClassName(languages.toString());
+ // find all classes that has that superClassName
+ Set<TypeElement> children = new LinkedHashSet<TypeElement>();
+ findTypeElementChildren(roundEnv, children, superClassName);
+ for (TypeElement child : children) {
+ XmlRootElement rootElement = child.getAnnotation(XmlRootElement.class);
+ if (rootElement != null) {
+ String childName = rootElement.name();
+ if (childName != null) {
+ oneOfTypes.add(childName);
+ }
+ }
+ }
+ }
+
+ EipOption ep = new EipOption(name, kind, fieldTypeName, required, "", docComment, isEnum, enums, isOneOf, oneOfTypes);
+ eipOptions.add(ep);
+ }
+ }
+
+ private void processElements(RoundEnvironment roundEnv, TypeElement classElement, XmlElements elements, VariableElement fieldElement,
+ Set<EipOption> eipOptions, String prefix) {
+ Elements elementUtils = processingEnv.getElementUtils();
+
+ String fieldName;
+ fieldName = fieldElement.getSimpleName().toString();
+ if (elements != null) {
+ String kind = "element";
+ String name = fieldName;
+ name = prefix + name;
+
+ TypeMirror fieldType = fieldElement.asType();
+ String fieldTypeName = fieldType.toString();
+
+ String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, classElement, true);
+ boolean required = true;
+
+ // gather oneOf of the elements
+ Set<String> oneOfTypes = new TreeSet<String>();
+ for (XmlElement element : elements.value()) {
+ String child = element.name();
+ oneOfTypes.add(child);
+ }
+
+ EipOption ep = new EipOption(name, kind, fieldTypeName, required, "", docComment, false, null, true, oneOfTypes);
+ eipOptions.add(ep);
+ }
+ }
+
private void processRoute(RoundEnvironment roundEnv, TypeElement originalClassType, TypeElement classElement,
Set<EipOption> eipOptions, String prefix) {