CAMEL-9482: Adjust the apt to make camel-core compile again, seems like we need to merge the core/spring into a single apt as the compiler cannot do both on camel-core for some odd reason.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/8a18e284 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/8a18e284 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/8a18e284 Branch: refs/heads/master Commit: 8a18e2849b08898d51b84c59fd892691ac593a94 Parents: bbb7ff9 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Aug 11 09:41:27 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Aug 11 09:43:41 2016 +0200 ---------------------------------------------------------------------- .../tools/apt/AbstractAnnotationProcessor.java | 419 ------- .../tools/apt/AnnotationProcessorHelper.java | 421 +++++++ .../apt/CamelContextAnnotationProcessor.java | 720 ----------- .../tools/apt/CoreEipAnnotationProcessor.java | 1127 +++++++++++++++++ .../camel/tools/apt/EipAnnotationProcessor.java | 1148 ------------------ .../tools/apt/EndpointAnnotationProcessor.java | 45 +- .../tools/apt/ModelAnnotationProcessor.java | 71 ++ .../tools/apt/SpringAnnotationProcessor.java | 689 +++++++++++ .../javax.annotation.processing.Processor | 5 +- 9 files changed, 2338 insertions(+), 2307 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/8a18e284/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 deleted file mode 100644 index 6159602..0000000 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java +++ /dev/null @@ -1,419 +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.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.net.URI; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Filer; -import javax.annotation.processing.RoundEnvironment; -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.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.tools.Diagnostic; -import javax.tools.FileObject; -import javax.tools.StandardLocation; - -import static org.apache.camel.tools.apt.helper.IOHelper.loadText; -import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName; -import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty; - -/** - * Abstract class for Camel apt plugins. - */ -public abstract class AbstractAnnotationProcessor extends AbstractProcessor { - - protected String findJavaDoc(Elements elementUtils, Element element, String fieldName, String name, TypeElement classElement, boolean builderPattern) { - String answer = null; - if (element != null) { - answer = elementUtils.getDocComment(element); - } - if (isNullOrEmpty(answer)) { - ExecutableElement setter = findSetter(fieldName, classElement); - if (setter != null) { - String doc = elementUtils.getDocComment(setter); - if (!isNullOrEmpty(doc)) { - answer = doc; - } - } - - // lets find the getter - if (answer == null) { - ExecutableElement getter = findGetter(fieldName, classElement); - if (getter != null) { - String doc = elementUtils.getDocComment(getter); - if (!isNullOrEmpty(doc)) { - answer = doc; - } - } - } - - // lets try builder pattern - if (answer == null && builderPattern) { - List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); - // lets try the builder pattern using annotation name (optional) as the method name - if (name != null) { - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if (name.equals(methodName) && method.getParameters().size() == 1) { - String doc = elementUtils.getDocComment(method); - if (!isNullOrEmpty(doc)) { - answer = doc; - break; - } - } - } - // there may be builder pattern with no-parameter methods, such as more common for boolean types - // so lets try those as well - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if (name.equals(methodName) && method.getParameters().size() == 0) { - String doc = elementUtils.getDocComment(method); - if (!isNullOrEmpty(doc)) { - answer = doc; - break; - } - } - } - } - // lets try builder pattern using fieldName as the method name - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if (fieldName.equals(methodName) && method.getParameters().size() == 1) { - String doc = elementUtils.getDocComment(method); - if (!isNullOrEmpty(doc)) { - answer = doc; - break; - } - } - } - // there may be builder pattern with no-parameter methods, such as more common for boolean types - // so lets try those as well - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if (fieldName.equals(methodName) && method.getParameters().size() == 0) { - String doc = elementUtils.getDocComment(method); - if (!isNullOrEmpty(doc)) { - answer = doc; - break; - } - } - } - } - } - return answer; - } - - protected ExecutableElement findSetter(String fieldName, TypeElement classElement) { - String setter = "set" + fieldName.substring(0, 1).toUpperCase(); - if (fieldName.length() > 1) { - setter += fieldName.substring(1); - } - // lets find the setter - List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if (setter.equals(methodName) && method.getParameters().size() == 1 && method.getReturnType().getKind().equals(TypeKind.VOID)) { - return method; - } - } - - return null; - } - - protected ExecutableElement findGetter(String fieldName, TypeElement classElement) { - String getter1 = "get" + fieldName.substring(0, 1).toUpperCase(); - if (fieldName.length() > 1) { - getter1 += fieldName.substring(1); - } - String getter2 = "is" + fieldName.substring(0, 1).toUpperCase(); - if (fieldName.length() > 1) { - getter2 += fieldName.substring(1); - } - // lets find the getter - List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); - for (ExecutableElement method : methods) { - String methodName = method.getSimpleName().toString(); - if ((getter1.equals(methodName) || getter2.equals(methodName)) && method.getParameters().size() == 0) { - return method; - } - } - - return null; - } - - protected VariableElement findFieldElement(TypeElement classElement, String fieldName) { - if (isNullOrEmpty(fieldName)) { - return null; - } - - List<VariableElement> fields = ElementFilter.fieldsIn(classElement.getEnclosedElements()); - for (VariableElement field : fields) { - if (fieldName.equals(field.getSimpleName().toString())) { - return field; - } - } - - return null; - } - - protected TypeElement findTypeElement(RoundEnvironment roundEnv, String className) { - if (isNullOrEmpty(className) || "java.lang.Object".equals(className)) { - return null; - } - - Set<? extends Element> rootElements = roundEnv.getRootElements(); - for (Element rootElement : rootElements) { - if (rootElement instanceof TypeElement) { - TypeElement typeElement = (TypeElement) rootElement; - String aRootName = canonicalClassName(typeElement.getQualifiedName().toString()); - if (className.equals(aRootName)) { - return typeElement; - } - } - } - - // fallback using package name - Elements elementUtils = processingEnv.getElementUtils(); - - int idx = className.lastIndexOf('.'); - if (idx > 0) { - String packageName = className.substring(0, idx); - PackageElement pe = elementUtils.getPackageElement(packageName); - if (pe != null) { - List<? extends Element> enclosedElements = getEnclosedElements(pe); - for (Element rootElement : enclosedElements) { - if (rootElement instanceof TypeElement) { - TypeElement typeElement = (TypeElement) rootElement; - String aRootName = canonicalClassName(typeElement.getQualifiedName().toString()); - if (className.equals(aRootName)) { - return typeElement; - } - } - } - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private List<? extends Element> getEnclosedElements(PackageElement pe) { - // some components like hadoop/spark has bad classes that causes javac scanning issues - try { - return pe.getEnclosedElements(); - } catch (Throwable e) { - // ignore - } - return Collections.EMPTY_LIST; - } - - protected void findTypeElementChildren(RoundEnvironment roundEnv, Set<TypeElement> found, String superClassName) { - Elements elementUtils = processingEnv.getElementUtils(); - - int idx = superClassName.lastIndexOf('.'); - if (idx > 0) { - String packageName = superClassName.substring(0, idx); - PackageElement pe = elementUtils.getPackageElement(packageName); - if (pe != null) { - List<? extends Element> enclosedElements = pe.getEnclosedElements(); - for (Element rootElement : enclosedElements) { - if (rootElement instanceof TypeElement) { - TypeElement typeElement = (TypeElement) rootElement; - String aSuperClassName = canonicalClassName(typeElement.getSuperclass().toString()); - if (superClassName.equals(aSuperClassName)) { - found.add(typeElement); - } - } - } - } - } - } - - protected boolean hasSuperClass(RoundEnvironment roundEnv, TypeElement classElement, String superClassName) { - String aRootName = canonicalClassName(classElement.getQualifiedName().toString()); - - // do not check the classes from JDK itself - if (isNullOrEmpty(aRootName) || aRootName.startsWith("java.") || aRootName.startsWith("javax.")) { - 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; - } - } - - protected boolean implementsInterface(RoundEnvironment roundEnv, TypeElement classElement, String interfaceClassName) { - while (true) { - // check if the class implements the interface - List<? extends TypeMirror> list = classElement.getInterfaces(); - if (list != null) { - for (TypeMirror type : list) { - if (type.getKind().compareTo(TypeKind.DECLARED) == 0) { - String name = type.toString(); - if (interfaceClassName.equals(name)) { - return true; - } - } - } - } - - // check super classes which may implement the interface - 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; - } - } - - return false; - } - - /** - * Helper method to produce class output text file using the given handler - */ - protected void processFile(String packageName, String fileName, Func1<PrintWriter, Void> handler) { - PrintWriter writer = null; - try { - Writer out; - Filer filer = processingEnv.getFiler(); - FileObject resource; - try { - resource = filer.getResource(StandardLocation.CLASS_OUTPUT, packageName, fileName); - } catch (Throwable e) { - resource = filer.createResource(StandardLocation.CLASS_OUTPUT, packageName, fileName); - } - URI uri = resource.toUri(); - File file = null; - if (uri != null) { - try { - file = new File(uri.getPath()); - } catch (Exception e) { - warning("Could not convert output directory resource URI to a file " + e); - } - } - if (file == null) { - warning("No class output directory could be found!"); - } else { - file.getParentFile().mkdirs(); - out = new FileWriter(file); - writer = new PrintWriter(out); - handler.call(writer); - } - } catch (IOException e) { - log(e); - } finally { - if (writer != null) { - writer.close(); - } - } - } - - protected void log(String message) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message); - } - - protected void warning(String message) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, message); - } - - protected void error(String message) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message); - } - - protected void log(Throwable e) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - e.printStackTrace(writer); - writer.close(); - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, buffer.toString()); - } - - protected String loadResource(String packageName, String fileName) { - Filer filer = processingEnv.getFiler(); - - FileObject resource; - try { - resource = filer.getResource(StandardLocation.CLASS_OUTPUT, "", packageName + "/" + fileName); - } catch (Throwable e) { - return "Crap" + e.getMessage(); - } - - if (resource == null) { - return null; - } - - try { - InputStream is = resource.openInputStream(); - return loadText(is, true); - } catch (Exception e) { - warning("Could not load file"); - } - - return null; - } - - protected void dumpExceptionToErrorFile(String fileName, String message, Throwable e) { - File file = new File(fileName); - try { - FileOutputStream fos = new FileOutputStream(file); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - fos.write(message.getBytes()); - fos.write("\n\n".getBytes()); - fos.write(sw.toString().getBytes()); - pw.close(); - sw.close(); - fos.close(); - } catch (Throwable t) { - // ignore - } - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/8a18e284/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java new file mode 100644 index 0000000..ccbe807 --- /dev/null +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java @@ -0,0 +1,421 @@ +/** + * 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.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import javax.annotation.processing.Filer; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +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.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.util.Elements; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +import static org.apache.camel.tools.apt.helper.IOHelper.loadText; +import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName; +import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty; + +/** + * Abstract class for Camel apt plugins. + */ +public final class AnnotationProcessorHelper { + + private AnnotationProcessorHelper() { + } + + public static String findJavaDoc(Elements elementUtils, Element element, String fieldName, String name, TypeElement classElement, boolean builderPattern) { + String answer = null; + if (element != null) { + answer = elementUtils.getDocComment(element); + } + if (isNullOrEmpty(answer)) { + ExecutableElement setter = findSetter(fieldName, classElement); + if (setter != null) { + String doc = elementUtils.getDocComment(setter); + if (!isNullOrEmpty(doc)) { + answer = doc; + } + } + + // lets find the getter + if (answer == null) { + ExecutableElement getter = findGetter(fieldName, classElement); + if (getter != null) { + String doc = elementUtils.getDocComment(getter); + if (!isNullOrEmpty(doc)) { + answer = doc; + } + } + } + + // lets try builder pattern + if (answer == null && builderPattern) { + List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); + // lets try the builder pattern using annotation name (optional) as the method name + if (name != null) { + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (name.equals(methodName) && method.getParameters().size() == 1) { + String doc = elementUtils.getDocComment(method); + if (!isNullOrEmpty(doc)) { + answer = doc; + break; + } + } + } + // there may be builder pattern with no-parameter methods, such as more common for boolean types + // so lets try those as well + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (name.equals(methodName) && method.getParameters().size() == 0) { + String doc = elementUtils.getDocComment(method); + if (!isNullOrEmpty(doc)) { + answer = doc; + break; + } + } + } + } + // lets try builder pattern using fieldName as the method name + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (fieldName.equals(methodName) && method.getParameters().size() == 1) { + String doc = elementUtils.getDocComment(method); + if (!isNullOrEmpty(doc)) { + answer = doc; + break; + } + } + } + // there may be builder pattern with no-parameter methods, such as more common for boolean types + // so lets try those as well + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (fieldName.equals(methodName) && method.getParameters().size() == 0) { + String doc = elementUtils.getDocComment(method); + if (!isNullOrEmpty(doc)) { + answer = doc; + break; + } + } + } + } + } + return answer; + } + + public static ExecutableElement findSetter(String fieldName, TypeElement classElement) { + String setter = "set" + fieldName.substring(0, 1).toUpperCase(); + if (fieldName.length() > 1) { + setter += fieldName.substring(1); + } + // lets find the setter + List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (setter.equals(methodName) && method.getParameters().size() == 1 && method.getReturnType().getKind().equals(TypeKind.VOID)) { + return method; + } + } + + return null; + } + + public static ExecutableElement findGetter(String fieldName, TypeElement classElement) { + String getter1 = "get" + fieldName.substring(0, 1).toUpperCase(); + if (fieldName.length() > 1) { + getter1 += fieldName.substring(1); + } + String getter2 = "is" + fieldName.substring(0, 1).toUpperCase(); + if (fieldName.length() > 1) { + getter2 += fieldName.substring(1); + } + // lets find the getter + List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if ((getter1.equals(methodName) || getter2.equals(methodName)) && method.getParameters().size() == 0) { + return method; + } + } + + return null; + } + + public static VariableElement findFieldElement(TypeElement classElement, String fieldName) { + if (isNullOrEmpty(fieldName)) { + return null; + } + + List<VariableElement> fields = ElementFilter.fieldsIn(classElement.getEnclosedElements()); + for (VariableElement field : fields) { + if (fieldName.equals(field.getSimpleName().toString())) { + return field; + } + } + + return null; + } + + public static TypeElement findTypeElement(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv, String className) { + if (isNullOrEmpty(className) || "java.lang.Object".equals(className)) { + return null; + } + + Set<? extends Element> rootElements = roundEnv.getRootElements(); + for (Element rootElement : rootElements) { + if (rootElement instanceof TypeElement) { + TypeElement typeElement = (TypeElement) rootElement; + String aRootName = canonicalClassName(typeElement.getQualifiedName().toString()); + if (className.equals(aRootName)) { + return typeElement; + } + } + } + + // fallback using package name + Elements elementUtils = processingEnv.getElementUtils(); + + int idx = className.lastIndexOf('.'); + if (idx > 0) { + String packageName = className.substring(0, idx); + PackageElement pe = elementUtils.getPackageElement(packageName); + if (pe != null) { + List<? extends Element> enclosedElements = getEnclosedElements(pe); + for (Element rootElement : enclosedElements) { + if (rootElement instanceof TypeElement) { + TypeElement typeElement = (TypeElement) rootElement; + String aRootName = canonicalClassName(typeElement.getQualifiedName().toString()); + if (className.equals(aRootName)) { + return typeElement; + } + } + } + } + } + + return null; + } + + @SuppressWarnings("unchecked") + public static List<? extends Element> getEnclosedElements(PackageElement pe) { + // some components like hadoop/spark has bad classes that causes javac scanning issues + try { + return pe.getEnclosedElements(); + } catch (Throwable e) { + // ignore + } + return Collections.EMPTY_LIST; + } + + public static void findTypeElementChildren(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv, Set<TypeElement> found, String superClassName) { + Elements elementUtils = processingEnv.getElementUtils(); + + int idx = superClassName.lastIndexOf('.'); + if (idx > 0) { + String packageName = superClassName.substring(0, idx); + PackageElement pe = elementUtils.getPackageElement(packageName); + if (pe != null) { + List<? extends Element> enclosedElements = pe.getEnclosedElements(); + for (Element rootElement : enclosedElements) { + if (rootElement instanceof TypeElement) { + TypeElement typeElement = (TypeElement) rootElement; + String aSuperClassName = canonicalClassName(typeElement.getSuperclass().toString()); + if (superClassName.equals(aSuperClassName)) { + found.add(typeElement); + } + } + } + } + } + } + + public static boolean hasSuperClass(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv, TypeElement classElement, String superClassName) { + String aRootName = canonicalClassName(classElement.getQualifiedName().toString()); + + // do not check the classes from JDK itself + if (isNullOrEmpty(aRootName) || aRootName.startsWith("java.") || aRootName.startsWith("javax.")) { + return false; + } + + String aSuperClassName = canonicalClassName(classElement.getSuperclass().toString()); + if (superClassName.equals(aSuperClassName)) { + return true; + } + + TypeElement aSuperClass = findTypeElement(processingEnv, roundEnv, aSuperClassName); + if (aSuperClass != null) { + return hasSuperClass(processingEnv, roundEnv, aSuperClass, superClassName); + } else { + return false; + } + } + + public static boolean implementsInterface(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv, TypeElement classElement, String interfaceClassName) { + while (true) { + // check if the class implements the interface + List<? extends TypeMirror> list = classElement.getInterfaces(); + if (list != null) { + for (TypeMirror type : list) { + if (type.getKind().compareTo(TypeKind.DECLARED) == 0) { + String name = type.toString(); + if (interfaceClassName.equals(name)) { + return true; + } + } + } + } + + // check super classes which may implement the interface + TypeElement baseTypeElement = null; + TypeMirror superclass = classElement.getSuperclass(); + if (superclass != null) { + String superClassName = canonicalClassName(superclass.toString()); + baseTypeElement = findTypeElement(processingEnv, roundEnv, superClassName); + } + if (baseTypeElement != null) { + classElement = baseTypeElement; + } else { + break; + } + } + + return false; + } + + /** + * Helper method to produce class output text file using the given handler + */ + public static void processFile(ProcessingEnvironment processingEnv, String packageName, String fileName, Func1<PrintWriter, Void> handler) { + PrintWriter writer = null; + try { + Writer out; + Filer filer = processingEnv.getFiler(); + FileObject resource; + try { + resource = filer.getResource(StandardLocation.CLASS_OUTPUT, packageName, fileName); + } catch (Throwable e) { + resource = filer.createResource(StandardLocation.CLASS_OUTPUT, packageName, fileName); + } + URI uri = resource.toUri(); + File file = null; + if (uri != null) { + try { + file = new File(uri.getPath()); + } catch (Exception e) { + warning(processingEnv, "Could not convert output directory resource URI to a file " + e); + } + } + if (file == null) { + warning(processingEnv, "No class output directory could be found!"); + } else { + file.getParentFile().mkdirs(); + out = new FileWriter(file); + writer = new PrintWriter(out); + handler.call(writer); + } + } catch (IOException e) { + log(processingEnv, e); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + public static void log(ProcessingEnvironment processingEnv, String message) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message); + } + + public static void warning(ProcessingEnvironment processingEnv, String message) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, message); + } + + public static void error(ProcessingEnvironment processingEnv, String message) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message); + } + + public static void log(ProcessingEnvironment processingEnv, Throwable e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + StringWriter buffer = new StringWriter(); + PrintWriter writer = new PrintWriter(buffer); + e.printStackTrace(writer); + writer.close(); + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, buffer.toString()); + } + + public static String loadResource(ProcessingEnvironment processingEnv, String packageName, String fileName) { + Filer filer = processingEnv.getFiler(); + + FileObject resource; + try { + resource = filer.getResource(StandardLocation.CLASS_OUTPUT, "", packageName + "/" + fileName); + } catch (Throwable e) { + return "Crap" + e.getMessage(); + } + + if (resource == null) { + return null; + } + + try { + InputStream is = resource.openInputStream(); + return loadText(is, true); + } catch (Exception e) { + warning(processingEnv, "Cannot load file"); + } + + return null; + } + + public static void dumpExceptionToErrorFile(String fileName, String message, Throwable e) { + File file = new File(fileName); + try { + FileOutputStream fos = new FileOutputStream(file); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + fos.write(message.getBytes()); + fos.write("\n\n".getBytes()); + fos.write(sw.toString().getBytes()); + pw.close(); + sw.close(); + fos.close(); + } catch (Throwable t) { + // ignore + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/8a18e284/tooling/apt/src/main/java/org/apache/camel/tools/apt/CamelContextAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CamelContextAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CamelContextAnnotationProcessor.java deleted file mode 100644 index f8e6b71..0000000 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CamelContextAnnotationProcessor.java +++ /dev/null @@ -1,720 +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.Comparator; -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.XmlElements; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import org.apache.camel.spi.Metadata; -import org.apache.camel.tools.apt.helper.JsonSchemaHelper; -import org.apache.camel.tools.apt.helper.Strings; - -import static org.apache.camel.tools.apt.helper.JsonSchemaHelper.sanitizeDescription; -import static org.apache.camel.tools.apt.helper.Strings.canonicalClassName; -import static org.apache.camel.tools.apt.helper.Strings.isNullOrEmpty; -import static org.apache.camel.tools.apt.helper.Strings.safeNull; - -/** - * Process camel-spring's <camelContext> and generate json schema documentation - */ -@SupportedAnnotationTypes({"javax.xml.bind.annotation.*", "org.apache.camel.spi.Label"}) -@SupportedSourceVersion(SourceVersion.RELEASE_8) -public class CamelContextAnnotationProcessor extends AbstractAnnotationProcessor { - - private static final String ONE_OF_TYPE_NAME = ""; - private boolean skipUnwanted = true; - - @Override - public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { - try { - 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); - } - } - } catch (Throwable e) { - dumpExceptionToErrorFile("camel-apt-error.log", "Error processing CamelContext model", e); - } - return true; - } - - protected void processModelClass(final RoundEnvironment roundEnv, final TypeElement classElement) { - // must be from camel-spring or camel-core-xml - final String javaTypeName = canonicalClassName(classElement.getQualifiedName().toString()); - String packageName = javaTypeName.substring(0, javaTypeName.lastIndexOf(".")); - boolean valid = javaTypeName.startsWith("org.apache.camel.spring") || javaTypeName.startsWith("org.apache.camel.core.xml"); - if (!valid) { - 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); - if (rootElement == null) { - return; - } - - 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 modelName) { - // gather eip information - EipModel eipModel = findEipModelProperties(roundEnv, classElement, javaTypeName, modelName); - - // collect eip information - Set<EipOption> eipOptions = new TreeSet<EipOption>(new EipOptionComparator(eipModel)); - findClassProperties(writer, roundEnv, eipOptions, classElement, classElement, "", modelName); - - 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 \"kind\": \"").append("model").append("\","); - buffer.append("\n \"name\": \"").append(eipModel.getName()).append("\","); - if (eipModel.getTitle() != null) { - buffer.append("\n \"title\": \"").append(eipModel.getTitle()).append("\","); - } else { - // fallback and use name as title - buffer.append("\n \"title\": \"").append(asTitle(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.isDeprecated(), false, null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes(), null, null, false)); - } - 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); - - Metadata metadata = classElement.getAnnotation(Metadata.class); - if (metadata != null) { - if (!Strings.isNullOrEmpty(metadata.label())) { - model.setLabel(metadata.label()); - } - if (!Strings.isNullOrEmpty(metadata.title())) { - model.setTitle(metadata.title()); - } - } - - // 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, String modelName) { - while (true) { - List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements()); - for (VariableElement fieldElement : fieldElements) { - - String fieldName = fieldElement.getSimpleName().toString(); - - XmlAttribute attribute = fieldElement.getAnnotation(XmlAttribute.class); - if (attribute != null) { - boolean skip = processAttribute(roundEnv, originalClassType, classElement, fieldElement, fieldName, attribute, eipOptions, prefix, modelName); - if (skip) { - continue; - } - } - - XmlElements elements = fieldElement.getAnnotation(XmlElements.class); - if (elements != null) { - processElements(roundEnv, classElement, elements, fieldElement, eipOptions, prefix); - } - - XmlElementRef elementRef = fieldElement.getAnnotation(XmlElementRef.class); - if (elementRef != null) { - processElement(roundEnv, classElement, null, elementRef, fieldElement, eipOptions, prefix); - } - - XmlElement element = fieldElement.getAnnotation(XmlElement.class); - if (element != null) { - if ("rests".equals(fieldName)) { - processRests(roundEnv, classElement, element, fieldElement, fieldName, eipOptions, prefix); - } else if ("routes".equals(fieldName)) { - processRoutes(roundEnv, classElement, element, fieldElement, fieldName, eipOptions, prefix); - } else { - processElement(roundEnv, classElement, element, null, fieldElement, 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 boolean processAttribute(RoundEnvironment roundEnv, TypeElement originalClassType, TypeElement classElement, VariableElement fieldElement, - String fieldName, XmlAttribute attribute, Set<EipOption> eipOptions, String prefix, String modelName) { - Elements elementUtils = processingEnv.getElementUtils(); - - String name = attribute.name(); - if (isNullOrEmpty(name) || "##default".equals(name)) { - name = fieldName; - } - - // lets skip some unwanted attributes - if (skipUnwanted) { - } - - name = prefix + name; - TypeMirror fieldType = fieldElement.asType(); - String fieldTypeName = fieldType.toString(); - TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName); - - String defaultValue = findDefaultValue(fieldElement, fieldTypeName); - String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, true); - if (isNullOrEmpty(docComment)) { - Metadata metadata = fieldElement.getAnnotation(Metadata.class); - docComment = metadata != null ? metadata.description() : null; - } - boolean required = attribute.required(); - // metadata may overrule element required - required = findRequired(fieldElement, 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); - } - } - } - - boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != null; - - // special for id as its inherited from camel-core - if ("id".equals(name) && isNullOrEmpty(docComment)) { - if ("CamelContextFactoryBean".equals(originalClassType.getSimpleName().toString())) { - docComment = "Sets the id (name) of this CamelContext"; - } else { - docComment = "Sets the id of this node"; - } - } - - EipOption ep = new EipOption(name, "attribute", fieldTypeName, required, defaultValue, docComment, deprecated, isEnum, enums, false, null); - eipOptions.add(ep); - - return false; - } - - /** - * Special for processing an @XmlElement routes field - */ - private void processRoutes(RoundEnvironment roundEnv, TypeElement originalClassType, XmlElement element, - VariableElement fieldElement, String fieldName, Set<EipOption> eipOptions, String prefix) { - - TypeMirror fieldType = fieldElement.asType(); - String fieldTypeName = fieldType.toString(); - - Set<String> oneOfTypes = new TreeSet<String>(); - oneOfTypes.add("route"); - - EipOption ep = new EipOption("route", "element", fieldTypeName, false, "", "Contains the Camel routes", false, false, null, true, oneOfTypes); - eipOptions.add(ep); - } - - /** - * Special for processing an @XmlElement rests field - */ - private void processRests(RoundEnvironment roundEnv, TypeElement originalClassType, XmlElement element, - VariableElement fieldElement, String fieldName, Set<EipOption> eipOptions, String prefix) { - - TypeMirror fieldType = fieldElement.asType(); - String fieldTypeName = fieldType.toString(); - - Set<String> oneOfTypes = new TreeSet<String>(); - oneOfTypes.add("rest"); - - EipOption ep = new EipOption("rest", "element", fieldTypeName, false, "", "Contains the rest services defined using the rest-dsl", false, false, null, true, oneOfTypes); - eipOptions.add(ep); - } - - private void processElement(RoundEnvironment roundEnv, TypeElement classElement, XmlElement element, XmlElementRef elementRef, VariableElement fieldElement, - Set<EipOption> eipOptions, String prefix) { - Elements elementUtils = processingEnv.getElementUtils(); - - String fieldName; - fieldName = fieldElement.getSimpleName().toString(); - if (element != null || elementRef != null) { - - String kind = "element"; - String name = element != null ? element.name() : elementRef.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 defaultValue = findDefaultValue(fieldElement, fieldTypeName); - String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, true); - if (isNullOrEmpty(docComment)) { - Metadata metadata = fieldElement.getAnnotation(Metadata.class); - docComment = metadata != null ? metadata.description() : null; - } - boolean required = element != null ? element.required() : elementRef.required(); - // metadata may overrule element required - required = findRequired(fieldElement, 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); - } - } - } - - // is it a definition/factory-bean type then its a oneOf - TreeSet oneOfTypes = new TreeSet<String>(); - if (fieldTypeName.endsWith("Definition") || fieldTypeName.endsWith("FactoryBean")) { - TypeElement definitionClass = findTypeElement(roundEnv, fieldTypeElement.asType().toString()); - if (definitionClass != null) { - XmlRootElement rootElement = definitionClass.getAnnotation(XmlRootElement.class); - if (rootElement != null) { - String childName = rootElement.name(); - if (childName != null) { - oneOfTypes.add(childName); - } - } - } - } else if (fieldTypeName.endsWith("Definition>") || fieldTypeName.endsWith("FactoryBean>")) { - // its a list so we need to load the generic type - String typeName = Strings.between(fieldTypeName, "<", ">"); - TypeElement definitionClass = findTypeElement(roundEnv, typeName); - if (definitionClass != null) { - XmlRootElement rootElement = definitionClass.getAnnotation(XmlRootElement.class); - if (rootElement != null) { - String childName = rootElement.name(); - if (childName != null) { - oneOfTypes.add(childName); - } - } - } - } - boolean oneOf = !oneOfTypes.isEmpty(); - - boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != null; - - EipOption ep = new EipOption(name, kind, fieldTypeName, required, defaultValue, docComment, deprecated, isEnum, enums, oneOf, 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 defaultValue = findDefaultValue(fieldElement, fieldTypeName); - String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, true); - if (isNullOrEmpty(docComment)) { - Metadata metadata = fieldElement.getAnnotation(Metadata.class); - docComment = metadata != null ? metadata.description() : null; - } - boolean required = false; - required = findRequired(fieldElement, required); - - // 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, defaultValue, docComment, false, false, null, true, oneOfTypes); - eipOptions.add(ep); - } - } - - private String findDefaultValue(VariableElement fieldElement, String fieldTypeName) { - String defaultValue = null; - Metadata metadata = fieldElement.getAnnotation(Metadata.class); - if (metadata != null) { - if (!Strings.isNullOrEmpty(metadata.defaultValue())) { - defaultValue = metadata.defaultValue(); - } - } - if (defaultValue == null) { - // if its a boolean type, then we use false as the default - if ("boolean".equals(fieldTypeName) || "java.lang.Boolean".equals(fieldTypeName)) { - defaultValue = "false"; - } - } - - return defaultValue; - } - - private boolean findRequired(VariableElement fieldElement, boolean defaultValue) { - Metadata metadata = fieldElement.getAnnotation(Metadata.class); - if (metadata != null) { - if (!Strings.isNullOrEmpty(metadata.required())) { - defaultValue = "true".equals(metadata.required()); - } - } - return defaultValue; - } - - /** - * Capitializes the name as a title - * - * @param name the name - * @return as a title - */ - private static String asTitle(String name) { - StringBuilder sb = new StringBuilder(); - for (char c : name.toCharArray()) { - boolean upper = Character.isUpperCase(c); - boolean first = sb.length() == 0; - if (first) { - sb.append(Character.toUpperCase(c)); - } else if (upper) { - sb.append(' '); - sb.append(c); - } else { - sb.append(Character.toLowerCase(c)); - } - } - return sb.toString().trim(); - } - - private static final class EipModel { - - private String name; - private String title; - private String javaType; - private String label; - private String description; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - 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 deprecated; - 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 deprecated, - 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.deprecated = deprecated; - 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 isDeprecated() { - return deprecated; - } - - 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(); - } - } - - private static final class EipOptionComparator implements Comparator<EipOption> { - - private final EipModel model; - - private EipOptionComparator(EipModel model) { - this.model = model; - } - - @Override - public int compare(EipOption o1, EipOption o2) { - int weigth = weigth(o1); - int weigth2 = weigth(o2); - - if (weigth == weigth2) { - // keep the current order - return 1; - } else { - // sort according to weight - return weigth2 - weigth; - } - } - - private int weigth(EipOption o) { - String name = o.getName(); - - // these should be first - if ("expression".equals(name)) { - return 10; - } - - // these should be last - if ("description".equals(name)) { - return -10; - } else if ("id".equals(name)) { - return -9; - } else if ("pattern".equals(name) && "to".equals(model.getName())) { - // and pattern only for the to model - return -8; - } - return 0; - } - } - -}