diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f701a4ace3..26092b9ca8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ #### New Features +* Fix #7045: (java-generator) Extend the existingJavaTypes to support use of existing enumerations + #### _**Note**_: Breaking changes ### 6.14.0 (2025-06-10) diff --git a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/AbstractJSONSchema2Pojo.java b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/AbstractJSONSchema2Pojo.java index 7cc80a256f2..316bafda09a 100644 --- a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/AbstractJSONSchema2Pojo.java +++ b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/AbstractJSONSchema2Pojo.java @@ -327,6 +327,7 @@ private static AbstractJSONSchema2Pojo fromJsonSchema( throw new JavaGeneratorException("Unsupported enumeration type/format: " + prop.getType() + "/" + prop.getFormat()); } return new JEnum( + parentPkg, key, enumType, prop.getEnum(), diff --git a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JEnum.java b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JEnum.java index 094650f2038..9d59993b7e6 100644 --- a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JEnum.java +++ b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JEnum.java @@ -47,20 +47,38 @@ public class JEnum extends AbstractJSONSchema2Pojo { private final String underlyingType; private final Set values; //Let's prevent duplicates - public JEnum(String type, String underlyingType, List values, Config config, String description, - final boolean isNullable, - JsonNode defaultValue) { + // Used for matching against existing types. + private final String pkgPrefixedType; + + public JEnum(String pkg, String type, String underlyingType, List values, Config config, String description, + final boolean isNullable, JsonNode defaultValue) { super(config, description, isNullable, defaultValue, null); this.type = AbstractJSONSchema2Pojo.sanitizeString( type.substring(0, 1).toUpperCase() + type.substring(1)); this.underlyingType = underlyingType; //Tests assume order so let's use LinkedHashSet instead of just using Collectors.toSet() this.values = values.stream().map(JsonNode::asText).collect(Collectors.toCollection(LinkedHashSet::new)); + this.pkgPrefixedType = createPackagePrefixedType(pkg, this.type); + } + + /** + * @deprecated use {@link #JEnum(String, String, String, List, Config, String, boolean, JsonNode)} + */ + @Deprecated + public JEnum(String type, String underlyingType, List values, Config config, String description, + final boolean isNullable, JsonNode defaultValue) { + this(null, type, underlyingType, values, config, description, isNullable, defaultValue); + } + + private String createPackagePrefixedType(String pkg, String type) { + String p = (pkg == null) ? "" : pkg.trim(); + String pkgPrefix = (p.isEmpty()) ? p : p + "."; + return pkgPrefix + type; } @Override public String getType() { - return this.type; + return config.getExistingJavaTypes().getOrDefault(this.pkgPrefixedType, this.type); } private String sanitizeEnumEntry(final String str) { @@ -93,6 +111,10 @@ private Statement generateBooleanCreator(boolean hasTrue, boolean hasFalse) { @Override public GeneratorResult generateJava() { + if (config.getExistingJavaTypes().containsKey(pkgPrefixedType)) { + return new GeneratorResult(Collections.emptyList()); + } + CompilationUnit cu = new CompilationUnit(); EnumDeclaration en = cu.addEnum(this.type); diff --git a/java-generator/core/src/test/java/io/fabric8/java/generator/GeneratorTest.java b/java-generator/core/src/test/java/io/fabric8/java/generator/GeneratorTest.java index c4565230e29..efe5d9e447f 100644 --- a/java-generator/core/src/test/java/io/fabric8/java/generator/GeneratorTest.java +++ b/java-generator/core/src/test/java/io/fabric8/java/generator/GeneratorTest.java @@ -448,6 +448,7 @@ void testDefaultEnum() { enumValues.add(new TextNode("baz")); props.put("e1", newEnum); JEnum enu = new JEnum( + "pkg", "t", JAVA_LANG_STRING, enumValues, @@ -484,6 +485,7 @@ void testLongEnum() { enumValues.add(new TextNode("3")); props.put("e1", newEnum); JEnum enu = new JEnum( + "pkg", "t", JAVA_LANG_LONG, enumValues, @@ -524,6 +526,7 @@ void testIntEnum() { enumValues.add(new TextNode("3")); props.put("e1", newEnum); JEnum enu = new JEnum( + "pkg", "t", JAVA_LANG_INTEGER, enumValues, @@ -562,6 +565,7 @@ void testBooleanEnum() { enumValues.add(new TextNode("false")); props.put("e1", newEnum); JEnum enu = new JEnum( + "pkg", "t", JAVA_PRIMITIVE_BOOLEAN, enumValues, @@ -600,6 +604,7 @@ void testNotUppercaseEnum() { enumValues.add(new TextNode("baz")); props.put("e1", newEnum); JEnum enu = new JEnum( + "pkg", "t", JAVA_LANG_STRING, enumValues, @@ -624,6 +629,32 @@ void testNotUppercaseEnum() { assertEquals("baz", en.get().getEntries().get(2).getName().asString()); } + @Test + void testEnumDeprecatedConstructor() { + // Arrange + JSONSchemaProps newEnum = new JSONSchemaProps(); + newEnum.setType("string"); + JEnum enu = new JEnum( + "t", + JAVA_LANG_STRING, + List.of(), + defaultConfig, + null, + Boolean.FALSE, + null); + + // Act + GeneratorResult res = enu.generateJava(); + + // Assert + assertEquals("T", enu.getType()); + assertEquals(1, res.getInnerClasses().size()); + assertEquals("T", res.getInnerClasses().get(0).getName()); + + Optional en = res.getInnerClasses().get(0).getEnumByName("T"); + assertTrue(en.isPresent()); + } + @Test void testArrayOfObjects() { // Arrange @@ -1087,4 +1118,27 @@ void testExistingJavaTypeObject() { assertEquals("org.test.ExistingJavaType", obj.getType()); assertEquals(0, res.getTopLevelClasses().size()); } + + @Test + void testExistingJavaTypeEnum() { + // Arrange + Config config = Config.builder() + .existingJavaTypes(Collections.singletonMap("v1alpha1.E", "org.test.ExistingJavaEnum")).build(); + JEnum obj = new JEnum( + "v1alpha1", + "E", + JAVA_LANG_STRING, + List.of(), + config, + null, + Boolean.FALSE, + null); + + // Act + GeneratorResult res = obj.generateJava(); + + // Assert + assertEquals("org.test.ExistingJavaEnum", obj.getType()); + assertEquals(0, res.getTopLevelClasses().size()); + } } diff --git a/java-generator/it/src/it/existing-java-types/pom.xml b/java-generator/it/src/it/existing-java-types/pom.xml index cf107634d03..3b0274aabdd 100644 --- a/java-generator/it/src/it/existing-java-types/pom.xml +++ b/java-generator/it/src/it/existing-java-types/pom.xml @@ -72,9 +72,14 @@ src/main/resources/existing-java-type-crd.yml false + io.fabric8.kubernetes.api.model.Affinity + + + io.fabric8.kubernetes.api.model.DeletionPropagation + diff --git a/java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java b/java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java index 0edf13060e7..f982091a671 100644 --- a/java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java +++ b/java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java @@ -17,10 +17,12 @@ import com.example.v1.ExistingJavaTypeSpec; import io.fabric8.kubernetes.api.model.Affinity; +import io.fabric8.kubernetes.api.model.DeletionPropagation; public class ExistingJavaTypes { public void example() { ExistingJavaTypeSpec existingJavaTypeSpec = new ExistingJavaTypeSpec(); existingJavaTypeSpec.setAffinity(new Affinity()); + existingJavaTypeSpec.setDeletionPropagation(DeletionPropagation.ORPHAN); } } diff --git a/java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml b/java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml index 17185cbb742..bf7c73eb453 100644 --- a/java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml +++ b/java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml @@ -37,3 +37,6 @@ spec: properties: affinity: type: object + deletionPropagation: + type: string + enum: [ "Orphan" ]