Skip to content

Commit

Permalink
Backport fabric8io#5588 commit f54242d
Browse files Browse the repository at this point in the history
  • Loading branch information
bequinn-hubspot committed Nov 20, 2023
1 parent b8fafc4 commit fa3bacf
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public AdditionalPrinterColumnDetector() {
}

public AdditionalPrinterColumnDetector(String prefix) {
super(prefix, PrinterColumn.class.getSimpleName(), new ArrayList<>());
super(prefix, PrinterColumn.class.getSimpleName());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@
import io.sundr.model.Property;
import io.sundr.model.TypeDef;
import io.sundr.model.TypeDefBuilder;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static io.fabric8.crd.generator.AbstractJsonSchema.ANNOTATION_JSON_IGNORE;

public class AnnotatedMultiPropertyPathDetector extends TypedVisitor<TypeDefBuilder> {

protected static final String DOT = ".";
Expand All @@ -37,54 +42,62 @@ public class AnnotatedMultiPropertyPathDetector extends TypedVisitor<TypeDefBuil
private final String annotationName;
private final List<Property> parents;
private final Map<String, Property> properties;
private final Deque<Runnable> toRun;

public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName) {
this(prefix, annotationName, new ArrayList<>());
}

public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName, List<Property> parents) {
this(prefix, annotationName, parents, new HashMap<>());
this(prefix, annotationName, new ArrayList<>(), new HashMap<>(), new ArrayDeque<>());
}

public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName, List<Property> parents, Map<String, Property> properties) {
public AnnotatedMultiPropertyPathDetector(String prefix, String annotationName, List<Property> parents,
Map<String, Property> properties, Deque<Runnable> toRun) {
this.prefix = prefix;
this.annotationName = annotationName;
this.parents = parents;
this.properties = properties;
this.toRun = toRun;
}

private boolean excludePropertyProcessing(Property p) {
return p.getAnnotations().stream()
.anyMatch(ann -> ann.getClassRef().getFullyQualifiedName().equals(ANNOTATION_JSON_IGNORE));
}

@Override
public void visit(TypeDefBuilder builder) {
TypeDef type = builder.build();
final List<Property> props = type.getProperties();
for (Property p : props) {
if (parents.contains(p)) {
continue;
}
if (parents.contains(p)) {
continue;
}

List<Property> newParents = new ArrayList<>(parents);
boolean match = p.getAnnotations().stream().anyMatch(a -> a.getClassRef().getName().equals(annotationName));
if (match) {
newParents.add(p);
this.properties
.put(newParents.stream().map(Property::getName).collect(Collectors.joining(DOT, prefix, "")), p);
}
List<Property> newParents = new ArrayList<>(parents);
boolean match = p.getAnnotations().stream().anyMatch(a -> a.getClassRef().getName().equals(annotationName));
if (match) {
newParents.add(p);
this.properties
.put(newParents.stream().map(Property::getName).collect(Collectors.joining(DOT, prefix, "")), p);
}
}

props.stream().filter(p -> p.getTypeRef() instanceof ClassRef).forEach(p -> {
if (!parents.contains(p)) {
ClassRef classRef = (ClassRef) p.getTypeRef();
TypeDef propertyType = Types.typeDefFrom(classRef);
if (!propertyType.isEnum()) {
List<Property> newParents = new ArrayList<>(parents);
newParents.add(p);
new TypeDefBuilder(propertyType)
.accept(new AnnotatedMultiPropertyPathDetector(prefix, annotationName, newParents,
this.properties))
.build();
}
if (!parents.contains(p) && !excludePropertyProcessing(p)) {
ClassRef classRef = (ClassRef) p.getTypeRef();
TypeDef propertyType = Types.typeDefFrom(classRef);
if (!propertyType.isEnum() && !classRef.getPackageName().startsWith("java.")) {
List<Property> newParents = new ArrayList<>(parents);
newParents.add(p);
toRun.add(() -> new TypeDefBuilder(propertyType)
.accept(new AnnotatedMultiPropertyPathDetector(prefix, annotationName, newParents, properties, toRun)));
}
});
}
});

if (parents.isEmpty()) {
while (!toRun.isEmpty()) {
toRun.pop().run();
}
}
}

public Set<String> getPaths() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@

import io.fabric8.crd.generator.utils.Types;
import io.sundr.builder.TypedVisitor;
import io.sundr.model.AnnotationRef;
import io.sundr.model.ClassRef;
import io.sundr.model.Property;
import io.sundr.model.TypeDef;
import io.sundr.model.TypeDefBuilder;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static io.fabric8.crd.generator.AbstractJsonSchema.ANNOTATION_JSON_IGNORE;

