Search in sources :

Example 81 with TypeElement

use of javax.lang.model.element.TypeElement in project camel by apache.

the class EndpointAnnotationProcessor method findComponentClassProperties.

protected void findComponentClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel, Set<ComponentOption> componentOptions, TypeElement classElement, String prefix) {
    Elements elementUtils = processingEnv.getElementUtils();
    while (true) {
        Metadata componentAnnotation = classElement.getAnnotation(Metadata.class);
        if (componentAnnotation != null && Objects.equals("verifiers", componentAnnotation.label())) {
            componentModel.setVerifiers(componentAnnotation.enums());
        }
        List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements());
        for (ExecutableElement method : methods) {
            String methodName = method.getSimpleName().toString();
            boolean deprecated = method.getAnnotation(Deprecated.class) != null;
            Metadata metadata = method.getAnnotation(Metadata.class);
            // must be the setter
            boolean isSetter = methodName.startsWith("set") && method.getParameters().size() == 1 & method.getReturnType().getKind().equals(TypeKind.VOID);
            if (!isSetter) {
                continue;
            }
            // skip unwanted methods as they are inherited from default component and are not intended for end users to configure
            if ("setEndpointClass".equals(methodName) || "setCamelContext".equals(methodName) || "setEndpointHeaderFilterStrategy".equals(methodName) || "setApplicationContext".equals(methodName)) {
                continue;
            }
            // must be a getter/setter pair
            String fieldName = methodName.substring(3);
            fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
            // we usually favor putting the @Metadata annotation on the field instead of the setter, so try to use it if its there
            VariableElement field = findFieldElement(classElement, fieldName);
            if (field != null && metadata == null) {
                metadata = field.getAnnotation(Metadata.class);
            }
            String required = metadata != null ? metadata.required() : null;
            String label = metadata != null ? metadata.label() : null;
            boolean secret = metadata != null && metadata.secret();
            String displayName = metadata != null ? metadata.displayName() : null;
            // we do not yet have default values / notes / as no annotation support yet
            // String defaultValueNote = param.defaultValueNote();
            String defaultValue = metadata != null ? metadata.defaultValue() : null;
            String defaultValueNote = null;
            ExecutableElement setter = method;
            String name = fieldName;
            name = prefix + name;
            TypeMirror fieldType = setter.getParameters().get(0).asType();
            String fieldTypeName = fieldType.toString();
            TypeElement fieldTypeElement = findTypeElement(processingEnv, roundEnv, fieldTypeName);
            String docComment = findJavaDoc(elementUtils, method, fieldName, name, classElement, false);
            if (isNullOrEmpty(docComment)) {
                docComment = metadata != null ? metadata.description() : null;
            }
            if (isNullOrEmpty(docComment)) {
                // apt cannot grab javadoc from camel-core, only from annotations
                if ("setHeaderFilterStrategy".equals(methodName)) {
                    docComment = HEADER_FILTER_STRATEGY_JAVADOC;
                } else {
                    docComment = "";
                }
            }
            // gather enums
            Set<String> enums = new LinkedHashSet<String>();
            boolean isEnum;
            if (metadata != null && !Strings.isNullOrEmpty(metadata.enums())) {
                isEnum = true;
                String[] values = metadata.enums().split(",");
                for (String val : values) {
                    enums.add(val);
                }
            } else {
                isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == ElementKind.ENUM;
                if (isEnum) {
                    TypeElement enumClass = findTypeElement(processingEnv, roundEnv, fieldTypeElement.asType().toString());
                    if (enumClass != null) {
                        // 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);
                            }
                        }
                    }
                }
            }
            String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
            ComponentOption option = new ComponentOption(name, displayName, fieldTypeName, required, defaultValue, defaultValueNote, docComment.trim(), deprecated, secret, group, label, isEnum, enums);
            componentOptions.add(option);
        }
        // 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(processingEnv, roundEnv, superClassName);
        }
        if (baseTypeElement != null) {
            classElement = baseTypeElement;
        } else {
            break;
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TypeElement(javax.lang.model.element.TypeElement) AnnotationProcessorHelper.findTypeElement(org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement) ComponentOption(org.apache.camel.tools.apt.model.ComponentOption) ExecutableElement(javax.lang.model.element.ExecutableElement) Metadata(org.apache.camel.spi.Metadata) VariableElement(javax.lang.model.element.VariableElement) Elements(javax.lang.model.util.Elements) TypeMirror(javax.lang.model.type.TypeMirror)

Example 82 with TypeElement

use of javax.lang.model.element.TypeElement in project camel by apache.

the class EndpointAnnotationProcessor method writeJSonSchemeDocumentation.

protected void writeJSonSchemeDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint, String title, String scheme, String extendsScheme, String label, String[] schemes) {
    // gather component information
    ComponentModel componentModel = findComponentProperties(roundEnv, uriEndpoint, classElement, title, scheme, extendsScheme, label);
    // get endpoint information which is divided into paths and options (though there should really only be one path)
    Set<EndpointPath> endpointPaths = new LinkedHashSet<EndpointPath>();
    Set<EndpointOption> endpointOptions = new LinkedHashSet<EndpointOption>();
    Set<ComponentOption> componentOptions = new LinkedHashSet<ComponentOption>();
    TypeElement componentClassElement = findTypeElement(processingEnv, roundEnv, componentModel.getJavaType());
    if (componentClassElement != null) {
        findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "");
    }
    findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties());
    String json = createParameterJsonSchema(componentModel, componentOptions, endpointPaths, endpointOptions, schemes);
    writer.println(json);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ComponentOption(org.apache.camel.tools.apt.model.ComponentOption) TypeElement(javax.lang.model.element.TypeElement) AnnotationProcessorHelper.findTypeElement(org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement) ComponentModel(org.apache.camel.tools.apt.model.ComponentModel) EndpointOption(org.apache.camel.tools.apt.model.EndpointOption) EndpointPath(org.apache.camel.tools.apt.model.EndpointPath)

