blob: 85e5000a7bcbb05e4651c9bd738b5b54349f0a5a [file] [log] [blame]
/*
* 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.Writer;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import org.apache.camel.tools.apt.helper.IOHelper;
import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile;
public final class PropertyPlaceholderGenerator {
private PropertyPlaceholderGenerator() {
}
public static void generatePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, TypeElement parent,
String def, String fqnDef, String cn, String fqn,
Set<CoreEipAnnotationProcessorHelper.EipOption> options) {
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 org.apache.camel.model.placeholder;\n");
w.write("\n");
w.write("import java.util.HashMap;\n");
w.write("import java.util.Map;\n");
w.write("import java.util.function.Consumer;\n");
w.write("import java.util.function.Supplier;\n");
w.write("\n");
w.write("import org.apache.camel.CamelContext;\n");
w.write("import " + fqnDef + ";\n");
w.write("import org.apache.camel.spi.PropertyPlaceholderConfigurer;\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 + " implements PropertyPlaceholderConfigurer {\n");
w.write("\n");
w.write(" private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();\n");
w.write(" private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();\n");
w.write("\n");
// add constructor
w.write(" public " + cn + "(Object obj) {\n");
w.write(" " + def + " definition = (" + def + ") obj;\n");
w.write("\n");
// only include string types as they are the only ones we can use for property placeholders
boolean found = false;
for (CoreEipAnnotationProcessorHelper.EipOption option : options) {
if ("java.lang.String".equals(option.getType())) {
found = true;
String getOrSet = sanitizePropertyPlaceholderOptionName(def, option);
getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
w.write(" readPlaceholders.put(\"" + option.getName() + "\", definition::get" + getOrSet + ");\n");
w.write(" writePlaceholders.put(\"" + option.getName() + "\", definition::set" + getOrSet + ");\n");
}
}
if (!found) {
w.write("\n");
}
w.write(" }\n");
w.write("\n");
w.write(" @Override\n");
w.write(" public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {\n");
w.write(" return readPlaceholders;\n");
w.write(" }\n");
w.write("\n");
w.write(" @Override\n");
w.write(" public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {\n");
w.write(" return writePlaceholders;\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);
}
}
public static void generatePropertyPlaceholderDefinitionsHelper(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv,
Set<String> propertyPlaceholderDefinitions) {
String fqn = "org.apache.camel.model.placeholder.DefinitionPropertiesPlaceholderProviderHelper";
Writer w = null;
try {
JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn);
w = src.openWriter();
w.write("/* Generated by camel-apt */\n");
w.write("package org.apache.camel.model.placeholder;\n");
w.write("\n");
w.write("import java.util.HashMap;\n");
w.write("import java.util.Map;\n");
w.write("import java.util.Optional;\n");
w.write("import java.util.function.Function;\n");
w.write("import java.util.function.Supplier;\n");
w.write("\n");
w.write("import org.apache.camel.spi.PropertyPlaceholderConfigurer;\n");
for (String def : propertyPlaceholderDefinitions) {
w.write("import " + def + ";\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 DefinitionPropertiesPlaceholderProviderHelper {\n");
w.write("\n");
w.write(" private static final Map<Class, Function<Object, PropertyPlaceholderConfigurer>> MAP;\n");
w.write(" static {\n");
w.write(" Map<Class, Function<Object, PropertyPlaceholderConfigurer>> map = new HashMap<>(" + propertyPlaceholderDefinitions.size() + ");\n");
for (String def : propertyPlaceholderDefinitions) {
String cn = def.substring(def.lastIndexOf('.') + 1);
w.write(" map.put(" + cn + ".class, " + cn + "PropertyPlaceholderProvider::new);\n");
}
w.write(" MAP = map;\n");
w.write(" }\n");
w.write("\n");
w.write(" public static Optional<PropertyPlaceholderConfigurer> provider(Object definition) {\n");
w.write(" Function<Object, PropertyPlaceholderConfigurer> func = MAP.get(definition.getClass());\n");
w.write(" if (func != null) {\n");
w.write(" return Optional.of(func.apply(definition));\n");
w.write(" }\n");
w.write(" return Optional.empty();\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);
}
}
/**
* Some models have different setter/getter names vs the xml name (eg as defined in @XmlAttribute).
* So we need to correct this using this method.
*/
private static String sanitizePropertyPlaceholderOptionName(String def, CoreEipAnnotationProcessorHelper.EipOption option) {
if ("SimpleExpression".equals(def) || "JsonPathExpression".equals(def)) {
if ("resultType".equals(option.getName())) {
return "resultTypeName";
}
} else if ("EnrichDefinition".equals(def) || "PollEnrichDefinition".equals(def) || "ClaimCheckDefinition".equals(def)) {
if ("strategyRef".equals(option.getName())) {
return "aggregationStrategyRef";
} else if ("strategyMethodName".equals(option.getName())) {
return "aggregationStrategyMethodName";
} else if ("strategyMethodAllowNull".equals(option.getName())) {
return "aggregationStrategyMethodAllowNull";
}
} else if ("MethodCallExpression".equals(def)) {
if ("beanType".equals(option.getName())) {
return "beanTypeName";
}
} else if ("XPathExpression".equals(def)) {
if ("documentType".equals(option.getName())) {
return "documentTypeName";
} else if ("resultType".equals(option.getName())) {
return "resultTypeName";
}
} else if ("WireTapDefinition".equals(def)) {
if ("processorRef".equals(option.getName())) {
return "newExchangeProcessorRef";
}
} else if ("TidyMarkupDataFormat".equals(def)) {
if ("dataObjectType".equals(option.getName())) {
return "dataObjectTypeName";
}
} else if ("BindyDataFormat".equals(def)) {
if ("classType".equals(option.getName())) {
return "classTypeAsString";
}
}
return option.getName();
}
}