Skip to content

Commit

Permalink
Support non-String values in fromValue() methods of generated `en…
Browse files Browse the repository at this point in the history
…um` classes (#235)

Fixed 2 bugs related to the `fromValue()`-method in generated `enum` classes. The first, affected **all** generated `enum` classes where the `type`-property was not set to `string`. The `fromValue()`-method would always generate the method parameter as `String`, leading to issues caused by comparing incompatible types. The second issue is encountered under the same conditions, but when the configOption `useEnumCaseInsensitive` is set to `true`. This would invoke `equalsIgnoreCase` on non-`String` objects - which caused compilation errors. Both of these bug fixes are contained to the `fromValue()`-method and are fully backwards-compatible.
  • Loading branch information
Chrimle authored Dec 1, 2024
1 parent 054a889 commit 14b56d2
Show file tree
Hide file tree
Showing 95 changed files with 1,037 additions and 272 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The mustache templates can be acquired through multiple ways.
<dependency>
<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.2.0</version>
<version>2.2.1</version>
</dependency>
```

Expand Down Expand Up @@ -271,8 +271,11 @@ public record Person(
}

/**
* Case-sensitively parses the given string to an enum constant whose {@link #getValue()}
* matches the provided value.
* Case-sensitively matches the given {@code value} to an enum constant using {@link
* #getValue()}.
*
* <p><b>NOTE:</b> if multiple enum constants have a matching value, the first enum constant is
* returned, by the order they are declared.
*
* @param value of the Enum
* @return a {@link GenderEnum } with the matching value
Expand Down
9 changes: 6 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The mustache templates can be acquired through multiple ways.
<dependency>
<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.2.0</version>
<version>2.2.1</version>
</dependency>
```

Expand Down Expand Up @@ -259,8 +259,11 @@ public record Person(
}

/**
* Case-sensitively parses the given string to an enum constant whose {@link #getValue()}
* matches the provided value.
* Case-sensitively matches the given {@code value} to an enum constant using {@link
* #getValue()}.
*
* <p><b>NOTE:</b> if multiple enum constants have a matching value, the first enum constant is
* returned, by the order they are declared.
*
* @param value of the Enum
* @return a {@link GenderEnum } with the matching value
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>io.github.chrimle</groupId>
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
<version>2.2.0</version>
<version>2.2.1</version>

<!-- Project Information -->
<name>OpenAPI to Java records :: Mustache Templates</name>
Expand Down
19 changes: 14 additions & 5 deletions src/main/resources/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ components:
- Some description of ENUM1
- Some description of ENUM2
- Some description of ENUM3
ExampleEnumWithIntegerValues:
type: integer
description: Example of an Enum with integer values
enum:
- 100
- 200
- 300
- 400
- 500
DeprecatedExampleEnum:
type: string
deprecated: true
Expand All @@ -161,12 +170,12 @@ components:
- Some description of ENUM2
- Some description of ENUM3
exampleInnerTwo:
type: string
description: Example of another inner enum class
type: integer
description: Example of another inner enum class with integer values
enum:
- ENUM1
- ENUM2
- ENUM3
- 404
- 501
- 503
RecordWithAllConstraints:
type: object
description: Example of a Record which has fields with constraints
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/generateBuilders.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/javadoc.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is a custom template, and is used by `pojo.mustache` and `modelEnum.mustache`.
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/licenseInfo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand All @@ -33,6 +33,6 @@
* openapi-to-java-records-mustache-templates. For further information,
* questions, requesting features or reporting issues, please visit:
* https://github.com/Chrimle/openapi-to-java-records-mustache-templates.
* Generated with Version: 2.2.0
* Generated with Version: 2.2.1
*
*/
13 changes: 8 additions & 5 deletions src/main/resources/templates/modelEnum.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand Down Expand Up @@ -54,16 +54,19 @@
}