Example 83 with TypeElement

use of javax.lang.model.element.TypeElement in project camel by apache.

the class EndpointAnnotationProcessor method findComponentProperties.

protected ComponentModel findComponentProperties(RoundEnvironment roundEnv, UriEndpoint uriEndpoint, TypeElement endpointClassElement, String title, String scheme, String extendsScheme, String label) {
    ComponentModel model = new ComponentModel(scheme);
    // if the scheme is an alias then replace the scheme name from the syntax with the alias
    String syntax = scheme + ":" + Strings.after(uriEndpoint.syntax(), ":");
    // alternative syntax is optional
    if (!Strings.isNullOrEmpty(uriEndpoint.alternativeSyntax())) {
        String alternativeSyntax = scheme + ":" + Strings.after(uriEndpoint.alternativeSyntax(), ":");
        model.setAlternativeSyntax(alternativeSyntax);
    }
    model.setExtendsScheme(extendsScheme);
    model.setSyntax(syntax);
    model.setTitle(title);
    model.setLabel(label);
    model.setConsumerOnly(uriEndpoint.consumerOnly());
    model.setProducerOnly(uriEndpoint.producerOnly());
    model.setLenientProperties(uriEndpoint.lenientProperties());
    model.setAsync(implementsInterface(processingEnv, roundEnv, endpointClassElement, "org.apache.camel.AsyncEndpoint"));
    // what is the first version this component was added to Apache Camel
    String firstVersion = uriEndpoint.firstVersion();
    if (Strings.isNullOrEmpty(firstVersion) && endpointClassElement.getAnnotation(Metadata.class) != null) {
        // fallback to @Metadata if not from @UriEndpoint
        firstVersion = endpointClassElement.getAnnotation(Metadata.class).firstVersion();
    }
    if (!Strings.isNullOrEmpty(firstVersion)) {
        model.setFirstVersion(firstVersion);
    }
    String data = loadResource(processingEnv, "META-INF/services/org/apache/camel/component", scheme);
    if (data != null) {
        Map<String, String> map = parseAsMap(data);
        model.setJavaType(map.get("class"));
    }
    data = loadResource(processingEnv, "META-INF/services/org/apache/camel", "component.properties");
    if (data != null) {
        Map<String, String> map = parseAsMap(data);
        // now we have a lot more data, so we need to load it as key/value
        // need to sanitize the description first
        String doc = map.get("projectDescription");
        if (doc != null) {
            model.setDescription(sanitizeDescription(doc, true));
        } else {
            model.setDescription("");
        }
        // we can mark a component as deprecated by using the annotation or in the pom.xml
        boolean deprecated = endpointClassElement.getAnnotation(Deprecated.class) != null;
        if (!deprecated) {
            String name = map.get("projectName");
            // we may have marked a component as deprecated in the project name
            deprecated = name != null && name.contains("(deprecated)");
        }
        model.setDeprecated(deprecated);
        if (map.containsKey("groupId")) {
            model.setGroupId(map.get("groupId"));
        } else {
            model.setGroupId("");
        }
        if (map.containsKey("artifactId")) {
            model.setArtifactId(map.get("artifactId"));
        } else {
            model.setArtifactId("");
        }
        if (map.containsKey("version")) {
            model.setVersionId(map.get("version"));
        } else {
            model.setVersionId("");
        }
    }
    // favor to use endpoint class javadoc as description
    Elements elementUtils = processingEnv.getElementUtils();
    TypeElement typeElement = findTypeElement(processingEnv, roundEnv, endpointClassElement.getQualifiedName().toString());
    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;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) AnnotationProcessorHelper.findTypeElement(org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement) ComponentModel(org.apache.camel.tools.apt.model.ComponentModel) Elements(javax.lang.model.util.Elements)

