CAMEL-10197: Exclude abstract classes and classes with no fields from being converted into nested configuration property classes for spring boot
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/fa6ee0b0 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/fa6ee0b0 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/fa6ee0b0 Branch: refs/heads/master Commit: fa6ee0b0cb60f21f4117b240942081b9e69a2ccd Parents: 0f7163e Author: Dhiraj Bokde <dhira...@yahoo.com> Authored: Fri Sep 2 10:21:48 2016 -0700 Committer: Dhiraj Bokde <dhira...@yahoo.com> Committed: Tue Sep 20 07:30:24 2016 -0700 ---------------------------------------------------------------------- .../SpringBootAutoConfigurationMojo.java | 69 +++++++++++++++----- 1 file changed, 54 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/fa6ee0b0/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java ---------------------------------------------------------------------- diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java index d1529b1..c6068c38 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -333,7 +334,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { type = getSimpleJavaType(type); // generate inner class for non-primitive options - if (isNestedProperty(type, project, nestedTypes)) { + if (isNestedProperty(type, nestedTypes)) { type = option.getShortJavaType() + INNER_TYPE_SUFFIX; } @@ -380,18 +381,14 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { .setLiteralInitializer(nestedType.getCanonicalName() + ".class"); // parse option type - for (PropertySource<JavaClassSource> sourceProp : nestedType.getProperties()) { + for (ResolvedProperty resolvedProperty : getProperties(nestedType)) { - final MethodSource<JavaClassSource> mutator = sourceProp.getMutator(); - // NOTE: fields with no setters are skipped - if (mutator == null) { - continue; - } + String optionType = resolvedProperty.propertyType; + PropertySource<JavaClassSource> sourceProp = resolvedProperty.propertySource; - // strip array dimensions Type<JavaClassSource> propType = sourceProp.getType(); - final String optionType = getSimpleJavaType(resolveParamType(nestedType, propType.getName())); final PropertySource<JavaClassSource> prop = innerClass.addProperty(optionType, sourceProp.getName()); + boolean anEnum; Class optionClass; if (!propType.isArray()) { @@ -415,6 +412,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { } String description = null; + final MethodSource<JavaClassSource> mutator = sourceProp.getMutator(); if (mutator.hasJavaDoc()) { description = mutator.getJavaDoc().getFullText(); } else if (sourceProp.hasField()) { @@ -451,6 +449,34 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { writeSourceIfChanged(javaClass, fileName); } + // resolved property type name and property source, Roaster doesn't resolve inner classes correctly + private class ResolvedProperty { + private String propertyType; + private PropertySource<JavaClassSource> propertySource; + + public ResolvedProperty(String propertyType, PropertySource<JavaClassSource> propertySource) { + this.propertyType = propertyType; + this.propertySource = propertySource; + } + } + + // get properties for nested type and super types, only properties with setters are supported!!! + private List<ResolvedProperty> getProperties(JavaClassSource nestedType) { + final List<ResolvedProperty> properties = new ArrayList<>(); + final Set<String> names = new HashSet<>(); + do { + for (PropertySource<JavaClassSource> propertySource : nestedType.getProperties()) { + // NOTE: fields with no setters are skipped + if (propertySource.isMutable() && !names.contains(propertySource.getName())) { + properties.add(new ResolvedProperty(getSimpleJavaType(resolveParamType(nestedType, propertySource.getType().getName())), propertySource)); + names.add(propertySource.getName()); + } + } + nestedType = readJavaType(nestedType.getSuperType()); + } while (nestedType != null); + return properties; + } + // try loading class, looking for inner classes if needed private Class loadClass(ClassLoader projectClassLoader, String loadClassName) throws MojoFailureException { Class optionClass; @@ -514,9 +540,23 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { return type; } - // it's a nested property if the source exists in this project, e.g. endpoint configuration - private boolean isNestedProperty(String type, MavenProject project, Set<JavaClassSource> nestedTypes) { - boolean nested = false; + // it's a nested property if the source exists and it's not an abstract class in this project, e.g. endpoint configuration + private boolean isNestedProperty(String type, Set<JavaClassSource> nestedTypes) { + JavaClassSource nestedType = readJavaType(type); + if (nestedType != null) { + // nested type MUST have some properties of it's own, besides those from super class + if (!nestedType.isAbstract() && !nestedType.getProperties().isEmpty()) { + nestedTypes.add(nestedType); + } else { + nestedType = null; + } + } + return nestedType != null; + } + + // read java type from project, returns null if not found + private JavaClassSource readJavaType(String type) { + JavaClassSource nestedType = null; if (!type.startsWith("java.lang.")) { final String fileName = type.replaceAll("[\\[\\]]", "").replaceAll("\\.", "\\/") + ".java"; @@ -527,8 +567,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { try { JavaType<?> classSource = Roaster.parse(sourceFile); if (classSource instanceof JavaClassSource) { - nestedTypes.add((JavaClassSource) classSource); - nested = true; + nestedType = (JavaClassSource) classSource; break; } } catch (FileNotFoundException e) { @@ -537,7 +576,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { } } } - return nested; + return nestedType; } // CHECKSTYLE:OFF