use of org.apache.camel.tools.apt.model.ComponentOption 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;
}
}
}
use of org.apache.camel.tools.apt.model.ComponentOption 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);
}
use of org.apache.camel.tools.apt.model.ComponentOption 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();
}
Aggregations