use of org.apache.camel.tooling.util.srcgen.Property in project camel-spring-boot by apache.
the class SpringBootAutoConfigurationMojo method createRestConfigurationSource.
private void createRestConfigurationSource(String packageName, EipModel model, String propertiesPrefix) throws MojoFailureException {
final int pos = model.getJavaType().lastIndexOf(".");
final String className = model.getJavaType().substring(pos + 1) + "Properties";
generateDummyClass(packageName + "." + className);
// Common base class
JavaClass javaClass = new JavaClass(getProjectClassLoader());
javaClass.setPackage(packageName);
javaClass.setName(className);
javaClass.addAnnotation(Generated.class).setStringValue("value", SpringBootAutoConfigurationMojo.class.getName());
javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", propertiesPrefix);
String doc = "Generated by camel-package-maven-plugin - do not edit this file!";
if (!Strings.isNullOrEmpty(model.getDescription())) {
doc = model.getDescription() + "\n\n" + doc;
}
javaClass.getJavaDoc().setFullText(doc);
for (EipOptionModel option : model.getOptions()) {
String type = option.getJavaType();
String name = option.getName();
if ("id".equalsIgnoreCase(name) || "parent".equalsIgnoreCase(name) || "camelContext".equalsIgnoreCase(name)) {
// Skip them as they should not be set via spring boot
continue;
}
if ("java.util.List<org.apache.camel.model.PropertyDefinition>".equalsIgnoreCase(type)) {
type = "java.util.Map<java.lang.String, java.lang.String>";
} else if ("java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>".equalsIgnoreCase(type)) {
type = "java.util.Map<java.lang.String, java.lang.Object>";
}
// to avoid ugly names such as c-o-r-s
if ("enableCORS".equalsIgnoreCase(name)) {
name = "enableCors";
}
// generate inner class for non-primitive options
Property prop = javaClass.addProperty(type, name);
if (!Strings.isNullOrEmpty(option.getDescription())) {
prop.getField().getJavaDoc().setFullText(option.getDescription());
}
if (!isBlank(option.getDefaultValue())) {
if ("java.lang.String".equals(type)) {
prop.getField().setStringInitializer(option.getDefaultValue().toString());
} else if ("long".equals(type) || "java.lang.Long".equals(type)) {
// the value should be a Long number
String value = option.getDefaultValue() + "L";
prop.getField().setLiteralInitializer(value);
} else if ("integer".equals(option.getType()) || "java.lang.Integer".equals(option.getJavaType()) || "boolean".equals(option.getType()) || "java.lang.Boolean".equals(option.getJavaType())) {
prop.getField().setLiteralInitializer(option.getDefaultValue().toString());
} else if (!isBlank(option.getEnums())) {
String enumShortName = type.substring(type.lastIndexOf(".") + 1);
prop.getField().setLiteralInitializer(enumShortName + "." + option.getDefaultValue());
javaClass.addImport(model.getJavaType());
}
}
}
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + className + ".java";
writeSourceIfChanged(javaClass, fileName, true);
}
use of org.apache.camel.tooling.util.srcgen.Property in project camel-spring-boot by apache.
the class SpringBootAutoConfigurationMojo method readJavaType.
// read java type from project, returns null if not found
private JavaClass readJavaType(String type) {
if (!type.startsWith("java.lang.") && (!type.contains("<") || !type.contains(">"))) {
String sourceCode = "";
try {
Class<?> clazz = getProjectClassLoader().loadClass(type);
URL url = clazz != null ? getProjectClassLoader().getResource(clazz.getName().replace('.', '/') + ".class") : null;
Artifact mainDep = project.getArtifactMap().get(getMainDepGroupId() + ":" + getMainDepArtifactId());
if (url == null || mainDep == null || !url.toString().contains(mainDep.getFile().toURI().toString())) {
return null;
}
JavaClass nestedType = new JavaClass(getProjectClassLoader()).setPackage(clazz.getPackage().getName()).setName(clazz.getSimpleName()).setEnum(clazz.isEnum()).setClass(!clazz.isInterface()).setAbstract((clazz.getModifiers() & Modifier.ABSTRACT) != 0).setStatic((clazz.getModifiers() & Modifier.STATIC) != 0).extendSuperType(clazz.getGenericSuperclass() != null ? new GenericType(clazz.getGenericSuperclass()).toString() : null);
List<java.lang.reflect.Method> publicMethods = Stream.of(clazz.getDeclaredMethods()).filter(m -> Modifier.isPublic(m.getModifiers())).collect(Collectors.toList());
List<java.lang.reflect.Method> allSetters = publicMethods.stream().filter(m -> m.getReturnType() == void.class || m.getReturnType() == clazz).filter(m -> m.getParameterCount() == 1).filter(m -> m.getName().matches("set[A-Z][a-zA-Z0-9]*")).collect(Collectors.toList());
List<java.lang.reflect.Method> allGetters = publicMethods.stream().filter(m -> m.getReturnType() != void.class).filter(m -> m.getParameterCount() == 0).filter(m -> m.getName().matches("(get|is)[A-Z][a-zA-Z0-9]*")).collect(Collectors.toList());
allSetters.stream().sorted(Comparator.<java.lang.reflect.Method>comparingInt(m -> getSetterPosition(sourceCode, m)).thenComparing(java.lang.reflect.Method::getName)).map(m -> StringUtils.uncapitalize(m.getName().substring(3))).forEach(fn -> {
Class<?> ft;
Type wft;
boolean isBoolean;
java.lang.reflect.Field field = Stream.of(clazz.getDeclaredFields()).filter(f -> f.getName().equals(fn)).findAny().orElse(null);
List<java.lang.reflect.Method> setters = allSetters.stream().filter(m -> m.getName().equals("set" + StringUtils.capitalize(fn))).collect(Collectors.toList());
List<java.lang.reflect.Method> getters = allGetters.stream().filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn)) || m.getName().equals("is" + StringUtils.capitalize(fn))).collect(Collectors.toList());
java.lang.reflect.Method mutator;
java.lang.reflect.Method accessor;
if (setters.size() == 1) {
mutator = setters.get(0);
ft = mutator.getParameterTypes()[0];
wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
isBoolean = ft == boolean.class || ft == Boolean.class;
accessor = allGetters.stream().filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn)) || isBoolean && m.getName().equals("is" + StringUtils.capitalize(fn))).filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getReturnType(), m.getReturnType()) == wft).findAny().orElse(null);
} else if (field != null) {
ft = field.getType();
wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
isBoolean = ft == boolean.class || ft == Boolean.class;
mutator = allSetters.stream().filter(m -> m.getName().equals("set" + StringUtils.capitalize(fn))).filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getParameterTypes()[0], m.getParameterTypes()[0]) == wft).findAny().orElse(null);
accessor = allGetters.stream().filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn)) || isBoolean && m.getName().equals("is" + StringUtils.capitalize(fn))).filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getReturnType(), m.getReturnType()) == wft).findAny().orElse(null);
} else {
if (getters.size() == 1) {
ft = getters.get(0).getReturnType();
} else {
throw new IllegalStateException("Unable to determine type for property " + fn);
}
wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
mutator = setters.stream().filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getParameterTypes()[0], m.getParameterTypes()[0]) == wft).findAny().orElse(null);
accessor = getters.stream().filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getReturnType(), m.getReturnType()) == wft).findAny().orElse(null);
}
if (mutator == null) {
throw new IllegalStateException("Could not find mutator for property " + fn);
}
Property property = nestedType.addProperty(new GenericType(wft), fn);
property.getMutator().getJavaDoc().setText(getSetterJavaDoc(sourceCode, fn));
for (java.lang.annotation.Annotation ann : mutator.getAnnotations()) {
addAnnotation(ac -> property.getMutator().addAnnotation(ac), ann);
}
if (accessor != null) {
for (java.lang.annotation.Annotation ann : accessor.getAnnotations()) {
addAnnotation(ac -> property.getAccessor().addAnnotation(ac), ann);
}
} else {
property.removeAccessor();
}
if (field != null) {
for (java.lang.annotation.Annotation ann : field.getAnnotations()) {
addAnnotation(ac -> property.getField().addAnnotation(ac), ann);
}
} else {
property.removeField();
}
});
return nestedType;
} catch (ClassNotFoundException e) {
return null;
}
}
return null;
}
use of org.apache.camel.tooling.util.srcgen.Property in project camel-spring-boot by apache.
the class SpringBootAutoConfigurationMojo method createEipModelConfigurationSource.
private void createEipModelConfigurationSource(String packageName, EipModel model, String propertiesPrefix, boolean generatedNestedConfig) throws MojoFailureException {
final int pos = model.getJavaType().lastIndexOf(".");
final String commonName = model.getJavaType().substring(pos + 1) + (generatedNestedConfig ? "Common" : "Properties");
final String configName = model.getJavaType().substring(pos + 1) + (generatedNestedConfig ? "Properties" : null);
// Common base class
JavaClass commonClass = new JavaClass(getProjectClassLoader());
commonClass.setPackage(packageName);
commonClass.setName(commonName);
String doc = "Generated by camel-package-maven-plugin - do not edit this file!";
if (!Strings.isNullOrEmpty(model.getDescription())) {
doc = model.getDescription() + "\n\n" + doc;
}
commonClass.getJavaDoc().setFullText(doc);
commonClass.addAnnotation(Generated.class).setStringValue("value", SpringBootAutoConfigurationMojo.class.getName());
for (EipOptionModel option : model.getOptions()) {
String type = option.getJavaType();
String name = option.getName();
if ("id".equalsIgnoreCase(name) || "parent".equalsIgnoreCase(name) || "camelContext".equalsIgnoreCase(name)) {
// Skip them as they should not be set via spring boot
continue;
}
if ("java.util.List<org.apache.camel.model.PropertyDefinition>".equalsIgnoreCase(type)) {
type = "java.util.Map<java.lang.String, java.lang.String>";
}
// generate inner class for non-primitive options
Property prop = commonClass.addProperty(type, option.getName());
if (!Strings.isNullOrEmpty(option.getDescription())) {
prop.getField().getJavaDoc().setFullText(option.getDescription());
}
if (!isBlank(option.getDefaultValue())) {
if ("java.lang.String".equals(type)) {
prop.getField().setStringInitializer(option.getDefaultValue().toString());
} else if ("long".equals(type) || "java.lang.Long".equals(type)) {
// the value should be a Long number
String value = option.getDefaultValue() + "L";
prop.getField().setLiteralInitializer(value);
} else if ("integer".equals(option.getType()) || "java.lang.Integer".equals(option.getJavaType()) || "boolean".equals(option.getType()) || "java.lang.Boolean".equals(option.getJavaType())) {
prop.getField().setLiteralInitializer(option.getDefaultValue().toString());
} else if (!isBlank(option.getEnums())) {
String enumShortName = type.substring(type.lastIndexOf(".") + 1);
prop.getField().setLiteralInitializer(enumShortName + "." + option.getDefaultValue());
commonClass.addImport(model.getJavaType());
}
}
}
writeSourceIfChanged(commonClass, packageName.replaceAll("\\.", "\\/") + "/" + commonName + ".java", true);
Class commonClazz = generateDummyClass(commonClass.getCanonicalName());
// Config class
if (generatedNestedConfig) {
JavaClass configClass = new JavaClass(getProjectClassLoader());
configClass.setPackage(packageName);
configClass.setName(configName);
configClass.extendSuperType(commonClass);
configClass.addAnnotation(Generated.class).setStringValue("value", SpringBootAutoConfigurationMojo.class.getName());
configClass.addAnnotation(loadClass("org.springframework.boot.context.properties.ConfigurationProperties")).setStringValue("prefix", propertiesPrefix);
configClass.addImport(Map.class);
configClass.addImport(HashMap.class);
configClass.removeImport(commonClass);
configClass.addField().setName("enabled").setType(boolean.class).setPrivate().setLiteralInitializer("true").getJavaDoc().setFullText("Enable the component");
configClass.addField().setName("configurations").setType(loadType("java.util.Map<java.lang.String, " + packageName + "." + commonName + ">")).setPrivate().setLiteralInitializer("new HashMap<>()").getJavaDoc().setFullText("Define additional configuration definitions");
Method method;
method = configClass.addMethod();
method.setName("getConfigurations");
method.setReturnType(loadType("java.util.Map<java.lang.String, " + packageName + "." + commonName + ">"));
method.setPublic();
method.setBody("return configurations;");
method = configClass.addMethod();
method.setName("isEnabled");
method.setReturnType(boolean.class);
method.setPublic();
method.setBody("return enabled;");
method = configClass.addMethod();
method.setName("setEnabled");
method.addParameter(boolean.class, "enabled");
method.setPublic();
method.setBody("this.enabled = enabled;");
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + configName + ".java";
writeSourceIfChanged(configClass, fileName, true);
}
}
use of org.apache.camel.tooling.util.srcgen.Property in project camel-spring-boot by apache.
the class SpringBootAutoConfigurationMojo method createDataFormatConfigurationSource.
// CHECKSTYLE:ON
private void createDataFormatConfigurationSource(String packageName, DataFormatModel model, String overrideDataFormatName) throws MojoFailureException {
final JavaClass javaClass = new JavaClass(getProjectClassLoader());
int pos = model.getJavaType().lastIndexOf(".");
String name = model.getJavaType().substring(pos + 1);
name = name.replace("DataFormat", "DataFormatConfiguration");
javaClass.setPackage(packageName).setName(name);
javaClass.extendSuperType("DataFormatConfigurationPropertiesCommon");
javaClass.addImport("org.apache.camel.spring.boot.DataFormatConfigurationPropertiesCommon");
// add bogus field for enabled so spring boot tooling can get the
// javadoc as description in its metadata
Property bogus = javaClass.addProperty("java.lang.Boolean", "enabled");
bogus.getField().getJavaDoc().setText("Whether to enable auto configuration of the " + model.getName() + " data format. This is enabled by default.");
bogus.removeAccessor();
bogus.removeMutator();
String doc = "Generated by camel-package-maven-plugin - do not edit this file!";
if (!Strings.isNullOrEmpty(model.getDescription())) {
doc = model.getDescription() + "\n\n" + doc;
}
javaClass.getJavaDoc().setFullText(doc);
String prefix = "camel.dataformat." + camelCaseToDash(overrideDataFormatName != null ? overrideDataFormatName : model.getName());
// make sure prefix is in lower case
prefix = prefix.toLowerCase(Locale.US);
javaClass.addAnnotation(Generated.class).setStringValue("value", SpringBootAutoConfigurationMojo.class.getName());
javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", prefix);
for (DataFormatOptionModel option : model.getOptions()) {
// skip option with name id in data format as we do not need that
if ("id".equals(option.getName())) {
continue;
}
Object defaultValue = option.getDefaultValue();
String type = option.getJavaType();
type = getSimpleJavaType(type);
// special for bindy
if ("org.apache.camel.model.dataformat.BindyType".equals(option.getJavaType())) {
// force to use a string type
type = "java.lang.String";
defaultValue = null;
} else if (option.getJavaType().contains("org.apache.camel.model.dataformat")) {
// skip options that are from the model as they are not possible to configure anyway
continue;
}
// spring-boot auto configuration does not support complex types
// (unless they are enum, nested)
// and if so then we should use a String type so spring-boot and its
// tooling support that
// as Camel will be able to convert the string value into a lookup
// of the bean in the registry anyway
// and therefore there is no problem, eg
// camel.component.jdbc.data-source = myDataSource
// where the type would have been javax.sql.DataSource
boolean complex = isComplexType(option) && isBlank(option.getEnums());
if (complex) {
// force to use a string type
type = "java.lang.String";
}
Property prop = javaClass.addProperty(type, option.getName());
if (option.isDeprecated()) {
prop.getField().addAnnotation(Deprecated.class);
prop.getAccessor().addAnnotation(Deprecated.class);
prop.getMutator().addAnnotation(Deprecated.class);
// DeprecatedConfigurationProperty must be on getter when
// deprecated
prop.getAccessor().addAnnotation(DeprecatedConfigurationProperty.class);
}
if (!Strings.isNullOrEmpty(option.getDescription())) {
String desc = option.getDescription();
if (complex) {
if (!desc.endsWith(".")) {
desc = desc + ".";
}
desc = desc + " The option is a " + option.getJavaType() + " type.";
}
prop.getField().getJavaDoc().setFullText(desc);
}
if (!isBlank(defaultValue)) {
if ("java.lang.String".equals(option.getJavaType())) {
prop.getField().setStringInitializer(defaultValue.toString());
} else if ("long".equals(option.getJavaType()) || "java.lang.Long".equals(option.getJavaType())) {
// the value should be a Long number
String value = defaultValue + "L";
prop.getField().setLiteralInitializer(value);
} else if ("integer".equals(option.getType()) || "java.lang.Integer".equals(option.getJavaType()) || "boolean".equals(option.getType()) || "java.lang.Boolean".equals(option.getJavaType())) {
prop.getField().setLiteralInitializer(defaultValue.toString());
} else if (!isBlank(option.getEnums())) {
String enumShortName = type.substring(type.lastIndexOf(".") + 1);
prop.getField().setLiteralInitializer(enumShortName + "." + defaultValue);
javaClass.addImport(model.getJavaType());
}
}
}
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
writeSourceIfChanged(javaClass, fileName, true);
}
use of org.apache.camel.tooling.util.srcgen.Property in project camel-spring-boot by apache.
the class SpringBootAutoConfigurationMojo method createComponentConfigurationSource.
private void createComponentConfigurationSource(String packageName, ComponentModel model, String overrideComponentName) throws MojoFailureException {
int pos = model.getJavaType().lastIndexOf(".");
String name = model.getJavaType().substring(pos + 1);
name = name.replace("Component", "ComponentConfiguration");
final JavaClass javaClass = new JavaClass(getProjectClassLoader());
javaClass.setPackage(packageName);
javaClass.setName(name);
javaClass.extendSuperType("ComponentConfigurationPropertiesCommon");
javaClass.addImport("org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon");
// add bogus field for enabled so spring boot tooling can get the
// javadoc as description in its metadata
Property bogus = javaClass.addProperty("java.lang.Boolean", "enabled");
String scheme = overrideComponentName != null ? overrideComponentName : model.getScheme();
bogus.getField().getJavaDoc().setText("Whether to enable auto configuration of the " + scheme + " component. This is enabled by default.");
bogus.removeAccessor();
bogus.removeMutator();
String doc = "Generated by camel-package-maven-plugin - do not edit this file!";
if (!Strings.isNullOrEmpty(model.getDescription())) {
doc = model.getDescription() + "\n\n" + doc;
}
javaClass.getJavaDoc().setText(doc);
String prefix = "camel.component." + camelCaseToDash(overrideComponentName != null ? overrideComponentName : model.getScheme());
// make sure prefix is in lower case
prefix = prefix.toLowerCase(Locale.US);
javaClass.addAnnotation(Generated.class.getName()).setStringValue("value", SpringBootAutoConfigurationMojo.class.getName());
javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", prefix);
for (ComponentOptionModel option : model.getComponentOptions()) {
if (skipComponentOption(model, option)) {
// some component options should be skipped
continue;
}
String type = option.getJavaType();
// generate inner class for non-primitive options
type = getSimpleJavaType(type);
Property prop = javaClass.addProperty(type, option.getName());
if (option.isDeprecated()) {
prop.getField().addAnnotation(Deprecated.class);
prop.getAccessor().addAnnotation(Deprecated.class);
prop.getMutator().addAnnotation(Deprecated.class);
// DeprecatedConfigurationProperty must be on getter when deprecated
prop.getAccessor().addAnnotation(DeprecatedConfigurationProperty.class);
}
if (!Strings.isNullOrEmpty(option.getDescription())) {
String desc = option.getDescription();
boolean complex = isComplexTypeOrDuration(option) && isBlank(option.getEnums());
if (complex) {
if (!desc.endsWith(".")) {
desc = desc + ".";
}
desc = desc + " The option is a " + option.getJavaType() + " type.";
}
prop.getField().getJavaDoc().setFullText(desc);
}
if (!isBlank(option.getDefaultValue())) {
if ("java.lang.String".equals(option.getJavaType())) {
prop.getField().setStringInitializer(option.getDefaultValue().toString());
} else if ("duration".equals(option.getType())) {
String value = convertDurationToMills(option.getDefaultValue().toString());
// duration is either long or int java type
if ("long".equals(option.getJavaType()) || "java.lang.Long".equals(option.getJavaType())) {
value = value + "L";
}
prop.getField().setLiteralInitializer(value);
} else if ("long".equals(option.getJavaType()) || "java.lang.Long".equals(option.getJavaType())) {
// the value should be a Long number
String value = option.getDefaultValue() + "L";
prop.getField().setLiteralInitializer(value);
} else if ("integer".equals(option.getType()) || "java.lang.Integer".equals(option.getJavaType()) || "boolean".equals(option.getType()) || "java.lang.Boolean".equals(option.getJavaType())) {
prop.getField().setLiteralInitializer(option.getDefaultValue().toString());
} else if (!isBlank(option.getEnums())) {
String enumShortName = type.substring(type.lastIndexOf(".") + 1);
prop.getField().setLiteralInitializer(enumShortName + "." + option.getDefaultValue());
javaClass.addImport(model.getJavaType());
}
}
}
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
writeSourceIfChanged(javaClass, fileName, true);
}
Aggregations