Search in sources :

Example 1 with EndpointPath

use of org.apache.camel.tools.apt.model.EndpointPath 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 2 with EndpointPath

use of org.apache.camel.tools.apt.model.EndpointPath in project camel by apache.

the class EndpointAnnotationProcessor method createParameterJsonSchema.

public String createParameterJsonSchema(ComponentModel componentModel, Set<ComponentOption> componentOptions, Set<EndpointPath> endpointPaths, Set<EndpointOption> endpointOptions, String[] schemes) {
    StringBuilder buffer = new StringBuilder("{");
    // component model
    buffer.append("\n \"component\": {");
    buffer.append("\n    \"kind\": \"").append("component").append("\",");
    buffer.append("\n    \"scheme\": \"").append(componentModel.getScheme()).append("\",");
    if (!Strings.isNullOrEmpty(componentModel.getExtendsScheme())) {
        buffer.append("\n    \"extendsScheme\": \"").append(componentModel.getExtendsScheme()).append("\",");
    }
    // the first scheme is the regular so only output if there is alternatives
    if (schemes != null && schemes.length > 1) {
        CollectionStringBuffer csb = new CollectionStringBuffer(",");
        for (String altScheme : schemes) {
            csb.append(altScheme);
        }
        buffer.append("\n    \"alternativeSchemes\": \"").append(csb.toString()).append("\",");
    }
    buffer.append("\n    \"syntax\": \"").append(componentModel.getSyntax()).append("\",");
    if (componentModel.getAlternativeSyntax() != null) {
        buffer.append("\n    \"alternativeSyntax\": \"").append(componentModel.getAlternativeSyntax()).append("\",");
    }
    buffer.append("\n    \"title\": \"").append(componentModel.getTitle()).append("\",");
    buffer.append("\n    \"description\": \"").append(componentModel.getDescription()).append("\",");
    buffer.append("\n    \"label\": \"").append(getOrElse(componentModel.getLabel(), "")).append("\",");
    buffer.append("\n    \"deprecated\": ").append(componentModel.isDeprecated()).append(",");
    buffer.append("\n    \"async\": ").append(componentModel.isAsync()).append(",");
    buffer.append("\n    \"consumerOnly\": ").append(componentModel.isConsumerOnly()).append(",");
    buffer.append("\n    \"producerOnly\": ").append(componentModel.isProducerOnly()).append(",");
    buffer.append("\n    \"lenientProperties\": ").append(componentModel.isLenientProperties()).append(",");
    buffer.append("\n    \"javaType\": \"").append(componentModel.getJavaType()).append("\",");
    if (componentModel.getFirstVersion() != null) {
        buffer.append("\n    \"firstVersion\": \"").append(componentModel.getFirstVersion()).append("\",");
    }
    buffer.append("\n    \"groupId\": \"").append(componentModel.getGroupId()).append("\",");
    buffer.append("\n    \"artifactId\": \"").append(componentModel.getArtifactId()).append("\",");
    if (componentModel.getVerifiers() != null) {
        buffer.append("\n    \"verifiers\": \"").append(componentModel.getVerifiers()).append("\",");
    }
    buffer.append("\n    \"version\": \"").append(componentModel.getVersionId()).append("\"");
    buffer.append("\n  },");
    // and component properties
    buffer.append("\n  \"componentProperties\": {");
    boolean first = true;
    for (ComponentOption entry : componentOptions) {
        if (first) {
            first = false;
        } else {
            buffer.append(",");
        }
        buffer.append("\n    ");
        // either we have the documentation from this apt plugin or we need help to find it from extended component
        String doc = entry.getDocumentationWithNotes();
        if (Strings.isNullOrEmpty(doc)) {
            doc = DocumentationHelper.findComponentJavaDoc(componentModel.getScheme(), componentModel.getExtendsScheme(), entry.getName());
        }
        // as its json we need to sanitize the docs
        doc = sanitizeDescription(doc, false);
        Boolean required = entry.getRequired() != null ? Boolean.valueOf(entry.getRequired()) : null;
        String defaultValue = entry.getDefaultValue();
        if (Strings.isNullOrEmpty(defaultValue) && "boolean".equals(entry.getType())) {
            // fallback as false for boolean types
            defaultValue = "false";
        }
        // component options do not have prefix
        String optionalPrefix = "";
        String prefix = "";
        boolean multiValue = false;
        boolean asPredicate = false;
        buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "property", required, entry.getType(), defaultValue, doc, entry.isDeprecated(), entry.isSecret(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, asPredicate, optionalPrefix, prefix, multiValue));
    }
    buffer.append("\n  },");
    buffer.append("\n  \"properties\": {");
    first = true;
    // sort the endpoint options in the standard order we prefer
    List<EndpointPath> paths = new ArrayList<EndpointPath>();
    paths.addAll(endpointPaths);
    Collections.sort(paths, EndpointHelper.createPathComparator(componentModel.getSyntax()));
    // include paths in the top
    for (EndpointPath entry : paths) {
        String label = entry.getLabel();
        if (label != null) {
            // skip options which are either consumer or producer labels but the component does not support them
            if (label.contains("consumer") && componentModel.isProducerOnly()) {
                continue;
            } else if (label.contains("producer") && componentModel.isConsumerOnly()) {
                continue;
            }
        }
        if (first) {
            first = false;
        } else {
            buffer.append(",");
        }
        buffer.append("\n    ");
        // either we have the documentation from this apt plugin or we need help to find it from extended component
        String doc = entry.getDocumentation();
        if (Strings.isNullOrEmpty(doc)) {
            doc = DocumentationHelper.findEndpointJavaDoc(componentModel.getScheme(), componentModel.getExtendsScheme(), entry.getName());
        }
        // as its json we need to sanitize the docs
        doc = sanitizeDescription(doc, false);
        Boolean required = entry.getRequired() != null ? Boolean.valueOf(entry.getRequired()) : null;
        String defaultValue = entry.getDefaultValue();
        if (Strings.isNullOrEmpty(defaultValue) && "boolean".equals(entry.getType())) {
            // fallback as false for boolean types
            defaultValue = "false";
        }
        // @UriPath options do not have prefix
        String optionalPrefix = "";
        String prefix = "";
        boolean multiValue = false;
        boolean asPredicate = false;
        buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "path", required, entry.getType(), defaultValue, doc, entry.isDeprecated(), entry.isSecret(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, asPredicate, optionalPrefix, prefix, multiValue));
    }
    // sort the endpoint options in the standard order we prefer
    List<EndpointOption> options = new ArrayList<EndpointOption>();
    options.addAll(endpointOptions);
    Collections.sort(options, EndpointHelper.createGroupAndLabelComparator());
    // and then regular parameter options
    for (EndpointOption entry : options) {
        String label = entry.getLabel();
        if (label != null) {
            // skip options which are either consumer or producer labels but the component does not support them
            if (label.contains("consumer") && componentModel.isProducerOnly()) {
                continue;
            } else if (label.contains("producer") && componentModel.isConsumerOnly()) {
                continue;
            }
        }
        if (first) {
            first = false;
        } else {
            buffer.append(",");
        }
        buffer.append("\n    ");
        // either we have the documentation from this apt plugin or we need help to find it from extended component
        String doc = entry.getDocumentationWithNotes();
        if (Strings.isNullOrEmpty(doc)) {
            doc = DocumentationHelper.findEndpointJavaDoc(componentModel.getScheme(), componentModel.getExtendsScheme(), entry.getName());
        }
        // as its json we need to sanitize the docs
        doc = sanitizeDescription(doc, false);
        Boolean required = entry.getRequired() != null ? Boolean.valueOf(entry.getRequired()) : null;
        String defaultValue = entry.getDefaultValue();
        if (Strings.isNullOrEmpty(defaultValue) && "boolean".equals(entry.getType())) {
            // fallback as false for boolean types
            defaultValue = "false";
        }
        String optionalPrefix = entry.getOptionalPrefix();
        String prefix = entry.getPrefix();
        boolean multiValue = entry.isMultiValue();
        boolean asPredicate = false;
        buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "parameter", required, entry.getType(), defaultValue, doc, entry.isDeprecated(), entry.isSecret(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, asPredicate, optionalPrefix, prefix, multiValue));
    }
    buffer.append("\n  }");
    buffer.append("\n}\n");
    return buffer.toString();
}
Also used : CollectionStringBuffer(org.apache.camel.tools.apt.helper.CollectionStringBuffer) ComponentOption(org.apache.camel.tools.apt.model.ComponentOption) ArrayList(java.util.ArrayList) EndpointOption(org.apache.camel.tools.apt.model.EndpointOption) EndpointPath(org.apache.camel.tools.apt.model.EndpointPath)