public class AnnotatedPropertyPathDetector extends TypedVisitor<TypeDefBuilder> {

protected static final String DOT = ".";
Expand All @@ -35,59 +41,74 @@ public class AnnotatedPropertyPathDetector extends TypedVisitor<TypeDefBuilder>
private final String prefix;
private final String annotationName;
private final List<Property> parents;
private final AtomicReference<Optional<String>> reference;
private final AtomicReference<String> reference;
private final Deque<Runnable> toRun;

public AnnotatedPropertyPathDetector(String prefix, String annotationName) {
this(prefix, annotationName, new ArrayList<>());
}

public AnnotatedPropertyPathDetector(String prefix, String annotationName, List<Property> parents) {
this(prefix, annotationName, parents, new AtomicReference<>(Optional.empty()));
this(prefix, annotationName, new ArrayList<>(), new AtomicReference<>(), new ArrayDeque<>());
}

public AnnotatedPropertyPathDetector(String prefix, String annotationName, List<Property> parents, AtomicReference<Optional<String>> reference) {
public AnnotatedPropertyPathDetector(String prefix, String annotationName, List<Property> parents,
AtomicReference<String> reference, Deque<Runnable> toRun) {
this.prefix = prefix;
this.annotationName = annotationName;
this.parents = parents;
this.reference = reference;
this.toRun = toRun;
}

private static boolean excludePropertyProcessing(Property p) {
for (AnnotationRef annotation : p.getAnnotations()) {
if (annotation.getClassRef().getFullyQualifiedName().equals(ANNOTATION_JSON_IGNORE)) {
return true;
}
}
return false;
}

@Override
public void visit(TypeDefBuilder builder) {
TypeDef type = builder.build();
final List<Property> properties = type.getProperties();
visitProperties(properties);
}

private void visitProperties(List<Property> properties) {
for (Property p : properties) {
if (parents.contains(p)) {
continue;
}
continue;
}

List<Property> newParents = new ArrayList<>(parents);
boolean match = p.getAnnotations().stream().anyMatch(a -> a.getClassRef().getName().equals(annotationName));
List<Property> 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, ""))));
reference.set(newParents.stream().map(Property::getName).collect(Collectors.joining(DOT, prefix, "")));
return;
}
}
}

properties.stream()
.filter(p -> p.getTypeRef() instanceof ClassRef)
.forEach(p -> {
if (!parents.contains(p)) {
ClassRef classRef = (ClassRef) p.getTypeRef();
TypeDef propertyType = Types.typeDefFrom(classRef);
if (!propertyType.isEnum()) {
List<Property> newParents = new ArrayList<>(parents);
newParents.add(p);
new TypeDefBuilder(propertyType)
.accept(new AnnotatedPropertyPathDetector(prefix, annotationName, newParents, reference))
.build();
}
if (p.getTypeRef() instanceof ClassRef && !excludePropertyProcessing(p)) {
ClassRef classRef = (ClassRef) p.getTypeRef();
TypeDef propertyType = Types.typeDefFrom(classRef);
if (!propertyType.isEnum() && !classRef.getPackageName().startsWith("java.")) {
newParents.add(p);
new TypeDefBuilder(propertyType)
.accept(new AnnotatedPropertyPathDetector(prefix, annotationName, newParents, reference, toRun));
}
});
}
}

if (parents.isEmpty()) {
while (!toRun.isEmpty() && reference.get() == null) {
toRun.pop().run();
}
}
}

public Optional<String> getPath() {
return reference.get();
return Optional.ofNullable(reference.get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ public LabelSelectorPathDetector() {
}

public LabelSelectorPathDetector(String prefix) {
super(prefix, LabelSelector.class.getSimpleName(), new ArrayList<>());
super(prefix, LabelSelector.class.getSimpleName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public SpecReplicasPathDetector() {
this(DOT);
}
public SpecReplicasPathDetector(String prefix) {
super(prefix, SpecReplicas.class.getSimpleName(), new ArrayList<>());
super(prefix, SpecReplicas.class.getSimpleName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class StatusReplicasPathDetector extends AnnotatedPropertyPathDetector {

public StatusReplicasPathDetector(String prefix) {
super(prefix, StatusReplicas.class.getSimpleName(), new ArrayList<>());
super(prefix, StatusReplicas.class.getSimpleName());

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.fabric8.crd.example.map;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;

Expand All @@ -32,4 +33,10 @@ public Map<String, Map<String, List<Boolean>>> getTest2() {
return test2;
}

public enum Foo {
BAR
}

private EnumMap<Foo, String> enumToStringMap;

}
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ void mapPropertyShouldHaveCorrectValueType() {
final Map<String, JSONSchemaProps> specProps = version.getSchema().getOpenAPIV3Schema()
.getProperties().get("spec").getProperties();

assertEquals(2, specProps.size());
assertEquals(3, specProps.size());

checkMapProp(specProps, "test", "array");
String arrayType = specProps.get("test").getAdditionalProperties().getSchema().getItems().getSchema().getType();
Expand Down

0 comments on commit fa3bacf

Please sign in to comment.