diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c6e5fa5730..b2e59d63ecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### Bugs * Fix #5580: [java-generator] Correctly handle defaults for IntOrString types +* Fix #5584: Fix CRD generation when EnumMap is used #### Improvements * Fix #5429: moved crd generator annotations to generator-annotations instead of crd-generator-api. Using generator-annotations introduces no transitive dependencies. diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AdditionalPrinterColumnDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AdditionalPrinterColumnDetector.java index 6eb7ebf5c72..d324801b9e1 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AdditionalPrinterColumnDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AdditionalPrinterColumnDetector.java @@ -17,8 +17,6 @@ import io.fabric8.crd.generator.annotation.PrinterColumn; -import java.util.ArrayList; - public class AdditionalPrinterColumnDetector extends AnnotatedMultiPropertyPathDetector { public AdditionalPrinterColumnDetector() { @@ -26,6 +24,6 @@ public AdditionalPrinterColumnDetector() { } public AdditionalPrinterColumnDetector(String prefix) { - super(prefix, PrinterColumn.class.getSimpleName(), new ArrayList<>()); + super(prefix, PrinterColumn.class.getSimpleName()); } } diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedMultiPropertyPathDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedMultiPropertyPathDetector.java index 2c5d38b83eb..761c9f1b8f4 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedMultiPropertyPathDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedMultiPropertyPathDetector.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Stack; import java.util.stream.Collectors; import static io.fabric8.crd.generator.AbstractJsonSchema.ANNOTATION_JSON_IGNORE; @@ -40,21 +41,19 @@ public class AnnotatedMultiPropertyPathDetector extends TypedVisitor parents; private final Map properties; + private final Stack toRun; public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName) { - this(prefix, annotationName, new ArrayList<>()); - } - - public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName, List parents) { - this(prefix, annotationName, parents, new HashMap<>()); + this(prefix, annotationName, new ArrayList<>(), new HashMap<>(), new Stack<>()); } public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName, List parents, - Map properties) { + Map properties, Stack toRun) { this.prefix = prefix; this.annotationName = annotationName; this.parents = parents; this.properties = properties; + this.toRun = toRun; } private boolean excludePropertyProcessing(Property p) { @@ -84,15 +83,20 @@ public void visit(TypeDefBuilder builder) { if (!parents.contains(p) && !excludePropertyProcessing(p)) { ClassRef classRef = (ClassRef) p.getTypeRef(); TypeDef propertyType = Types.typeDefFrom(classRef); - if (!propertyType.isEnum()) { + if (!propertyType.isEnum() && !classRef.getPackageName().startsWith("java.")) { List newParents = new ArrayList<>(parents); newParents.add(p); - new TypeDefBuilder(propertyType) - .accept(new AnnotatedMultiPropertyPathDetector(prefix, annotationName, newParents, properties)) - .build(); + toRun.add(() -> new TypeDefBuilder(propertyType) + .accept(new AnnotatedMultiPropertyPathDetector(prefix, annotationName, newParents, properties, toRun))); } } }); + + if (parents.isEmpty()) { + while (!toRun.isEmpty()) { + toRun.pop().run(); + } + } } public Set getPaths() { diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedPropertyPathDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedPropertyPathDetector.java index 5ae2ee8c222..2c91d89719b 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedPropertyPathDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/AnnotatedPropertyPathDetector.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Stack; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -39,22 +40,20 @@ public class AnnotatedPropertyPathDetector extends TypedVisitor private final String prefix; private final String annotationName; private final List parents; - private final AtomicReference> reference; + private final AtomicReference reference; + private final Stack toRun; public AnnotatedPropertyPathDetector(String prefix, String annotationName) { - this(prefix, annotationName, new ArrayList<>()); - } - - public AnnotatedPropertyPathDetector(String prefix, String annotationName, List parents) { - this(prefix, annotationName, parents, new AtomicReference<>(Optional.empty())); + this(prefix, annotationName, new ArrayList<>(), new AtomicReference<>(), new Stack<>()); } public AnnotatedPropertyPathDetector(String prefix, String annotationName, List parents, - AtomicReference> reference) { + AtomicReference reference, Stack toRun) { this.prefix = prefix; this.annotationName = annotationName; this.parents = parents; this.reference = reference; + this.toRun = toRun; } private static boolean excludePropertyProcessing(Property p) { @@ -70,52 +69,48 @@ private static boolean excludePropertyProcessing(Property p) { public void visit(TypeDefBuilder builder) { TypeDef type = builder.build(); final List properties = type.getProperties(); - if (visitProperties(properties)) { - return; - } - visitPropertiesClasses(properties); + visitProperties(properties); } - private void visitPropertiesClasses(List properties) { + private void visitProperties(List properties) { for (Property p : properties) { + if (parents.contains(p)) { + continue; + } + + List newParents = new ArrayList<>(parents); + boolean match = false; + for (AnnotationRef annotation : p.getAnnotations()) { + match = annotation.getClassRef().getName().equals(annotationName); + if (match) { + newParents.add(p); + reference.set(newParents.stream().map(Property::getName).collect(Collectors.joining(DOT, prefix, ""))); + return; + } + } + if (!(p.getTypeRef() instanceof ClassRef)) { continue; } if (!parents.contains(p) && !excludePropertyProcessing(p)) { ClassRef classRef = (ClassRef) p.getTypeRef(); TypeDef propertyType = Types.typeDefFrom(classRef); - if (!propertyType.isEnum()) { - List newParents = new ArrayList<>(parents); + if (!propertyType.isEnum() && !classRef.getPackageName().startsWith("java.")) { newParents.add(p); new TypeDefBuilder(propertyType) - .accept(new AnnotatedPropertyPathDetector(prefix, annotationName, newParents, reference)) - .build(); + .accept(new AnnotatedPropertyPathDetector(prefix, annotationName, newParents, reference, toRun)); } } } - } - private boolean visitProperties(List properties) { - for (Property p : properties) { - if (parents.contains(p)) { - continue; - } - - List newParents = new ArrayList<>(parents); - boolean match = false; - for (AnnotationRef annotation : p.getAnnotations()) { - match = annotation.getClassRef().getName().equals(annotationName); - if (match) { - newParents.add(p); - reference.set(Optional.of(newParents.stream().map(Property::getName).collect(Collectors.joining(DOT, prefix, "")))); - return true; - } + if (parents.isEmpty()) { + while (!toRun.isEmpty() && reference.get() == null) { + toRun.pop().run(); } } - return false; } public Optional getPath() { - return reference.get(); + return Optional.ofNullable(reference.get()); } } diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/LabelSelectorPathDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/LabelSelectorPathDetector.java index dda802865e9..ff4609c084f 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/LabelSelectorPathDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/LabelSelectorPathDetector.java @@ -17,8 +17,6 @@ import io.fabric8.kubernetes.model.annotation.LabelSelector; -import java.util.ArrayList; - public class LabelSelectorPathDetector extends AnnotatedPropertyPathDetector { public LabelSelectorPathDetector() { @@ -26,6 +24,6 @@ public LabelSelectorPathDetector() { } public LabelSelectorPathDetector(String prefix) { - super(prefix, LabelSelector.class.getSimpleName(), new ArrayList<>()); + super(prefix, LabelSelector.class.getSimpleName()); } } diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/SpecReplicasPathDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/SpecReplicasPathDetector.java index 74d2ac3b758..9513166ec09 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/SpecReplicasPathDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/SpecReplicasPathDetector.java @@ -17,8 +17,6 @@ import io.fabric8.kubernetes.model.annotation.SpecReplicas; -import java.util.ArrayList; - public class SpecReplicasPathDetector extends AnnotatedPropertyPathDetector { public SpecReplicasPathDetector() { @@ -26,6 +24,6 @@ public SpecReplicasPathDetector() { } public SpecReplicasPathDetector(String prefix) { - super(prefix, SpecReplicas.class.getSimpleName(), new ArrayList<>()); + super(prefix, SpecReplicas.class.getSimpleName()); } } diff --git a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/StatusReplicasPathDetector.java b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/StatusReplicasPathDetector.java index f982bdf1166..a573cbeffc7 100644 --- a/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/StatusReplicasPathDetector.java +++ b/crd-generator/api/src/main/java/io/fabric8/crd/generator/visitor/StatusReplicasPathDetector.java @@ -17,12 +17,10 @@ import io.fabric8.kubernetes.model.annotation.StatusReplicas; -import java.util.ArrayList; - public class StatusReplicasPathDetector extends AnnotatedPropertyPathDetector { public StatusReplicasPathDetector(String prefix) { - super(prefix, StatusReplicas.class.getSimpleName(), new ArrayList<>()); + super(prefix, StatusReplicas.class.getSimpleName()); } diff --git a/crd-generator/api/src/test/java/io/fabric8/crd/example/map/ContainingMaps.java b/crd-generator/api/src/test/java/io/fabric8/crd/example/map/ContainingMaps.java index 0bc432d06fe..a4a4913d141 100644 --- a/crd-generator/api/src/test/java/io/fabric8/crd/example/map/ContainingMaps.java +++ b/crd-generator/api/src/test/java/io/fabric8/crd/example/map/ContainingMaps.java @@ -19,8 +19,14 @@ import io.fabric8.kubernetes.model.annotation.Group; import io.fabric8.kubernetes.model.annotation.Version; +import java.util.EnumMap; + @Group("map.fabric8.io") @Version("v1alpha1") public class ContainingMaps extends CustomResource { + public enum Foo { BAR } + + private EnumMap enumToStringMap; + }