From c874679d56c47e3916855b351ed3bc5b0a8d4a50 Mon Sep 17 00:00:00 2001 From: Matt Riben Date: Tue, 2 Apr 2024 18:33:14 -0500 Subject: [PATCH] Support existingJavaType extension in java-generator --- CHANGELOG.md | 2 + doc/java-generation-from-CRD.md | 16 ++- .../generator/cli/GenerateJavaSources.java | 7 +- .../io/fabric8/java/generator/Config.java | 16 ++- .../fabric8/java/generator/nodes/JObject.java | 5 +- .../fabric8/java/generator/ApprovalTest.java | 6 +- .../io/fabric8/java/generator/ConfigTest.java | 2 +- .../fabric8/java/generator/GeneratorTest.java | 26 +++- .../test/resources/existing-java-type-crd.yml | 39 ++++++ ...atePojos.testExistingJavaType.approved.txt | 30 +++++ java-generator/gradle-plugin/pom.xml | 4 + .../plugin/JavaGeneratorPluginExtension.java | 48 ++++++-- .../JavaGeneratorPluginExtensionTest.java | 113 ++++++++++++++++++ .../it/existing-java-types/invoker.properties | 17 +++ .../it/src/it/existing-java-types/pom.xml | 93 ++++++++++++++ .../io/fabric8/test/ExistingJavaTypes.java | 26 ++++ .../main/resources/existing-java-type-crd.yml | 39 ++++++ .../src/it/plugin/gradle/simple/build.gradle | 4 +- .../existingjavatypes/ExistingJavaTypes.java | 26 ++++ .../main/resources/existing-java-type-crd.yml | 39 ++++++ .../maven/plugin/JavaGeneratorMojo.java | 8 ++ 21 files changed, 545 insertions(+), 21 deletions(-) create mode 100644 java-generator/core/src/test/resources/existing-java-type-crd.yml create mode 100644 java-generator/core/src/test/resources/io/fabric8/java/generator/approvals/ApprovalTest.generate_withValidCrd_shouldGeneratePojos.testExistingJavaType.approved.txt create mode 100644 java-generator/gradle-plugin/src/test/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtensionTest.java create mode 100644 java-generator/it/src/it/existing-java-types/invoker.properties create mode 100644 java-generator/it/src/it/existing-java-types/pom.xml create mode 100644 java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java create mode 100644 java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml create mode 100644 java-generator/it/src/it/plugin/gradle/simple/src/main/java/existingjavatypes/ExistingJavaTypes.java create mode 100644 java-generator/it/src/it/plugin/gradle/simple/src/main/resources/existing-java-type-crd.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be8e2d9c42..8d2d330e4cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,10 @@ #### Bugs * Fix #5853: [java-generator] Gracefully handle colliding enum definitions +* Fix #5860: Corrections to java-generator gradle plugin extension #### Improvements +* Fix #5843: Support existingJavaTypes extension in java-generator #### Dependency Upgrade diff --git a/doc/java-generation-from-CRD.md b/doc/java-generation-from-CRD.md index 57eac379632..106aaed148d 100644 --- a/doc/java-generation-from-CRD.md +++ b/doc/java-generation-from-CRD.md @@ -79,18 +79,20 @@ Provide a `source` referencing a file or a folder containing your CRDs definitio The full list of options of the CLI is (output of `--help`): ``` -Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase] +Usage: java-gen [-hV] [-add-extra-annotations] [-always-preserve-unknown] + [-enum-uppercase] [-deserialization-datetime-format=] [-dt=] [-s=] [-serialization-datetime-format=] - -t= [-files-suffixes=]... + -t= [-existing-java-types=]... + [-files-suffixes=]... [-package-overrides=]... [-u=]... -add-extra-annotations, --add-extra-annotations Add extra lombok and sundrio annotation to the generated classes -always-preserve-unknown, --always-preserve-unknown Always preserve unknown fields in the generated - classes + classes by emitting an additionalProperties field -deserialization-datetime-format, --deserialization-datetime-format= DateTime format used for Deserialization of fields of @@ -100,6 +102,9 @@ Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase] crds -enum-uppercase, --enum-uppercase Uppercase the enum values + -existing-java-types, --existing-java-types= + Mapping from fully qualified generated type to fully + qualified existing Java type -files-suffixes, --files-suffixes= Filter the source files with the specific suffixes -h, --help Show this help message and exit. @@ -141,6 +146,11 @@ And the corresponding configurations of the Maven plugin are (output of `mvn hel User property: fabric8.java-generator.enum-uppercase Generate uppercase Enums + existingJavaTypes + User property: fabric8.java-generator.existing-java-types + Mapping from fully qualified generated type to fully qualified existing + Java type + extraAnnotations User property: fabric8.java-generator.extra-annotations Generate Extra annotation for lombok and sundrio integration diff --git a/java-generator/cli/src/main/java/io/fabric8/java/generator/cli/GenerateJavaSources.java b/java-generator/cli/src/main/java/io/fabric8/java/generator/cli/GenerateJavaSources.java index d12ac719197..95888674538 100644 --- a/java-generator/cli/src/main/java/io/fabric8/java/generator/cli/GenerateJavaSources.java +++ b/java-generator/cli/src/main/java/io/fabric8/java/generator/cli/GenerateJavaSources.java @@ -83,6 +83,10 @@ public class GenerateJavaSources implements Runnable { "--deserialization-datetime-format" }, description = "DateTime format used for Deserialization of fields of type `date-time`", required = false) String deserializationDateTimeFormat = null; + @Option(names = { "-existing-java-types", + "--existing-java-types" }, description = "Mapping from fully qualified generated type to fully qualified existing Java type", required = false) + Map existingJavaTypes = null; + @Override public void run() { final Boolean noGeneratedAnnotations = (skipGeneratedAnnotations != null) ? skipGeneratedAnnotations : false; @@ -94,7 +98,8 @@ public void run() { packageOverrides, filesSuffixes, serializationDateTimeFormat, - deserializationDateTimeFormat); + deserializationDateTimeFormat, + existingJavaTypes); List runners = new ArrayList<>(); diff --git a/java-generator/core/src/main/java/io/fabric8/java/generator/Config.java b/java-generator/core/src/main/java/io/fabric8/java/generator/Config.java index e44911dc1a5..2867d1ab6bb 100644 --- a/java-generator/core/src/main/java/io/fabric8/java/generator/Config.java +++ b/java-generator/core/src/main/java/io/fabric8/java/generator/Config.java @@ -35,6 +35,7 @@ public class Config { // RFC 3339 - from: https://swagger.io/docs/specification/data-models/data-types/ public static final String DEFAULT_SER_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssVV"; public static final String DEFAULT_DESER_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]"; + public static final Map DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES = new HashMap<>(); private Boolean uppercaseEnums = DEFAULT_UPPERCASE_ENUM; private Boolean objectExtraAnnotations = DEFAULT_ADD_EXTRA_ANNOTATIONS; @@ -44,6 +45,7 @@ public class Config { private List filesSuffixes = DEFAULT_FILES_SUFFIXES; private String serDatetimeFormat = DEFAULT_SER_DATETIME_FORMAT; private String deserDatetimeFormat = DEFAULT_DESER_DATETIME_FORMAT; + private Map existingJavaTypes = DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES; public Config( Boolean uppercaseEnums, @@ -64,6 +66,7 @@ public Config( } } + @Deprecated public Config( Boolean uppercaseEnums, Boolean objectExtraAnnotations, @@ -87,6 +90,7 @@ public Config( } } + @Deprecated public Config( Boolean uppercaseEnums, Boolean objectExtraAnnotations, @@ -126,7 +130,8 @@ public Config( Map packageOverrides, List filesSuffixes, String serDatetimeFormat, - String deserDatetimeFormat) { + String deserDatetimeFormat, + Map existingJavaTypes) { if (uppercaseEnums != null) { this.uppercaseEnums = uppercaseEnums; } @@ -151,6 +156,9 @@ public Config( if (deserDatetimeFormat != null) { this.deserDatetimeFormat = deserDatetimeFormat; } + if (existingJavaTypes != null) { + this.existingJavaTypes = existingJavaTypes; + } } public boolean isUppercaseEnums() { @@ -198,4 +206,10 @@ public String getDeserDatetimeFormat() { ? DEFAULT_DESER_DATETIME_FORMAT : deserDatetimeFormat; } + + public Map getExistingJavaTypes() { + return (existingJavaTypes == null || existingJavaTypes.isEmpty()) + ? DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES + : existingJavaTypes; + } } diff --git a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JObject.java b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JObject.java index 0bff149e7f9..bc0f034a9c9 100644 --- a/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JObject.java +++ b/java-generator/core/src/main/java/io/fabric8/java/generator/nodes/JObject.java @@ -133,7 +133,7 @@ public JObject( @Override public String getType() { - return this.type; + return config.getExistingJavaTypes().getOrDefault(this.type, this.type); } private String getSortedFieldsAsParam(Set list) { @@ -153,6 +153,9 @@ private String getSortedFieldsAsParam(Set list) { @Override public GeneratorResult generateJava() { + if (config.getExistingJavaTypes().containsKey(this.type)) { + return new GeneratorResult(Collections.emptyList()); + } CompilationUnit cu = new CompilationUnit(); if (!this.pkg.isEmpty()) { cu.setPackageDeclaration(new PackageDeclaration(new Name(this.pkg))); diff --git a/java-generator/core/src/test/java/io/fabric8/java/generator/ApprovalTest.java b/java-generator/core/src/test/java/io/fabric8/java/generator/ApprovalTest.java index da2e40e8038..60a131615e8 100644 --- a/java-generator/core/src/test/java/io/fabric8/java/generator/ApprovalTest.java +++ b/java-generator/core/src/test/java/io/fabric8/java/generator/ApprovalTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.params.provider.MethodSource; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.stream.Stream; @@ -44,7 +45,10 @@ private static Stream getCRDGenerationInputData() { Arguments.of("testJokeCrd", "jokerequests-crd.yml", "JokeRequest", "JokeRequestJavaCr", new Config()), Arguments.of("testAkkaMicroservicesCrd", "akka-microservices-crd.yml", "AkkaMicroservice", "AkkaMicroserviceJavaCr", new Config()), - Arguments.of("testCalicoIPPoolCrd", "calico-ippool-crd.yml", "IPPool", "CalicoIPPoolCr", new Config())); + Arguments.of("testCalicoIPPoolCrd", "calico-ippool-crd.yml", "IPPool", "CalicoIPPoolCr", new Config()), + Arguments.of("testExistingJavaType", "existing-java-type-crd.yml", "ExistingJavaType", "ExistingJavaTypeCr", + Config.builder().existingJavaTypes(Collections.singletonMap( + "org.test.v1.existingjavatypespec.Affinity", "io.fabric8.kubernetes.api.model.Affinity")).build())); } @ParameterizedTest diff --git a/java-generator/core/src/test/java/io/fabric8/java/generator/ConfigTest.java b/java-generator/core/src/test/java/io/fabric8/java/generator/ConfigTest.java index afbd901626d..8551f04ac61 100644 --- a/java-generator/core/src/test/java/io/fabric8/java/generator/ConfigTest.java +++ b/java-generator/core/src/test/java/io/fabric8/java/generator/ConfigTest.java @@ -23,7 +23,7 @@ class ConfigTest { @Test void defaultValuesWithAllArgsConstructor() { - final Config result = new Config(null, null, null, null, null, null, null, null); + final Config result = new Config(null, null, null, null, null, null, null, null, null); assertThat(result) .returns(Config.DEFAULT_UPPERCASE_ENUM, Config::isUppercaseEnums) .returns(Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, Config::isObjectExtraAnnotations) 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 6c87615a55d..7c5d91b5265 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 @@ -698,7 +698,7 @@ void testObjectWithPreservedFields() { @Test void testConfigToGeneratePreservedUnknownFields() { // Arrange - Config config = new Config(null, null, null, true, new HashMap<>(), new ArrayList<>(), null, null); + Config config = new Config(null, null, null, true, new HashMap<>(), new ArrayList<>(), null, null, null); JObject obj = new JObject( null, "t", @@ -982,4 +982,28 @@ void testExactlyDuplicatedFieldNotMarkedAsDeprecatedFailsWithException() { }, "An exception is expected to be thrown when an object contains one duplicated field that is not marked as deprecated"); } + + @Test + void testExistingJavaTypeObject() { + // Arrange + Config config = Config.builder() + .existingJavaTypes(Collections.singletonMap("v1alpha1.T", "org.test.ExistingJavaType")).build(); + JObject obj = new JObject( + "v1alpha1", + "T", + null, + null, + false, + config, + null, + Boolean.FALSE, + null); + + // Act + GeneratorResult res = obj.generateJava(); + + // Assert + assertEquals("org.test.ExistingJavaType", obj.getType()); + assertEquals(0, res.getTopLevelClasses().size()); + } } diff --git a/java-generator/core/src/test/resources/existing-java-type-crd.yml b/java-generator/core/src/test/resources/existing-java-type-crd.yml new file mode 100644 index 00000000000..17185cbb742 --- /dev/null +++ b/java-generator/core/src/test/resources/existing-java-type-crd.yml @@ -0,0 +1,39 @@ +# +# Copyright (C) 2015 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: existing-java-type.example.com +spec: + scope: Namespaced + names: + plural: existingJavaTypes + kind: ExistingJavaType + group: example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + affinity: + type: object diff --git a/java-generator/core/src/test/resources/io/fabric8/java/generator/approvals/ApprovalTest.generate_withValidCrd_shouldGeneratePojos.testExistingJavaType.approved.txt b/java-generator/core/src/test/resources/io/fabric8/java/generator/approvals/ApprovalTest.generate_withValidCrd_shouldGeneratePojos.testExistingJavaType.approved.txt new file mode 100644 index 00000000000..2c2ae53b442 --- /dev/null +++ b/java-generator/core/src/test/resources/io/fabric8/java/generator/approvals/ApprovalTest.generate_withValidCrd_shouldGeneratePojos.testExistingJavaType.approved.txt @@ -0,0 +1,30 @@ +ExistingJavaTypeCr[0] = package org.test.v1; + +@io.fabric8.kubernetes.model.annotation.Version(value = "v1" , storage = true , served = true) +@io.fabric8.kubernetes.model.annotation.Group("example.com") +@io.fabric8.kubernetes.model.annotation.Plural("existingJavaTypes") +@javax.annotation.processing.Generated("io.fabric8.java.generator.CRGeneratorRunner") +public class ExistingJavaType extends io.fabric8.kubernetes.client.CustomResource implements io.fabric8.kubernetes.api.model.Namespaced { +} + +ExistingJavaTypeCr[1] = package org.test.v1; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"affinity"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +@javax.annotation.processing.Generated("io.fabric8.java.generator.CRGeneratorRunner") +public class ExistingJavaTypeSpec implements io.fabric8.kubernetes.api.model.KubernetesResource { + + @com.fasterxml.jackson.annotation.JsonProperty("affinity") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.Affinity affinity; + + public io.fabric8.kubernetes.api.model.Affinity getAffinity() { + return affinity; + } + + public void setAffinity(io.fabric8.kubernetes.api.model.Affinity affinity) { + this.affinity = affinity; + } +} + diff --git a/java-generator/gradle-plugin/pom.xml b/java-generator/gradle-plugin/pom.xml index 41553d0a033..682111ec62b 100644 --- a/java-generator/gradle-plugin/pom.xml +++ b/java-generator/gradle-plugin/pom.xml @@ -73,6 +73,10 @@ org.junit.jupiter junit-jupiter-api + + org.junit.jupiter + junit-jupiter-params + org.mockito mockito-core diff --git a/java-generator/gradle-plugin/src/main/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtension.java b/java-generator/gradle-plugin/src/main/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtension.java index d09869e29a0..efd05a318c8 100644 --- a/java-generator/gradle-plugin/src/main/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtension.java +++ b/java-generator/gradle-plugin/src/main/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtension.java @@ -104,7 +104,8 @@ public void setEnumUppercase(final Boolean isEnumUppercase) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -123,7 +124,8 @@ public void setExtraAnnotations(final Boolean isExtraAnnotations) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -131,7 +133,7 @@ public void setExtraAnnotations(final Boolean isExtraAnnotations) { * */ public Boolean getGeneratedAnnotations() { - return javaGeneratorConfig.isUppercaseEnums(); + return javaGeneratorConfig.isGeneratedAnnotations(); } public void setGeneratedAnnotations(final Boolean isGeneratedAnnotations) { @@ -142,7 +144,8 @@ public void setGeneratedAnnotations(final Boolean isGeneratedAnnotations) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -161,7 +164,8 @@ public void setAlwaysPreserveUnknown(final Boolean isAlwaysPreserveUnknown) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -180,7 +184,8 @@ public void setPackageOverrides(final Map packageOverrides) { packageOverrides, javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -191,7 +196,7 @@ public List getFilesSuffixes() { return javaGeneratorConfig.getFilesSuffixes(); } - public void setPackageOverrides(final List filesSuffixes) { + public void setFilesSuffixes(final List filesSuffixes) { javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(), javaGeneratorConfig.isObjectExtraAnnotations(), javaGeneratorConfig.isGeneratedAnnotations(), @@ -199,7 +204,8 @@ public void setPackageOverrides(final List filesSuffixes) { javaGeneratorConfig.getPackageOverrides(), filesSuffixes, javaGeneratorConfig.getSerDatetimeFormat(), - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -218,7 +224,8 @@ public void setSerializationDatetimeFormat(final String serDatetimeFmt) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), serDatetimeFmt, - javaGeneratorConfig.getDeserDatetimeFormat()); + javaGeneratorConfig.getDeserDatetimeFormat(), + javaGeneratorConfig.getExistingJavaTypes()); } /** @@ -237,6 +244,27 @@ public void setDeserializationDatetimeFormat(final String deserDatetimeFmt) { javaGeneratorConfig.getPackageOverrides(), javaGeneratorConfig.getFilesSuffixes(), javaGeneratorConfig.getSerDatetimeFormat(), - deserDatetimeFmt); + deserDatetimeFmt, + javaGeneratorConfig.getExistingJavaTypes()); + } + + /** + * Mapping from fully qualified generated type to fully qualified existing Java type + * + */ + public Map getExistingJavaTypes() { + return javaGeneratorConfig.getExistingJavaTypes(); + } + + public void setExistingJavaTypes(final Map existingJavaTypes) { + javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(), + javaGeneratorConfig.isObjectExtraAnnotations(), + javaGeneratorConfig.isGeneratedAnnotations(), + javaGeneratorConfig.isAlwaysPreserveUnknown(), + javaGeneratorConfig.getPackageOverrides(), + javaGeneratorConfig.getFilesSuffixes(), + javaGeneratorConfig.getSerDatetimeFormat(), + javaGeneratorConfig.getDeserDatetimeFormat(), + existingJavaTypes); } } diff --git a/java-generator/gradle-plugin/src/test/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtensionTest.java b/java-generator/gradle-plugin/src/test/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtensionTest.java new file mode 100644 index 00000000000..93845cee3b5 --- /dev/null +++ b/java-generator/gradle-plugin/src/test/java/io/fabric8/java/generator/gradle/plugin/JavaGeneratorPluginExtensionTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.java.generator.gradle.plugin; + +import io.fabric8.java.generator.Config; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.ListProperty; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JavaGeneratorPluginExtensionTest { + static Stream testGettersAndSetters() { + JavaGeneratorPluginExtension extension = new JavaGeneratorPluginExtensionTestImpl(); + return Stream.of( + Arguments.of(Config.DEFAULT_ALWAYS_PRESERVE_UNKNOWN, !Config.DEFAULT_ALWAYS_PRESERVE_UNKNOWN, null, + (Supplier) extension::getAlwaysPreserveUnknown, (Consumer) extension::setAlwaysPreserveUnknown), + Arguments.of(Config.DEFAULT_UPPERCASE_ENUM, !Config.DEFAULT_UPPERCASE_ENUM, null, + (Supplier) extension::getEnumUppercase, (Consumer) extension::setEnumUppercase), + Arguments.of(Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, !Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, null, + (Supplier) extension::getExtraAnnotations, (Consumer) extension::setExtraAnnotations), + Arguments.of(Config.DEFAULT_ADD_GENERATED_ANNOTATIONS, !Config.DEFAULT_ADD_GENERATED_ANNOTATIONS, null, + (Supplier) extension::getGeneratedAnnotations, (Consumer) extension::setGeneratedAnnotations), + Arguments.of(Config.DEFAULT_DESER_DATETIME_FORMAT, UUID.randomUUID().toString(), "", + (Supplier) extension::getDeserializationDatetimeFormat, + (Consumer) extension::setDeserializationDatetimeFormat), + Arguments.of(Config.DEFAULT_SER_DATETIME_FORMAT, UUID.randomUUID().toString(), "", + (Supplier) extension::getSerializationDatetimeFormat, + (Consumer) extension::setSerializationDatetimeFormat), + Arguments.of(Config.DEFAULT_FILES_SUFFIXES, + Collections.singletonList(UUID.randomUUID().toString()), Collections.emptyList(), + (Supplier>) extension::getFilesSuffixes, (Consumer>) extension::setFilesSuffixes), + Arguments.of(Config.DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES, + Collections.singletonMap(UUID.randomUUID().toString(), UUID.randomUUID().toString()), Collections.emptyMap(), + (Supplier>) extension::getExistingJavaTypes, + (Consumer>) extension::setExistingJavaTypes), + Arguments.of(Config.DEFAULT_PACKAGE_OVERRIDES, + Collections.singletonMap(UUID.randomUUID().toString(), UUID.randomUUID().toString()), Collections.emptyMap(), + (Supplier>) extension::getPackageOverrides, + (Consumer>) extension::setPackageOverrides)); + } + + @ParameterizedTest + @MethodSource + void testGettersAndSetters(T defaultValue, T alternateValue, T emptyValue, Supplier getter, Consumer setter) { + assertEquals(defaultValue, getter.get()); + + setter.accept(alternateValue); + assertEquals(alternateValue, getter.get()); + + setter.accept(null); + assertEquals(defaultValue, getter.get()); + + setter.accept(alternateValue); + assertEquals(alternateValue, getter.get()); + + setter.accept(emptyValue); + assertEquals(defaultValue, getter.get()); + + setter.accept(alternateValue); + assertEquals(alternateValue, getter.get()); + } + + static class JavaGeneratorPluginExtensionTestImpl extends JavaGeneratorPluginExtension { + public JavaGeneratorPluginExtensionTestImpl() { + super(null); + } + + @Override + public RegularFileProperty getSource() { + return null; + } + + @Override + public ListProperty getUrls() { + return null; + } + + @Override + public DirectoryProperty getDownloadTarget() { + return null; + } + + @Override + public DirectoryProperty getTarget() { + return null; + } + } +} diff --git a/java-generator/it/src/it/existing-java-types/invoker.properties b/java-generator/it/src/it/existing-java-types/invoker.properties new file mode 100644 index 00000000000..9135f207843 --- /dev/null +++ b/java-generator/it/src/it/existing-java-types/invoker.properties @@ -0,0 +1,17 @@ +# +# Copyright (C) 2015 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +invoker.goals=test diff --git a/java-generator/it/src/it/existing-java-types/pom.xml b/java-generator/it/src/it/existing-java-types/pom.xml new file mode 100644 index 00000000000..cf107634d03 --- /dev/null +++ b/java-generator/it/src/it/existing-java-types/pom.xml @@ -0,0 +1,93 @@ + + + + + 4.0.0 + + existing-java-types + io.fabric8.it + 0.0-SNAPSHOT + jar + + + @maven.compiler.source@ + @maven.compiler.target@ + + + + + io.fabric8 + java-generator-integration-tests + @project.version@ + + + io.fabric8 + generator-annotations + @project.version@ + + + org.junit.jupiter + junit-jupiter-api + @junit.version@ + test + + + org.junit.jupiter + junit-jupiter-engine + @junit.version@ + test + + + + + + + io.fabric8 + java-generator-maven-plugin + @project.version@ + + + + generate + + + + + src/main/resources/existing-java-type-crd.yml + false + + + io.fabric8.kubernetes.api.model.Affinity + + + + + + org.apache.maven.plugins + maven-surefire-plugin + @maven.surefire.plugin.version@ + + false + false + + + + + + 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 new file mode 100644 index 00000000000..0edf13060e7 --- /dev/null +++ b/java-generator/it/src/it/existing-java-types/src/main/java/io/fabric8/test/ExistingJavaTypes.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.test; + +import com.example.v1.ExistingJavaTypeSpec; +import io.fabric8.kubernetes.api.model.Affinity; + +public class ExistingJavaTypes { + public void example() { + ExistingJavaTypeSpec existingJavaTypeSpec = new ExistingJavaTypeSpec(); + existingJavaTypeSpec.setAffinity(new Affinity()); + } +} 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 new file mode 100644 index 00000000000..17185cbb742 --- /dev/null +++ b/java-generator/it/src/it/existing-java-types/src/main/resources/existing-java-type-crd.yml @@ -0,0 +1,39 @@ +# +# Copyright (C) 2015 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: existing-java-type.example.com +spec: + scope: Namespaced + names: + plural: existingJavaTypes + kind: ExistingJavaType + group: example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + affinity: + type: object diff --git a/java-generator/it/src/it/plugin/gradle/simple/build.gradle b/java-generator/it/src/it/plugin/gradle/simple/build.gradle index 3ea7cce4ca6..67af4dcc155 100644 --- a/java-generator/it/src/it/plugin/gradle/simple/build.gradle +++ b/java-generator/it/src/it/plugin/gradle/simple/build.gradle @@ -54,6 +54,6 @@ java { } javaGen { - source = file('src/main/resources/broker_activemqartemis_crd.yaml') + source = file('src/main/resources') + existingJavaTypes(Collections.singletonMap("com.example.v1.existingjavatypespec.Affinity", "io.fabric8.kubernetes.api.model.Affinity")) } - diff --git a/java-generator/it/src/it/plugin/gradle/simple/src/main/java/existingjavatypes/ExistingJavaTypes.java b/java-generator/it/src/it/plugin/gradle/simple/src/main/java/existingjavatypes/ExistingJavaTypes.java new file mode 100644 index 00000000000..f44ecf40754 --- /dev/null +++ b/java-generator/it/src/it/plugin/gradle/simple/src/main/java/existingjavatypes/ExistingJavaTypes.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package existingjavatypes; + +import com.example.v1.ExistingJavaTypeSpec; +import io.fabric8.kubernetes.api.model.Affinity; + +public class ExistingJavaTypes { + public void example() { + ExistingJavaTypeSpec existingJavaTypeSpec = new ExistingJavaTypeSpec(); + existingJavaTypeSpec.setAffinity(new Affinity()); + } +} diff --git a/java-generator/it/src/it/plugin/gradle/simple/src/main/resources/existing-java-type-crd.yml b/java-generator/it/src/it/plugin/gradle/simple/src/main/resources/existing-java-type-crd.yml new file mode 100644 index 00000000000..17185cbb742 --- /dev/null +++ b/java-generator/it/src/it/plugin/gradle/simple/src/main/resources/existing-java-type-crd.yml @@ -0,0 +1,39 @@ +# +# Copyright (C) 2015 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: existing-java-type.example.com +spec: + scope: Namespaced + names: + plural: existingJavaTypes + kind: ExistingJavaType + group: example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + affinity: + type: object diff --git a/java-generator/maven-plugin/src/main/java/io/fabric8/java/generator/maven/plugin/JavaGeneratorMojo.java b/java-generator/maven-plugin/src/main/java/io/fabric8/java/generator/maven/plugin/JavaGeneratorMojo.java index 284dc973d9d..966077784b8 100644 --- a/java-generator/maven-plugin/src/main/java/io/fabric8/java/generator/maven/plugin/JavaGeneratorMojo.java +++ b/java-generator/maven-plugin/src/main/java/io/fabric8/java/generator/maven/plugin/JavaGeneratorMojo.java @@ -122,6 +122,13 @@ public class JavaGeneratorMojo extends AbstractMojo { @Parameter(property = "fabric8.java-generator.datetime-deserialization-format", required = false) String datetimeDeserializationFormat = null; + /** + * Mapping from fully qualified generated type to fully qualified existing Java type + * + */ + @Parameter(property = "fabric8.java-generator.existing-java-types", required = false) + Map existingJavaTypes = null; + @Override public void execute() throws MojoExecutionException { final Config config = Config.builder() @@ -133,6 +140,7 @@ public void execute() throws MojoExecutionException { .filesSuffixes(filesSuffixes) .serDatetimeFormat(datetimeSerializationFormat) .deserDatetimeFormat(datetimeDeserializationFormat) + .existingJavaTypes(existingJavaTypes) .build(); List runners = new ArrayList<>();