This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new 2919474 CAMEL-13870: Fix apt using wrong name. And preparing for generating for fast component options. 2919474 is described below commit 291947472afc0dfc5d487d867b21b21c4d6df42e Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sat Aug 24 12:21:00 2019 +0200 CAMEL-13870: Fix apt using wrong name. And preparing for generating for fast component options. --- .../apt/ComponentPropertyConfigurerGenerator.java | 150 +++++++++++++++++++++ .../tools/apt/EndpointAnnotationProcessor.java | 10 +- .../camel/tools/apt/helper/JsonSchemaHelper.java | 6 +- .../camel/tools/apt/model/ComponentOption.java | 14 +- 4 files changed, 171 insertions(+), 9 deletions(-) diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java new file mode 100644 index 0000000..4f9474b --- /dev/null +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java @@ -0,0 +1,150 @@ +/* + * 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.IOException; +import java.io.Writer; +import java.util.Set; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; + +import org.apache.camel.tools.apt.helper.IOHelper; +import org.apache.camel.tools.apt.model.ComponentOption; +import org.apache.camel.tools.apt.model.EndpointOption; + +import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile; + +public final class ComponentPropertyConfigurerGenerator { + + private ComponentPropertyConfigurerGenerator() { + } + + public static void generateExtendConfigurer(ProcessingEnvironment processingEnv, TypeElement parent, + String pn, String cn, String fqn) { + + Writer w = null; + try { + JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent); + w = src.openWriter(); + + w.write("/* Generated by org.apache.camel:apt */\n"); + w.write("package " + pn + ";\n"); + w.write("\n"); + w.write("import " + parent.getQualifiedName().toString() + ";\n"); + w.write("\n"); + w.write("/**\n"); + w.write(" * Source code generated by org.apache.camel:apt\n"); + w.write(" */\n"); + w.write("public class " + cn + " extends " + parent.getSimpleName().toString() + " {\n"); + w.write("\n"); + w.write("}\n"); + w.write("\n"); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage()); + dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e); + } finally { + IOHelper.close(w); + } + } + + public static void generatePropertyConfigurer(ProcessingEnvironment processingEnv, TypeElement parent, + String pn, String cn, String fqn, String en, + Set<ComponentOption> options) { + + Writer w = null; + try { + JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent); + w = src.openWriter(); + + int size = options.size(); + + w.write("/* Generated by org.apache.camel:apt */\n"); + w.write("package " + pn + ";\n"); + w.write("\n"); + w.write("import java.util.HashMap;\n"); + w.write("import java.util.Map;\n"); + w.write("\n"); + w.write("import org.apache.camel.CamelContext;\n"); + w.write("import org.apache.camel.spi.TriPropertyConfigurer;\n"); + w.write("import org.apache.camel.support.component.PropertyConfigurerSupport;\n"); + w.write("import org.apache.camel.util.function.TriConsumer;\n"); + w.write("\n"); + w.write("/**\n"); + w.write(" * Source code generated by org.apache.camel:apt\n"); + w.write(" */\n"); + w.write("public class " + cn + " extends PropertyConfigurerSupport implements TriPropertyConfigurer {\n"); + w.write("\n"); + w.write(" private static final Map<String, TriConsumer<CamelContext, Object, Object>> WRITES;\n"); + w.write(" static {\n"); + w.write(" Map<String, TriConsumer<CamelContext, Object, Object>> map = new HashMap<>(" + size + ");\n"); + for (ComponentOption option : options) { + String getOrSet = option.getName(); + getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1); + String setterLambda = setterLambda(en, getOrSet, option.getType(), option.getConfigurationField()); + w.write(" map.put(\"" + option.getName() + "\", (camelContext, component, value) -> " + setterLambda + ");\n"); + } + w.write(" WRITES = map;\n"); + w.write(" }\n"); + w.write("\n"); + w.write(" @Override\n"); + w.write(" public Map<String, TriConsumer<CamelContext, Object, Object>> getWriteOptions(CamelContext camelContext) {\n"); + w.write(" return WRITES;\n"); + w.write(" }\n"); + w.write("\n"); + w.write("}\n"); + w.write("\n"); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage()); + dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e); + } finally { + IOHelper.close(w); + } + } + + private static String setterLambda(String en, String getOrSet, String type, String configurationField) { + // type may contain generics so remove those + if (type.indexOf('<') != -1) { + type = type.substring(0, type.indexOf('<')); + } + if (configurationField != null) { + getOrSet = "get" + Character.toUpperCase(configurationField.charAt(0)) + configurationField.substring(1) + "().set" + getOrSet; + } else { + getOrSet = "set" + getOrSet; + } + + // ((LogEndpoint) endpoint).setGroupSize(property(camelContext, java.lang.Integer.class, value)) + return String.format("((%s) component).%s(property(camelContext, %s.class, value))", en, getOrSet, type); + } + + public static void generateMetaInfConfigurer(ProcessingEnvironment processingEnv, String name, String fqn) { + try { + FileObject resource = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", + "META-INF/services/org/apache/camel/configurer/" + name); + try (Writer w = resource.openWriter()) { + w.append("# Generated by camel annotation processor\n"); + w.append("class=").append(fqn).append("\n"); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java index 400b03a..8d7d7d6 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java @@ -165,7 +165,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso TypeElement componentClassElement = findTypeElement(processingEnv, roundEnv, componentModel.getJavaType()); if (componentClassElement != null) { - findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData); + findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData, null, null); } findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties(), parentData, null, null); @@ -185,7 +185,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso EndpointPropertyConfigurerGenerator.generateExtendConfigurer(processingEnv, parent, pn, cn, fqn); EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqn); } else if (uriEndpoint.generateConfigurer() && !endpointOptions.isEmpty()) { - TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.support.component.EndpointPropertyConfigurerSupport"); + TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.spi.TriPropertyConfigurer"); String fqen = classElement.getQualifiedName().toString(); String pn = fqen.substring(0, fqen.lastIndexOf('.')); String en = classElement.getSimpleName().toString(); @@ -279,7 +279,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getDisplayName(), "property", required, entry.getType(), defaultValue, doc, entry.isDeprecated(), entry.getDeprecationNote(), entry.isSecret(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), - false, null, asPredicate, optionalPrefix, prefix, multiValue, null, null)); + false, null, asPredicate, optionalPrefix, prefix, multiValue, entry.getConfigurationClass(), entry.getConfigurationField())); parentComponentProperties.remove(entry.getName()); } @@ -508,7 +508,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso protected void findComponentClassProperties(PrintWriter writer, RoundEnvironment roundEnv, ComponentModel componentModel, Set<ComponentOption> componentOptions, TypeElement classElement, String prefix, - Map<String, Object> parentData) { + Map<String, Object> parentData, String nestedTypeName, String nestedFieldName) { Elements elementUtils = processingEnv.getElementUtils(); while (true) { Metadata componentAnnotation = classElement.getAnnotation(Metadata.class); @@ -616,7 +616,7 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly()); ComponentOption option = new ComponentOption(name, displayName, fieldTypeName, required, defaultValue, defaultValueNote, - docComment.trim(), deprecated, deprecationNote, secret, group, label, isEnum, enums); + docComment.trim(), deprecated, deprecationNote, secret, group, label, isEnum, enums, nestedTypeName, nestedFieldName); componentOptions.add(option); } diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java index cda387c..b4619ff 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java @@ -43,7 +43,7 @@ public final class JsonSchemaHelper { public static String toJson(String name, String displayName, String kind, Boolean required, String type, String defaultValue, String description, Boolean deprecated, String deprecationNote, Boolean secret, String group, String label, boolean enumType, Set<String> enums, boolean oneOfType, Set<String> oneOffTypes, boolean asPredicate, String optionalPrefix, String prefix, boolean multiValue, - String configurationClass, String configurtationField) { + String configurationClass, String configurationField) { String typeName = JsonSchemaHelper.getType(type, enumType); StringBuilder sb = new StringBuilder(); @@ -158,9 +158,9 @@ public final class JsonSchemaHelper { sb.append(", \"configurationClass\": "); sb.append(Strings.doubleQuote(configurationClass)); } - if (!Strings.isNullOrEmpty(configurtationField)) { + if (!Strings.isNullOrEmpty(configurationField)) { sb.append(", \"configurationField\": "); - sb.append(Strings.doubleQuote(configurtationField)); + sb.append(Strings.doubleQuote(configurationField)); } if (!Strings.isNullOrEmpty(description)) { diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java index f2b3a53..537594b 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentOption.java @@ -36,10 +36,12 @@ public final class ComponentOption { private String label; private boolean enumType; private Set<String> enums; + private String configurationClass; + private String configurationField; public ComponentOption(String name, String displayName, String type, boolean required, String defaultValue, String defaultValueNote, String documentation, boolean deprecated, String deprecationNote, boolean secret, String group, String label, - boolean enumType, Set<String> enums) { + boolean enumType, Set<String> enums, String configurationClass, String nestedFieldName) { this.name = name; this.displayName = displayName; this.type = type; @@ -54,6 +56,8 @@ public final class ComponentOption { this.label = label; this.enumType = enumType; this.enums = enums; + this.configurationClass = configurationClass; + this.configurationField = nestedFieldName; } public String getName() { @@ -115,6 +119,14 @@ public final class ComponentOption { return enums; } + public String getConfigurationClass() { + return configurationClass; + } + + public String getConfigurationField() { + return configurationField; + } + public String getGroup() { return group; }