Skip to content

Commit ab117aa

Browse files
authored
[okhttp-gson] Generate static validateJsonElement method in all Classes (#375)
Generates a static `validateJsonElement` method in all generated `enum` and `record` classes, when the `library` configuration is set to `okhttp-gson` (default `library`). This method is used by GSON to validate the object. Additionally, two static fields; `openapiFields` and `openapiRequiredFields`, will also be generated in all `record` classes, as these are used in the `validateJsonElement` method. This method _may_ also be referenced by other classes, most notably by generated `oneOf` interface classes, or by _supportingFiles_. However, please note that this release does **not** include support for `oneOf` / `anyOf` / `allOf`.
1 parent b0ab06e commit ab117aa

File tree

346 files changed

+27504
-269
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

346 files changed

+27504
-269
lines changed

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ authors:
55
given-names: "Christopher"
66
orcid: "https://orcid.org/0009-0002-1005-3942"
77
title: "OpenAPI to Java Records Mustache Templates"
8-
version: 2.7.1
8+
version: 2.8.0
99
date-released: 2025-01-06
1010
url: "https://github.com/Chrimle/openapi-to-java-records-mustache-templates"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ The mustache templates are best acquired by importing the project as a dependenc
3737
<dependency>
3838
<groupId>io.github.chrimle</groupId>
3939
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
40-
<version>2.7.1</version>
40+
<version>2.8.0</version>
4141
</dependency>
4242
```
4343
It is **strongly recommended** to import the project as a dependency. It has officially been published to:

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The mustache templates are best acquired by importing the project as a dependenc
3232
<dependency>
3333
<groupId>io.github.chrimle</groupId>
3434
<artifactId>openapi-to-java-records-mustache-templates</artifactId>
35-
<version>2.7.1</version>
35+
<version>2.8.0</version>
3636
</dependency>
3737
```
3838
It is **strongly recommended** to import the project as a dependency. It has officially been published to:

mustache-templates/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>io.github.chrimle</groupId>
88
<artifactId>openapi-to-java-records-mustache-templates-parent</artifactId>
9-
<version>2.7.1</version>
9+
<version>2.8.0</version>
1010
</parent>
1111

1212
<artifactId>openapi-to-java-records-mustache-templates</artifactId>

mustache-templates/src/main/resources/templates/modelEnum.mustache

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
- This template is overriding an official 'openapi-generator-maven-plugin' template.
2727
- Generates an `enum` class.
2828

29+
}}{{!
30+
}}{{#gson}}import java.io.IOException;
31+
import com.google.gson.JsonElement;
32+
33+
{{/gson}}{{!
2934
}}{{#isUri}}import java.net.URI;
3035

3136
{{/isUri}}{{>javadoc}}{{!
@@ -78,4 +83,17 @@
7883
}
7984
{{#enumUnknownDefaultCase}}{{#allowableValues}}{{#enumVars}}{{#-last}}return {{{name}}};{{/-last}}{{/enumVars}}{{/allowableValues}}{{/enumUnknownDefaultCase}}{{^enumUnknownDefaultCase}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/enumUnknownDefaultCase}}
8085
}
86+
{{#gson}}
87+
88+
/**
89+
* Validates the JSON Element and throws an exception if issues are found.
90+
*
91+
* @param jsonElement to validate.
92+
* @throws IOException if the JSON Element is not a valid {{classname}} object.
93+
*/
94+
public static void validateJsonElement(final JsonElement jsonElement) throws IOException {
95+
final {{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = {{#isUri}}URI.create({{/isUri}}jsonElement.{{#isNumber}}getAsString(){{/isNumber}}{{#isInteger}}getAsInt(){{/isInteger}}{{#isUri}}getAsString()){{/isUri}}{{^isNumber}}{{^isInteger}}{{^isUri}}getAs{{{dataType}}}(){{/isUri}}{{/isInteger}}{{/isNumber}};
96+
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
97+
}
98+
{{/gson}}
8199
}

mustache-templates/src/main/resources/templates/pojo.mustache

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@
2828
Additional Context:
2929
- This template is overriding an official 'openapi-generator-maven-plugin' template.
3030

31+
}}{{!
32+
Imports needed for 'okhttp-gson'
33+
}}{{#gson}}{{!
34+
}}import com.google.gson.JsonArray;
35+
import com.google.gson.JsonElement;
36+
import com.google.gson.JsonObject;
37+
import java.util.HashSet;
38+
import java.util.Map;
39+
import java.util.Set;
40+
41+
{{/gson}}{{!
3142
}}{{>javadoc}}{{!
3243
}}{{#isDeprecated}}@Deprecated
3344
{{/isDeprecated}}{{!
@@ -44,6 +55,19 @@
4455
{{/-last}}{{/vars}}{{^serializableModel}}){{/serializableModel}}{{#serializableModel}}
4556
) implements Serializable{{/serializableModel}} {
4657
{{>serializableModel}}
58+
{{#gson}} /** A set containing the names of all instance fields defined in this class. */
59+
public static final HashSet<String> openapiFields =
60+
new HashSet<String>(
61+
Set.of({{#allVars}}"{{baseName}}"{{^-last}},
62+
{{/-last}}{{/allVars}}));
63+
64+
/** A set containing the names of all required fields defined in this class. */
65+
public static final HashSet<String> openapiRequiredFields =
66+
new HashSet<String>(
67+
Set.of({{#requiredVars}}"{{baseName}}"{{^-last}},
68+
{{/-last}}{{/requiredVars}}));
69+
70+
{{/gson}}
4771
public {{classname}}(
4872
{{#vars}}@{{javaxPackage}}.annotation.{{#isNullable}}Nullable{{/isNullable}}{{^isNullable}}{{#defaultValue}}Nullable{{/defaultValue}}{{^defaultValue}}Nonnull{{/defaultValue}}{{/isNullable}} final {{{datatypeWithEnum}}} {{name}}{{^-last}},
4973
{{/-last}}{{/vars}}) { {{#vars}}
@@ -103,5 +127,87 @@
103127
}
104128
{{#enumUnknownDefaultCase}}{{#allowableValues}}{{#enumVars}}{{#-last}}return {{{name}}};{{/-last}}{{/enumVars}}{{/allowableValues}}{{/enumUnknownDefaultCase}}{{^enumUnknownDefaultCase}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/enumUnknownDefaultCase}}
105129
}
130+
{{#gson}}
131+
132+
/**
133+
* Validates the JSON Element and throws an exception if issues are found.
134+
*
135+
* @param jsonElement to validate.
136+
* @throws IOException if the JSON Element is not a valid {{datatypeWithEnum}} object.
137+
*/
138+
public static void validateJsonElement(final JsonElement jsonElement) throws IOException {
139+
final {{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = {{#isUri}}URI.create({{/isUri}}jsonElement.{{#isNumber}}getAsString(){{/isNumber}}{{#isInteger}}getAsInt(){{/isInteger}}{{#isUri}}getAsString()){{/isUri}}{{^isNumber}}{{^isInteger}}{{^isUri}}getAs{{{dataType}}}(){{/isUri}}{{/isInteger}}{{/isNumber}};
140+
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
141+
}
142+
{{/gson}}
106143
}{{/isEnum}}{{/vars}}
144+
{{#gson}}
145+
146+
/**
147+
* Validates the JSON Element and throws an exception if issues are found.
148+
*
149+
* @param jsonElement to validate.
150+
* @throws IOException if the JSON Element is not a valid {{classname}} object.
151+
*/
152+
public static void validateJsonElement(final JsonElement jsonElement) throws IOException { {{#requiredVars}}{{#-first}}
153+
if (jsonElement == null) {
154+
throw new IllegalArgumentException(
155+
String.format(
156+
"The required field(s) %s in {{{classname}}} is not found in the empty JSON string",
157+
{{classname}}.openapiRequiredFields.toString()));
158+
}
159+
{{/-first}}{{/requiredVars}}{{!
160+
}}{{^hasChildren}}{{^isAdditionalPropertiesTrue}}
161+
for (final String key : jsonElement.getAsJsonObject().keySet()) {
162+
if (!{{classname}}.openapiFields.contains(key)) {
163+
throw new IllegalArgumentException(
164+
String.format(
165+
"The field `%s` in the JSON string is not defined in the `{{classname}}` properties. JSON: %s",
166+
key, jsonElement));
167+
}
168+
}
169+
{{/isAdditionalPropertiesTrue}}{{!
170+
}}{{#requiredVars}}{{#-first}}
171+
for (final String requiredField : {{classname}}.openapiRequiredFields) {
172+
if (jsonElement.getAsJsonObject().get(requiredField) == null) {
173+
throw new IllegalArgumentException(
174+
String.format(
175+
"The required field `%s` is not found in the JSON string: %s",
176+
requiredField, jsonElement));
177+
}
178+
}
179+
{{/-first}}{{/requiredVars}}{{/hasChildren}}{{!
180+
}}{{^discriminator}}{{#hasVars}}
181+
final JsonObject jsonObj = jsonElement.getAsJsonObject();
182+
{{/hasVars}}{{!
183+
}}{{#vars}}{{^required}}
184+
if (jsonObj.get("{{{baseName}}}") != null
185+
&& !jsonObj.get("{{{baseName}}}").isJsonNull()) { {{/required}}{{!
186+
}}{{^isModel}}{{^isEnumRef}}{{^isEnum}}
187+
{{^required}} {{/required}} if (!jsonObj.get("{{{baseName}}}").{{#isArray}}isJsonArray(){{/isArray}}{{^isContainer}}{{^isModel}}isJsonPrimitive(){{/isModel}}{{/isContainer}}) {
188+
{{^required}} {{/required}} throw new IllegalArgumentException(
189+
{{^required}} {{/required}} String.format(
190+
{{^required}} {{/required}} "Expected the field `{{{baseName}}}` to be {{#isArray}}an array{{/isArray}}{{^isArray}}a primitive type{{/isArray}} in the JSON string but got `%s`",
191+
{{^required}} {{/required}} jsonObj.get("{{{baseName}}}")));
192+
{{^required}} {{/required}} }{{!
193+
}}{{/isEnum}}{{/isEnumRef}}{{/isModel}}{{!
194+
}}{{#items.isModel}}
195+
{{^required}} {{/required}} for (final JsonElement element : jsonObj.getAsJsonArray("{{{baseName}}}").asList()) {
196+
{{^required}} {{/required}} {{{items.dataType}}}.validateJsonElement(element);
197+
{{^required}} {{/required}} }{{!
198+
}}{{/items.isModel}}{{!
199+
}}{{^isContainer}}{{#isModel}}
200+
{{^required}} {{/required}} {{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));{{!
201+
}}{{/isModel}}{{/isContainer}}{{!
202+
}}{{#isEnum}}
203+
{{^required}} {{/required}} {{{datatypeWithEnum}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));{{!
204+
}}{{/isEnum}}{{!
205+
}}{{#isEnumRef}}
206+
{{^required}} {{/required}} {{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));{{!
207+
}}{{/isEnumRef}}
208+
{{^required}}
209+
}
210+
{{/required}}{{/vars}}{{/discriminator}}{{!
211+
}} }
212+
{{/gson}}
107213
}

mustache-templates/target/classes/templates/generateBuilders.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
}}{{!
1717
Source: openapi-to-java-records-mustache-templates
18-
Version: 2.7.1
18+
Version: 2.8.0
1919
Type: Custom
2020
Dependencies:
2121
- none

mustache-templates/target/classes/templates/javadoc.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
}}{{!
1717
Source: openapi-to-java-records-mustache-templates
18-
Version: 2.7.1
18+
Version: 2.8.0
1919
Type: Custom
2020
Dependencies:
2121
- none

mustache-templates/target/classes/templates/licenseInfo.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
}}{{!
1717
Source: openapi-to-java-records-mustache-templates
18-
Version: 2.7.1
18+
Version: 2.8.0
1919
Type: Override
2020
Dependencies:
2121
- none
@@ -39,6 +39,6 @@
3939
* openapi-to-java-records-mustache-templates. For further information,
4040
* questions, requesting features or reporting issues, please visit:
4141
* https://github.com/Chrimle/openapi-to-java-records-mustache-templates.
42-
* Generated with Version: 2.7.1
42+
* Generated with Version: 2.8.0
4343
*
4444
*/

mustache-templates/target/classes/templates/modelEnum.mustache

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
}}{{!
1717
Source: openapi-to-java-records-mustache-templates
18-
Version: 2.7.1
18+
Version: 2.8.0
1919
Type: Override
2020
Dependencies:
2121
- `additionalEnumTypeAnnotations.mustache` (Official)
@@ -26,6 +26,11 @@
2626
- This template is overriding an official 'openapi-generator-maven-plugin' template.
2727
- Generates an `enum` class.
2828
29+
}}{{!
30+
}}{{#gson}}import java.io.IOException;
31+
import com.google.gson.JsonElement;
32+
33+
{{/gson}}{{!
2934
}}{{#isUri}}import java.net.URI;
3035

3136
{{/isUri}}{{>javadoc}}{{!
@@ -78,4 +83,17 @@
7883
}
7984
{{#enumUnknownDefaultCase}}{{#allowableValues}}{{#enumVars}}{{#-last}}return {{{name}}};{{/-last}}{{/enumVars}}{{/allowableValues}}{{/enumUnknownDefaultCase}}{{^enumUnknownDefaultCase}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/enumUnknownDefaultCase}}
8085
}
86+
{{#gson}}
87+
88+
/**
89+
* Validates the JSON Element and throws an exception if issues are found.
90+
*
91+
* @param jsonElement to validate.
92+
* @throws IOException if the JSON Element is not a valid {{classname}} object.
93+
*/
94+
public static void validateJsonElement(final JsonElement jsonElement) throws IOException {
95+
final {{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = {{#isUri}}URI.create({{/isUri}}jsonElement.{{#isNumber}}getAsString(){{/isNumber}}{{#isInteger}}getAsInt(){{/isInteger}}{{#isUri}}getAsString()){{/isUri}}{{^isNumber}}{{^isInteger}}{{^isUri}}getAs{{{dataType}}}(){{/isUri}}{{/isInteger}}{{/isNumber}};
96+
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
97+
}
98+
{{/gson}}
8199
}

0 commit comments

Comments
 (0)