Example 84 with TypeElement

use of javax.lang.model.element.TypeElement in project camel by apache.

the class SpringAnnotationProcessor method findEipModelProperties.

protected EipModel findEipModelProperties(ProcessingEnvironment processingEnv, 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(processingEnv, 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;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) AnnotationProcessorHelper.findTypeElement(org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement) Metadata(org.apache.camel.spi.Metadata) Elements(javax.lang.model.util.Elements) XmlElements(javax.xml.bind.annotation.XmlElements)

Example 85 with TypeElement

use of javax.lang.model.element.TypeElement in project camel by apache.

the class SpringAnnotationProcessor method findClassProperties.

protected void findClassProperties(ProcessingEnvironment processingEnv, 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(processingEnv, roundEnv, originalClassType, classElement, fieldElement, fieldName, attribute, eipOptions, prefix, modelName);
                if (skip) {
                    continue;
                }
            }
            XmlElements elements = fieldElement.getAnnotation(XmlElements.class);
            if (elements != null) {
                processElements(processingEnv, roundEnv, classElement, elements, fieldElement, eipOptions, prefix);
            }
            XmlElementRef elementRef = fieldElement.getAnnotation(XmlElementRef.class);
            if (elementRef != null) {
                processElement(processingEnv, 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(processingEnv, 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(processingEnv, roundEnv, superClassName);
        }
        if (baseTypeElement != null) {
            classElement = baseTypeElement;
        } else {
            break;
        }
    }
}
Also used : XmlElementRef(javax.xml.bind.annotation.XmlElementRef) XmlElements(javax.xml.bind.annotation.XmlElements) XmlAttribute(javax.xml.bind.annotation.XmlAttribute) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) AnnotationProcessorHelper.findTypeElement(org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement) XmlElement(javax.xml.bind.annotation.XmlElement) VariableElement(javax.lang.model.element.VariableElement)

Aggregations

TypeElement (javax.lang.model.element.TypeElement)1562 ExecutableElement (javax.lang.model.element.ExecutableElement)517 Element (javax.lang.model.element.Element)502 TypeMirror (javax.lang.model.type.TypeMirror)420 VariableElement (javax.lang.model.element.VariableElement)333 DeclaredType (javax.lang.model.type.DeclaredType)201 ArrayList (java.util.ArrayList)177 PackageElement (javax.lang.model.element.PackageElement)159 AnnotationMirror (javax.lang.model.element.AnnotationMirror)151 Test (org.junit.Test)136 HashMap (java.util.HashMap)118 HashSet (java.util.HashSet)109 Elements (javax.lang.model.util.Elements)101 Map (java.util.Map)98 IOException (java.io.IOException)97 List (java.util.List)97 ClassName (com.squareup.javapoet.ClassName)88 Test (org.junit.jupiter.api.Test)80 MethodSpec (com.squareup.javapoet.MethodSpec)72 TypeSpec (com.squareup.javapoet.TypeSpec)63