/**
* Case-{{#useEnumCaseInsensitive}}in{{/useEnumCaseInsensitive}}sensitively parses the given string to an enum constant whose {@link #getValue()}
* matches the provided value.
* {{#isString}}Case-{{#useEnumCaseInsensitive}}in{{/useEnumCaseInsensitive}}sensitively m{{/isString}}{{^isString}}M{{/isString}}atches the given {@code value} to an enum constant using {@link
* #getValue()}.
*
* <p><b>NOTE:</b> if multiple enum constants have a matching value, the first enum constant is
* returned, by the order they are declared.
*
* @param value of the Enum
* @return a {@link {{classname}} } with the matching value
* @throws IllegalArgumentException if no enum has a value matching the given value
*/
public static {{classname}} fromValue(final String value) {
public static {{classname}} fromValue(final {{{dataType}}} value) {
for (final {{classname}} constant : {{classname}}.values()) {
if (constant.getValue().equals{{#useEnumCaseInsensitive}}IgnoreCase{{/useEnumCaseInsensitive}}(value)) {
if (constant.getValue().equals{{#useEnumCaseInsensitive}}{{#isString}}IgnoreCase{{/isString}}{{/useEnumCaseInsensitive}}(value)) {
return constant;
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/main/resources/templates/pojo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is overriding an official 'openapi-generator-maven-plugin' template.
Expand Down Expand Up @@ -75,16 +75,19 @@
}

/**
* Case-{{#useEnumCaseInsensitive}}in{{/useEnumCaseInsensitive}}sensitively parses the given string to an enum constant whose {@link #getValue()}
* matches the provided value.
* {{#isString}}Case-{{#useEnumCaseInsensitive}}in{{/useEnumCaseInsensitive}}sensitively m{{/isString}}{{^isString}}M{{/isString}}atches the given {@code value} to an enum constant using {@link
* #getValue()}.
*
* <p><b>NOTE:</b> if multiple enum constants have a matching value, the first enum constant is
* returned, by the order they are declared.
*
* @param value of the Enum
* @return a {@link {{datatypeWithEnum}} } with the matching value
* @throws IllegalArgumentException if no enum has a value matching the given value
*/
public static {{datatypeWithEnum}} fromValue(final String value) {
public static {{datatypeWithEnum}} fromValue(final {{{dataType}}} value) {
for (final {{datatypeWithEnum}} constant : {{datatypeWithEnum}}.values()) {
if (constant.getValue().equals{{#useEnumCaseInsensitive}}IgnoreCase{{/useEnumCaseInsensitive}}(value)) {
if (constant.getValue().equals{{#useEnumCaseInsensitive}}{{#isString}}IgnoreCase{{/isString}}{{/useEnumCaseInsensitive}}(value)) {
return constant;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/serializableModel.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/useBeanValidation.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}}{{!
Source: openapi-to-java-records-mustache-templates
Version: 2.2.0
Version: 2.2.1
This template is a custom template, and is used by `pojo.mustache`.
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/io/github/chrimle/example/GeneratedClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public enum GeneratedClass {
RECORD_WITH_ALL_CONSTRAINTS("RecordWithAllConstraints", false, false),
RECORD_WITH_INNER_ENUMS("RecordWithInnerEnums", false, false),
EXAMPLE_INNER_ENUM("RecordWithInnerEnums$ExampleInnerEnum", false, true),
EXAMPLE_INNER_TWO_ENUM("RecordWithInnerEnums$ExampleInnerTwoEnum", false, true);
EXAMPLE_INNER_TWO_ENUM("RecordWithInnerEnums$ExampleInnerTwoEnum", false, true),
EXAMPLE_ENUM_WITH_INTEGER_VALUES("ExampleEnumWithIntegerValues", false, true);

public static final String PACKAGE_NAME = "io.github.chrimle.example";
public final String simpleClassName;
Expand Down
17 changes: 15 additions & 2 deletions src/test/java/io/github/chrimle/example/GeneratedField.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public record GeneratedField<T>(
boolean isBeanValidationNullable,
boolean isCustomClass,
boolean isEmail,
T enumValue,
Optional<T> defaultValue,
Optional<String> pattern,
Optional<Integer> minLength,
Expand All @@ -64,7 +65,11 @@ public record GeneratedField<T>(
Optional<String> decimalMax) {

public static <T> Builder<T> of(final String name, final Class<T> type) {
return new Builder<>(name, type);
return new Builder<>(name, type, null);
}

public static <T> Builder<T> of(final String name, final Class<T> type, final T enumValue) {
return new Builder<>(name, type, enumValue);
}

public static class Builder<T> {
Expand All @@ -74,6 +79,7 @@ public static class Builder<T> {
private boolean isBeanValidationNullable = true;
private boolean isCustomClass = false;
private boolean isEmail = false;
private T enumValue;
private Optional<T> defaultValue = Optional.empty();
private Optional<String> pattern = Optional.empty();
private Optional<Integer> minLength = Optional.empty();
Expand All @@ -85,9 +91,10 @@ public static class Builder<T> {
private Optional<String> decimalMin = Optional.empty();
private Optional<String> decimalMax = Optional.empty();

public Builder(final String name, final Class<T> type) {
public Builder(final String name, final Class<T> type, final T enumValue) {
this.name = name;
this.type = type;
this.enumValue = enumValue;
}

public Builder<T> isNullable(final boolean isNullable) {
Expand All @@ -110,6 +117,11 @@ public Builder<T> isEmail(final boolean isEmail) {
return this;
}

public Builder<T> enumValue(final T enumValue) {
this.enumValue = enumValue;
return this;
}

public Builder<T> defaultValue(final T defaultValue) {
this.defaultValue = Optional.ofNullable(defaultValue);
return this;
Expand Down Expand Up @@ -168,6 +180,7 @@ public GeneratedField<T> build() {
isBeanValidationNullable,
isCustomClass,
isEmail,
enumValue,
defaultValue,
pattern,
minLength,
Expand Down
25 changes: 23 additions & 2 deletions src/test/java/io/github/chrimle/example/TestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,29 @@ public void testAll(final PluginExecution pluginExecution) {
private static GeneratedSource getGeneratedSourceForGeneratedClass(
final GeneratedClass generatedClass, final PluginExecution pluginExecution) {
return switch (generatedClass) {
case DEPRECATED_EXAMPLE_ENUM, EXAMPLE_ENUM, EXAMPLE_INNER_ENUM, EXAMPLE_INNER_TWO_ENUM ->
new GeneratedSource(pluginExecution, generatedClass);
case DEPRECATED_EXAMPLE_ENUM, EXAMPLE_ENUM, EXAMPLE_INNER_ENUM ->
new GeneratedSource(
pluginExecution,
generatedClass,
GeneratedField.of("ENUM1", String.class, "ENUM1").build(),
GeneratedField.of("ENUM2", String.class, "ENUM2").build(),
GeneratedField.of("ENUM3", String.class, "ENUM3").build());
case EXAMPLE_INNER_TWO_ENUM ->
new GeneratedSource(
pluginExecution,
generatedClass,
GeneratedField.of("NUMBER_404", Integer.class, 404).build(),
GeneratedField.of("NUMBER_501", Integer.class, 501).build(),
GeneratedField.of("NUMBER_503", Integer.class, 503).build());
case EXAMPLE_ENUM_WITH_INTEGER_VALUES ->
new GeneratedSource(
pluginExecution,
generatedClass,
GeneratedField.of("NUMBER_100", Integer.class, 100).build(),
GeneratedField.of("NUMBER_200", Integer.class, 200).build(),
GeneratedField.of("NUMBER_300", Integer.class, 300).build(),
GeneratedField.of("NUMBER_400", Integer.class, 400).build(),
GeneratedField.of("NUMBER_500", Integer.class, 500).build());
case DEPRECATED_EXAMPLE_RECORD, EXAMPLE_RECORD ->
new GeneratedSource(
pluginExecution, generatedClass, GeneratedField.of("field1", Boolean.class).build());
Expand Down
Loading

0 comments on commit 14b56d2

Please sign in to comment.