Example 3 with EndpointPath

use of org.apache.camel.tools.apt.model.EndpointPath in project camel by apache.

the class EndpointAnnotationProcessor method findClassProperties.

protected void findClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel, Set<EndpointPath> endpointPaths, Set<EndpointOption> endpointOptions, TypeElement classElement, String prefix, String excludeProperties) {
    Elements elementUtils = processingEnv.getElementUtils();
    while (true) {
        List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
        for (VariableElement fieldElement : fieldElements) {
            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != null;
            Boolean secret = metadata != null ? metadata.secret() : null;
            UriPath path = fieldElement.getAnnotation(UriPath.class);
            String fieldName = fieldElement.getSimpleName().toString();
            if (path != null) {
                String name = path.name();
                if (isNullOrEmpty(name)) {
                    name = fieldName;
                }
                name = prefix + name;
                // should we exclude the name?
                if (excludeProperty(excludeProperties, name)) {
                    continue;
                }
                String defaultValue = path.defaultValue();
                if (Strings.isNullOrEmpty(defaultValue) && metadata != null) {
                    defaultValue = metadata.defaultValue();
                }
                String defaultValueNote = path.defaultValueNote();
                String required = metadata != null ? metadata.required() : null;
                String label = path.label();
                if (Strings.isNullOrEmpty(label) && metadata != null) {
                    label = metadata.label();
                }
                String displayName = path.displayName();
                if (Strings.isNullOrEmpty(displayName)) {
                    displayName = metadata != null ? metadata.displayName() : null;
                }
                TypeMirror fieldType = fieldElement.asType();
                String fieldTypeName = fieldType.toString();
                TypeElement fieldTypeElement = findTypeElement(processingEnv, roundEnv, fieldTypeName);
                String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, false);
                if (isNullOrEmpty(docComment)) {
                    docComment = path.description();
                }
                // gather enums
                Set<String> enums = new LinkedHashSet<String>();
                boolean isEnum;
                if (!Strings.isNullOrEmpty(path.enums())) {
                    isEnum = true;
                    String[] values = path.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());
                        // find all the enum constants which has the possible enum value that can be used
                        if (enumClass != null) {
                            List<VariableElement> fields = ElementFilter.fieldsIn(enumClass.getEnclosedElements());
                            for (VariableElement var : fields) {
                                if (var.getKind() == ElementKind.ENUM_CONSTANT) {
                                    String val = var.toString();
                                    enums.add(val);
                                }
                            }
                        }
                    }
                }
                // the field type may be overloaded by another type
                if (!Strings.isNullOrEmpty(path.javaType())) {
                    fieldTypeName = path.javaType();
                }
                String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                boolean isSecret = secret != null ? secret : false;
                EndpointPath ep = new EndpointPath(name, displayName, fieldTypeName, required, defaultValue, docComment, deprecated, isSecret, group, label, isEnum, enums);
                endpointPaths.add(ep);
            }
            UriParam param = fieldElement.getAnnotation(UriParam.class);
            fieldName = fieldElement.getSimpleName().toString();
            if (param != null) {
                String name = param.name();
                if (isNullOrEmpty(name)) {
                    name = fieldName;
                }
                name = prefix + name;
                // should we exclude the name?
                if (excludeProperty(excludeProperties, name)) {
                    continue;
                }
                String paramOptionalPrefix = param.optionalPrefix();
                String paramPrefix = param.prefix();
                boolean multiValue = param.multiValue();
                String defaultValue = param.defaultValue();
                if (defaultValue == null && metadata != null) {
                    defaultValue = metadata.defaultValue();
                }
                String defaultValueNote = param.defaultValueNote();
                String required = metadata != null ? metadata.required() : null;
                String label = param.label();
                if (Strings.isNullOrEmpty(label) && metadata != null) {
                    label = metadata.label();
                }
                String displayName = param.displayName();
                if (Strings.isNullOrEmpty(displayName)) {
                    displayName = metadata != null ? metadata.displayName() : null;
                }
                // if the field type is a nested parameter then iterate through its fields
                TypeMirror fieldType = fieldElement.asType();
                String fieldTypeName = fieldType.toString();
                TypeElement fieldTypeElement = findTypeElement(processingEnv, roundEnv, fieldTypeName);
                UriParams fieldParams = null;
                if (fieldTypeElement != null) {
                    fieldParams = fieldTypeElement.getAnnotation(UriParams.class);
                }
                if (fieldParams != null) {
                    String nestedPrefix = prefix;
                    String extraPrefix = fieldParams.prefix();
                    if (!isNullOrEmpty(extraPrefix)) {
                        nestedPrefix += extraPrefix;
                    }
                    findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, fieldTypeElement, nestedPrefix, excludeProperties);
                } else {
                    String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, name, classElement, false);
                    if (isNullOrEmpty(docComment)) {
                        docComment = param.description();
                    }
                    if (isNullOrEmpty(docComment)) {
                        docComment = "";
                    }
                    // gather enums
                    Set<String> enums = new LinkedHashSet<String>();
                    boolean isEnum;
                    if (!Strings.isNullOrEmpty(param.enums())) {
                        isEnum = true;
                        String[] values = param.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);
                                    }
                                }
                            }
                        }
                    }
                    // the field type may be overloaded by another type
                    if (!Strings.isNullOrEmpty(param.javaType())) {
                        fieldTypeName = param.javaType();
                    }
                    boolean isSecret = secret != null ? secret : param.secret();
                    String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                    EndpointOption option = new EndpointOption(name, displayName, fieldTypeName, required, defaultValue, defaultValueNote, docComment.trim(), paramOptionalPrefix, paramPrefix, multiValue, deprecated, isSecret, group, label, isEnum, enums);
                    endpointOptions.add(option);
                }
            }
        }
        // check super classes which may also have @UriParam 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) Metadata(org.apache.camel.spi.Metadata) VariableElement(javax.lang.model.element.VariableElement) Elements(javax.lang.model.util.Elements) UriParam(org.apache.camel.spi.UriParam) EndpointPath(org.apache.camel.tools.apt.model.EndpointPath) UriParams(org.apache.camel.spi.UriParams) TypeMirror(javax.lang.model.type.TypeMirror) UriPath(org.apache.camel.spi.UriPath) EndpointOption(org.apache.camel.tools.apt.model.EndpointOption)

Aggregations

EndpointOption (org.apache.camel.tools.apt.model.EndpointOption)3 EndpointPath (org.apache.camel.tools.apt.model.EndpointPath)3 LinkedHashSet (java.util.LinkedHashSet)2 TypeElement (javax.lang.model.element.TypeElement)2 AnnotationProcessorHelper.findTypeElement (org.apache.camel.tools.apt.AnnotationProcessorHelper.findTypeElement)2 ComponentOption (org.apache.camel.tools.apt.model.ComponentOption)2 ArrayList (java.util.ArrayList)1 VariableElement (javax.lang.model.element.VariableElement)1 TypeMirror (javax.lang.model.type.TypeMirror)1 Elements (javax.lang.model.util.Elements)1 Metadata (org.apache.camel.spi.Metadata)1 UriParam (org.apache.camel.spi.UriParam)1 UriParams (org.apache.camel.spi.UriParams)1 UriPath (org.apache.camel.spi.UriPath)1 CollectionStringBuffer (org.apache.camel.tools.apt.helper.CollectionStringBuffer)1 ComponentModel (org.apache.camel.tools.apt.model.ComponentModel)1