Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[java-generator] Add the possibility to always emit additionalProperties on generated POJOs #5434

Merged
merged 2 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Fix #5423: OkHttpClientImpl supports setting request method for empty payload requests

#### Improvements
* Fix #5432: [java-generator] Add the possibility to always emit `additionalProperties` on generated POJOs
* Fix #5368: added support for additional ListOptions fields
* Fix #5377: added a createOr and unlock function to provide a straight-forward replacement for createOrReplace.
* Fix #5388: [crd-generator] Generate deterministic CRDs
Expand Down
8 changes: 8 additions & 0 deletions doc/java-generation-from-CRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase]
-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
-deserialization-datetime-format,
--deserialization-datetime-format=<deserializationDateTimeFormat>
DateTime format used for Deserialization of fields of
Expand Down Expand Up @@ -117,6 +120,11 @@ Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase]
And the corresponding configurations of the Maven plugin are (output of `mvn help:describe -DgroupId=io.fabric8 -DartifactId=java-generator-maven-plugin -Dversion=<version> -Ddetail`):

```
alwaysPreserveUnknown
User property: fabric8.java-generator.always-preserve-unknown
Always preserve unknown fields in the generated classes by emitting an
additionalProperties field

datetimeDeserializationFormat
User property: fabric8.java-generator.datetime-deserialization-format
DateTime format used for Deserialization of fields of type `date-time`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public class GenerateJavaSources implements Runnable {
"--skip-generated-annotations" }, description = "Skip emitting the @javax.annotation.processing.Generated annotation on the generated sources", required = false, hidden = true)
Boolean skipGeneratedAnnotations = null;

@Option(names = { "-always-preserve-unknown",
"--always-preserve-unknown" }, description = "Always preserve unknown fields in the generated classes by emitting an additionalProperties field", required = false, hidden = false)
Boolean alwaysPreserveUnkown = null;

@Option(names = { "-package-overrides",
"--package-overrides" }, description = "Apply the overrides to the package names", required = false)
Map<String, String> packageOverrides = null;
Expand All @@ -86,6 +90,7 @@ public void run() {
uppercaseEnum,
addExtraAnnotations,
!noGeneratedAnnotations,
alwaysPreserveUnkown,
packageOverrides,
filesSuffixes,
serializationDateTimeFormat,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class Config {
public static final boolean DEFAULT_UPPERCASE_ENUM = true;
public static final boolean DEFAULT_ADD_EXTRA_ANNOTATIONS = false;
public static final boolean DEFAULT_ADD_GENERATED_ANNOTATIONS = true;
public static final boolean DEFAULT_ALWAYS_PRESERVE_UNKNOWN = false;
public static final Map<String, String> DEFAULT_PACKAGE_OVERRIDES = new HashMap<>();
public static final List<String> DEFAULT_FILES_SUFFIXES = Arrays.asList(".yaml", ".yml", ".json");
// RFC 3339 - from: https://swagger.io/docs/specification/data-models/data-types/
Expand All @@ -38,6 +39,7 @@ public class Config {
private Boolean uppercaseEnums = DEFAULT_UPPERCASE_ENUM;
private Boolean objectExtraAnnotations = DEFAULT_ADD_EXTRA_ANNOTATIONS;
private Boolean generatedAnnotations = DEFAULT_ADD_GENERATED_ANNOTATIONS;
private Boolean alwaysPreserveUnknown = DEFAULT_ALWAYS_PRESERVE_UNKNOWN;
private Map<String, String> packageOverrides = DEFAULT_PACKAGE_OVERRIDES;
private List<String> filesSuffixes = DEFAULT_FILES_SUFFIXES;
private String serDatetimeFormat = DEFAULT_SER_DATETIME_FORMAT;
Expand Down Expand Up @@ -116,6 +118,41 @@ public Config(
}
}

public Config(
Boolean uppercaseEnums,
Boolean objectExtraAnnotations,
Boolean generatedAnnotations,
Boolean alwaysPreserveUnknown,
Map<String, String> packageOverrides,
List<String> filesSuffixes,
String serDatetimeFormat,
String deserDatetimeFormat) {
if (uppercaseEnums != null) {
rohanKanojia marked this conversation as resolved.
Show resolved Hide resolved
this.uppercaseEnums = uppercaseEnums;
}
if (objectExtraAnnotations != null) {
this.objectExtraAnnotations = objectExtraAnnotations;
}
if (generatedAnnotations != null) {
this.generatedAnnotations = generatedAnnotations;
}
if (alwaysPreserveUnknown != null) {
this.alwaysPreserveUnknown = alwaysPreserveUnknown;
}
if (packageOverrides != null) {
this.packageOverrides = packageOverrides;
}
if (filesSuffixes != null) {
this.filesSuffixes = filesSuffixes;
}
if (serDatetimeFormat != null) {
this.serDatetimeFormat = serDatetimeFormat;
}
if (deserDatetimeFormat != null) {
this.deserDatetimeFormat = deserDatetimeFormat;
}
}

public boolean isUppercaseEnums() {
return (uppercaseEnums == null) ? DEFAULT_UPPERCASE_ENUM : uppercaseEnums;
}
Expand All @@ -132,6 +169,12 @@ public boolean isGeneratedAnnotations() {
: generatedAnnotations;
}

public boolean isAlwaysPreserveUnknown() {
return (alwaysPreserveUnknown == null)
? DEFAULT_ALWAYS_PRESERVE_UNKNOWN
: alwaysPreserveUnknown;
}

public Map<String, String> getPackageOverrides() {
return (packageOverrides == null || packageOverrides.isEmpty())
? DEFAULT_PACKAGE_OVERRIDES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public GeneratorResult generateJava() {
}
}

if (this.preserveUnknownFields) {
if (this.preserveUnknownFields || config.isAlwaysPreserveUnknown()) {
ClassOrInterfaceType mapType = new ClassOrInterfaceType()
.setName(Keywords.JAVA_UTIL_MAP)
.setTypeArguments(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ class ConfigTest {

@Test
void defaultValuesWithAllArgsConstructor() {
final Config result = new Config(null, null, null, null, null, null, null);
final Config result = new Config(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)
.returns(Config.DEFAULT_ADD_GENERATED_ANNOTATIONS, Config::isGeneratedAnnotations)
.returns(Config.DEFAULT_ALWAYS_PRESERVE_UNKNOWN, Config::isAlwaysPreserveUnknown)
.returns(Config.DEFAULT_PACKAGE_OVERRIDES, Config::getPackageOverrides)
.returns(Config.DEFAULT_FILES_SUFFIXES, Config::getFilesSuffixes)
.returns(Config.DEFAULT_SER_DATETIME_FORMAT, Config::getSerDatetimeFormat)
Expand All @@ -41,6 +42,7 @@ void defaultValuesWithNoArgsConstructor() {
.returns(Config.DEFAULT_UPPERCASE_ENUM, Config::isUppercaseEnums)
.returns(Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, Config::isObjectExtraAnnotations)
.returns(Config.DEFAULT_ADD_GENERATED_ANNOTATIONS, Config::isGeneratedAnnotations)
.returns(Config.DEFAULT_ALWAYS_PRESERVE_UNKNOWN, Config::isAlwaysPreserveUnknown)
.returns(Config.DEFAULT_PACKAGE_OVERRIDES, Config::getPackageOverrides)
.returns(Config.DEFAULT_FILES_SUFFIXES, Config::getFilesSuffixes)
.returns(Config.DEFAULT_SER_DATETIME_FORMAT, Config::getSerDatetimeFormat)
Expand All @@ -54,6 +56,7 @@ void defaultValuesWithBuilder() {
.returns(Config.DEFAULT_UPPERCASE_ENUM, Config::isUppercaseEnums)
.returns(Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, Config::isObjectExtraAnnotations)
.returns(Config.DEFAULT_ADD_GENERATED_ANNOTATIONS, Config::isGeneratedAnnotations)
.returns(Config.DEFAULT_ALWAYS_PRESERVE_UNKNOWN, Config::isAlwaysPreserveUnknown)
.returns(Config.DEFAULT_PACKAGE_OVERRIDES, Config::getPackageOverrides)
.returns(Config.DEFAULT_FILES_SUFFIXES, Config::getFilesSuffixes)
.returns(Config.DEFAULT_SER_DATETIME_FORMAT, Config::getSerDatetimeFormat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,33 @@ void testObjectWithPreservedFields() {
assertTrue(clzT.get().getFieldByName("additionalProperties").isPresent());
}

@Test
void testConfigToGeneratePreservedUnknownFields() {
// Arrange
Config config = new Config(null, null, null, true, new HashMap<>(), new ArrayList<>(), null, null);
JObject obj = new JObject(
null,
"t",
null,
null,
false,
config,
null,
Boolean.FALSE,
null);

// Act
GeneratorResult res = obj.generateJava();

// Assert
assertEquals(1, res.getTopLevelClasses().size());
assertEquals("T", res.getTopLevelClasses().get(0).getName());

Optional<ClassOrInterfaceDeclaration> clzT = res.getTopLevelClasses().get(0).getClassByName("T");
assertTrue(clzT.isPresent());
assertTrue(clzT.get().getFieldByName("additionalProperties").isPresent());
}

@Test
void testObjectWithSpecialFieldNames() {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public void setEnumUppercase(final Boolean isEnumUppercase) {
javaGeneratorConfig = new Config(isEnumUppercase,
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
Expand All @@ -118,6 +119,7 @@ public void setExtraAnnotations(final Boolean isExtraAnnotations) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
isExtraAnnotations,
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
Expand All @@ -136,6 +138,26 @@ public void setGeneratedAnnotations(final Boolean isGeneratedAnnotations) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
isGeneratedAnnotations,
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
javaGeneratorConfig.getDeserDatetimeFormat());
}

/**
* Always preserve unknown fields in the generated classes by emitting an additionalProperties field
*
*/
public Boolean getAlwaysPreserveUnknown() {
return javaGeneratorConfig.isAlwaysPreserveUnknown();
}

public void setAlwaysPreserveUnknown(final Boolean isAlwaysPreserveUnknown) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
isAlwaysPreserveUnknown,
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
Expand All @@ -154,6 +176,7 @@ public void setPackageOverrides(final Map<String, String> packageOverrides) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
packageOverrides,
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
Expand All @@ -172,6 +195,7 @@ public void setPackageOverrides(final List<String> filesSuffixes) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
filesSuffixes,
javaGeneratorConfig.getSerDatetimeFormat(),
Expand All @@ -190,6 +214,7 @@ public void setSerializationDatetimeFormat(final String serDatetimeFmt) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
serDatetimeFmt,
Expand All @@ -208,6 +233,7 @@ public void setDeserializationDatetimeFormat(final String deserDatetimeFmt) {
javaGeneratorConfig = new Config(javaGeneratorConfig.isUppercaseEnums(),
javaGeneratorConfig.isObjectExtraAnnotations(),
javaGeneratorConfig.isGeneratedAnnotations(),
javaGeneratorConfig.isAlwaysPreserveUnknown(),
javaGeneratorConfig.getPackageOverrides(),
javaGeneratorConfig.getFilesSuffixes(),
javaGeneratorConfig.getSerDatetimeFormat(),
Expand Down
2 changes: 1 addition & 1 deletion java-generator/it/src/it/crd-names/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<version>@maven.surefire.plugin.version@</version>
<configuration>
<useFile>false</useFile>
<trimStackTrace>false</trimStackTrace>
Expand Down
2 changes: 1 addition & 1 deletion java-generator/it/src/it/datetime-fmt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<version>@maven.surefire.plugin.version@</version>
<configuration>
<useFile>false</useFile>
<trimStackTrace>false</trimStackTrace>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<version>@maven.surefire.plugin.version@</version>
<configuration>
<useFile>false</useFile>
<trimStackTrace>false</trimStackTrace>
Expand Down
2 changes: 1 addition & 1 deletion java-generator/it/src/it/escape-characters/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<version>@maven.surefire.plugin.version@</version>
<configuration>
<useFile>false</useFile>
<trimStackTrace>false</trimStackTrace>
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Loading
Loading