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][okhttp-gson] validateJsonElement does not validate enum values #16865

Merged
merged 3 commits into from
Nov 8, 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
2 changes: 1 addition & 1 deletion bin/utils/test_file_list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/ClientTest.java"
sha256: db505f7801fef62c13a08a8e9ca1fc4c5c947ab46b46f12943139d353feacf17
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java"
sha256: 3371236d615e7fb79ed87d00c9fc486c31c379195a658781ac9440f0e3228d62
sha256: 6db714e9744c150c8982c3cb18e4f37a9c1ecd8f72f6d58943986e781ab4a344
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/api/PetApiTest.java"
sha256: 0d64cdc11809a7b5b952ccdad2bd91bd0045b3894d6fabf3e368fa0be12b8217
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{{#jackson}}
Copy link
Member

@wing328 wing328 Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you've time, can you please file another PR to clean up {{#jackson}} ... {{/jackson}} in this file as okhttp-gson library doesn't use the jackson mustache tag?

(and we don't need the gson tag either as it must be true when using okhttp-gson)

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
{{/jackson}}
{{#gson}}
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.JsonElement;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
{{/gson}}

/**
* {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
*/
{{#gson}}
@JsonAdapter({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.Adapter.class)
{{/gson}}
{{#jsonb}}
@JsonbTypeSerializer({{datatypeWithEnum}}.Serializer.class)
@JsonbTypeDeserializer({{datatypeWithEnum}}.Deserializer.class)
{{/jsonb}}
{{>additionalEnumTypeAnnotations}}public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#allowableValues}}{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{/withXml}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}

private {{{dataType}}} value;

{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}

{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}

@Override
public String toString() {
return String.valueOf(value);
}

{{#jackson}}
@JsonCreator
{{/jackson}}
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (b.value.{{^isString}}equals{{/isString}}{{#isString}}{{#useEnumCaseInsensitive}}equalsIgnoreCase{{/useEnumCaseInsensitive}}{{^useEnumCaseInsensitive}}equals{{/useEnumCaseInsensitive}}{{/isString}}(value)) {
return b;
}
}
{{#isNullable}}return null;{{/isNullable}}{{^isNullable}}{{#enumUnknownDefaultCase}}{{#allowableValues}}{{#enumVars}}{{#-last}}return {{{name}}};{{/-last}}{{/enumVars}}{{/allowableValues}}{{/enumUnknownDefaultCase}}{{^enumUnknownDefaultCase}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/enumUnknownDefaultCase}}{{/isNullable}}
}
{{#gson}}

public static class Adapter extends TypeAdapter<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> {
@Override
public void write(final JsonWriter jsonWriter, final {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumeration) throws IOException {
jsonWriter.value(enumeration.getValue());
}

@Override
public {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException {
{{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = jsonReader.{{#isNumber}}nextString(){{/isNumber}}{{#isInteger}}nextInt(){{/isInteger}}{{^isNumber}}{{^isInteger}}next{{{dataType}}}(){{/isInteger}}{{/isNumber}};
return {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
{{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = jsonElement.{{#isNumber}}getAsString(){{/isNumber}}{{#isInteger}}getAsInt(){{/isInteger}}{{^isNumber}}{{^isInteger}}getAs{{{dataType}}}(){{/isInteger}}{{/isNumber}};
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
}
{{/gson}}
{{#jsonb}}

public static final class Deserializer implements JsonbDeserializer<{{datatypeWithEnum}}> {
@Override
public {{datatypeWithEnum}} deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(parser.getString())) {
return b;
}
}
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + parser.getString() + "'");{{/useNullForUnknownEnumValue}}
}
}

public static final class Serializer implements JsonbSerializer<{{datatypeWithEnum}}> {
@Override
public void serialize({{datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
generator.write(obj.value);
}
}
{{/jsonb}}
{{#supportUrlQuery}}

/**
* Convert the instance into URL query string.
*
* @param prefix prefix of the query string
* @return URL query string
*/
public String toUrlQueryString(String prefix) {
if (prefix == null) {
prefix = "";
}

return String.format("%s=%s", prefix, this.toString());
}
{{/supportUrlQuery}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
*/
{{#gson}}
@JsonAdapter({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.Adapter.class)
{{/gson}}
{{#jsonb}}
@JsonbTypeSerializer({{datatypeWithEnum}}.Serializer.class)
@JsonbTypeDeserializer({{datatypeWithEnum}}.Deserializer.class)
{{/jsonb}}
{{#withXml}}
@XmlType(name="{{datatypeWithEnum}}")
@XmlEnum({{dataType}}.class)
{{/withXml}}
{{>additionalEnumTypeAnnotations}}public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
{{#allowableValues}}
{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{/withXml}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}

private {{{dataType}}} value;

{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}

{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}

@Override
public String toString() {
return String.valueOf(value);
}

{{#jackson}}
@JsonCreator
{{/jackson}}
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (b.value.{{^isString}}equals{{/isString}}{{#isString}}{{#useEnumCaseInsensitive}}equalsIgnoreCase{{/useEnumCaseInsensitive}}{{^useEnumCaseInsensitive}}equals{{/useEnumCaseInsensitive}}{{/isString}}(value)) {
return b;
}
}
{{#isNullable}}return null;{{/isNullable}}{{^isNullable}}{{#enumUnknownDefaultCase}}{{#allowableValues}}{{#enumVars}}{{#-last}}return {{{name}}};{{/-last}}{{/enumVars}}{{/allowableValues}}{{/enumUnknownDefaultCase}}{{^enumUnknownDefaultCase}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/enumUnknownDefaultCase}}{{/isNullable}}
}
{{#gson}}

public static class Adapter extends TypeAdapter<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}> {
@Override
public void write(final JsonWriter jsonWriter, final {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} enumeration) throws IOException {
jsonWriter.value(enumeration.getValue());
}

@Override
public {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException {
{{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = {{#isFloat}}(float){{/isFloat}} jsonReader.{{#isNumber}}nextString(){{/isNumber}}{{#isInteger}}nextInt(){{/isInteger}}{{^isNumber}}{{^isInteger}}{{#isFloat}}nextDouble{{/isFloat}}{{^isFloat}}next{{{dataType}}}{{/isFloat}}(){{/isInteger}}{{/isNumber}};
return {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
{{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = jsonElement.{{#isNumber}}getAsString(){{/isNumber}}{{#isInteger}}getAsInt(){{/isInteger}}{{^isNumber}}{{^isInteger}}getAs{{{dataType}}}(){{/isInteger}}{{/isNumber}};
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
}
{{/gson}}
{{#jsonb}}
public static final class Deserializer implements JsonbDeserializer<{{datatypeWithEnum}}> {
@Override
public {{datatypeWithEnum}} deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(parser.getString())) {
return b;
}
}
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + parser.getString() + "'");{{/useNullForUnknownEnumValue}}
}
}

public static final class Serializer implements JsonbSerializer<{{datatypeWithEnum}}> {
@Override
public void serialize({{datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
generator.write(obj.value);
}
}
{{/jsonb}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,30 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
}
{{/required}}
{{/isModel}}
{{#isEnum}}
{{#required}}
// validate the required field `{{{baseName}}}`
{{{datatypeWithEnum}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
{{{datatypeWithEnum}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
}
{{/required}}
{{/isEnum}}
{{#isEnumRef}}
{{#required}}
// validate the required field `{{{baseName}}}`
{{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
{{/required}}
{{^required}}
// validate the optional field `{{{baseName}}}`
if (jsonObj.get("{{{baseName}}}") != null && !jsonObj.get("{{{baseName}}}").isJsonNull()) {
{{{dataType}}}.validateJsonElement(jsonObj.get("{{{baseName}}}"));
}
{{/required}}
{{/isEnumRef}}
{{/isContainer}}
{{/vars}}
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ public ArrayStringEnumDefaultEnum read(final JsonReader jsonReader) throws IOExc
return ArrayStringEnumDefaultEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
ArrayStringEnumDefaultEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_ARRAY_STRING_ENUM_DEFAULT = "array_string_enum_default";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public StatusEnum read(final JsonReader jsonReader) throws IOException {
return StatusEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
StatusEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_STATUS = "status";
Expand Down Expand Up @@ -399,6 +404,10 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti
if ((jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) && !jsonObj.get("status").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `status` to be a primitive type in the JSON string but got `%s`", jsonObj.get("status").toString()));
}
// validate the optional field `status`
if (jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) {
StatusEnum.validateJsonElement(jsonObj.get("status"));
}
}

public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ public OutcomesEnum read(final JsonReader jsonReader) throws IOException {
return OutcomesEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
OutcomesEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_OUTCOMES = "outcomes";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.JsonElement;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
Expand Down Expand Up @@ -70,5 +71,10 @@ public StringEnumRef read(final JsonReader jsonReader) throws IOException {
return StringEnumRef.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
StringEnumRef.fromValue(value);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ public TypeEnum read(final JsonReader jsonReader) throws IOException {
return TypeEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
TypeEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_$_TYPE = "$_type";
Expand Down Expand Up @@ -314,6 +319,10 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti
if ((jsonObj.get("$_type") != null && !jsonObj.get("$_type").isJsonNull()) && !jsonObj.get("$_type").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `$_type` to be a primitive type in the JSON string but got `%s`", jsonObj.get("$_type").toString()));
}
// validate the optional field `$_type`
if (jsonObj.get("$_type") != null && !jsonObj.get("$_type").isJsonNull()) {
TypeEnum.validateJsonElement(jsonObj.get("$_type"));
}
if ((jsonObj.get("name") != null && !jsonObj.get("name").isJsonNull()) && !jsonObj.get("name").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ public StatusEnum read(final JsonReader jsonReader) throws IOException {
return StatusEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
StatusEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_STATUS = "status";
Expand Down Expand Up @@ -382,6 +387,10 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti
if ((jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) && !jsonObj.get("status").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `status` to be a primitive type in the JSON string but got `%s`", jsonObj.get("status").toString()));
}
// validate the optional field `status`
if (jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) {
StatusEnum.validateJsonElement(jsonObj.get("status"));
}
}

public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public StatusEnum read(final JsonReader jsonReader) throws IOException {
return StatusEnum.fromValue(value);
}
}

public static void validateJsonElement(JsonElement jsonElement) throws IOException {
String value = jsonElement.getAsString();
StatusEnum.fromValue(value);
}
}

public static final String SERIALIZED_NAME_STATUS = "status";
Expand Down Expand Up @@ -442,6 +447,10 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti
if ((jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) && !jsonObj.get("status").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `status` to be a primitive type in the JSON string but got `%s`", jsonObj.get("status").toString()));
}
// validate the optional field `status`
if (jsonObj.get("status") != null && !jsonObj.get("status").isJsonNull()) {
StatusEnum.validateJsonElement(jsonObj.get("status"));
}
}

public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
Expand Down
Loading
Loading