forked from loafle/openapi-generator-original
fix oneOf discriminator lookup in java okhttp-gson client (#11735)
This commit is contained in:
parent
33b89148e5
commit
b0877a112d
@ -6,3 +6,4 @@ templateDir: modules/openapi-generator/src/main/resources/Java
|
||||
additionalProperties:
|
||||
artifactId: petstore-okhttp-gson
|
||||
hideGenerationTimestamp: "true"
|
||||
useOneOfDiscriminatorLookup: "true"
|
||||
|
@ -76,16 +76,20 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
{{#discriminator}}
|
||||
// use discriminator value for faster oneOf lookup
|
||||
{{classname}} new{{classname}} = new {{classname}}();
|
||||
String discriminatorValue = elementAdapter.read(in).getAsJsonObject().get("{{{propertyBaseName}}}").getAsString();
|
||||
switch (discriminatorValue) {
|
||||
{{#mappedModels}}
|
||||
case "{{{mappingName}}}":
|
||||
deserialized = adapter{{modelName}}.fromJsonTree(jsonObject);
|
||||
new{{classname}}.setActualInstance(deserialized);
|
||||
return new{{classname}};
|
||||
{{/mappedModels}}
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for {{classname}}. Possible values:{{#mappedModels}} {{{mappingName}}}{{/mappedModels}}", discriminatorValue));
|
||||
if (jsonObject.get("{{{propertyBaseName}}}") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for {{classname}} as `{{{propertyBaseName}}}` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `{{{propertyBaseName}}}`
|
||||
switch (jsonObject.get("{{{propertyBaseName}}}").getAsString()) {
|
||||
{{#mappedModels}}
|
||||
case "{{{mappingName}}}":
|
||||
deserialized = adapter{{modelName}}.fromJsonTree(jsonObject);
|
||||
new{{classname}}.setActualInstance(deserialized);
|
||||
return new{{classname}};
|
||||
{{/mappedModels}}
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for {{classname}}. Possible values:{{#mappedModels}} {{{mappingName}}}{{/mappedModels}}", jsonObject.get("{{{propertyBaseName}}}").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
{{/discriminator}}
|
||||
|
@ -113,6 +113,30 @@ public class Mammal extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
Mammal newMammal = new Mammal();
|
||||
if (jsonObject.get("className") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for Mammal as `className` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `className`
|
||||
switch (jsonObject.get("className").getAsString()) {
|
||||
case "Pig":
|
||||
deserialized = adapterPig.fromJsonTree(jsonObject);
|
||||
newMammal.setActualInstance(deserialized);
|
||||
return newMammal;
|
||||
case "whale":
|
||||
deserialized = adapterWhale.fromJsonTree(jsonObject);
|
||||
newMammal.setActualInstance(deserialized);
|
||||
return newMammal;
|
||||
case "zebra":
|
||||
deserialized = adapterZebra.fromJsonTree(jsonObject);
|
||||
newMammal.setActualInstance(deserialized);
|
||||
return newMammal;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for Mammal. Possible values: Pig whale zebra", jsonObject.get("className").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -104,6 +104,26 @@ public class NullableShape extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
NullableShape newNullableShape = new NullableShape();
|
||||
if (jsonObject.get("shapeType") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for NullableShape as `shapeType` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `shapeType`
|
||||
switch (jsonObject.get("shapeType").getAsString()) {
|
||||
case "Quadrilateral":
|
||||
deserialized = adapterQuadrilateral.fromJsonTree(jsonObject);
|
||||
newNullableShape.setActualInstance(deserialized);
|
||||
return newNullableShape;
|
||||
case "Triangle":
|
||||
deserialized = adapterTriangle.fromJsonTree(jsonObject);
|
||||
newNullableShape.setActualInstance(deserialized);
|
||||
return newNullableShape;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for NullableShape. Possible values: Quadrilateral Triangle", jsonObject.get("shapeType").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -104,6 +104,26 @@ public class Pig extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
Pig newPig = new Pig();
|
||||
if (jsonObject.get("className") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for Pig as `className` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `className`
|
||||
switch (jsonObject.get("className").getAsString()) {
|
||||
case "BasquePig":
|
||||
deserialized = adapterBasquePig.fromJsonTree(jsonObject);
|
||||
newPig.setActualInstance(deserialized);
|
||||
return newPig;
|
||||
case "DanishPig":
|
||||
deserialized = adapterDanishPig.fromJsonTree(jsonObject);
|
||||
newPig.setActualInstance(deserialized);
|
||||
return newPig;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for Pig. Possible values: BasquePig DanishPig", jsonObject.get("className").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -104,6 +104,26 @@ public class Quadrilateral extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
Quadrilateral newQuadrilateral = new Quadrilateral();
|
||||
if (jsonObject.get("quadrilateralType") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for Quadrilateral as `quadrilateralType` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `quadrilateralType`
|
||||
switch (jsonObject.get("quadrilateralType").getAsString()) {
|
||||
case "ComplexQuadrilateral":
|
||||
deserialized = adapterComplexQuadrilateral.fromJsonTree(jsonObject);
|
||||
newQuadrilateral.setActualInstance(deserialized);
|
||||
return newQuadrilateral;
|
||||
case "SimpleQuadrilateral":
|
||||
deserialized = adapterSimpleQuadrilateral.fromJsonTree(jsonObject);
|
||||
newQuadrilateral.setActualInstance(deserialized);
|
||||
return newQuadrilateral;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for Quadrilateral. Possible values: ComplexQuadrilateral SimpleQuadrilateral", jsonObject.get("quadrilateralType").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -104,6 +104,26 @@ public class Shape extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
Shape newShape = new Shape();
|
||||
if (jsonObject.get("shapeType") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for Shape as `shapeType` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `shapeType`
|
||||
switch (jsonObject.get("shapeType").getAsString()) {
|
||||
case "Quadrilateral":
|
||||
deserialized = adapterQuadrilateral.fromJsonTree(jsonObject);
|
||||
newShape.setActualInstance(deserialized);
|
||||
return newShape;
|
||||
case "Triangle":
|
||||
deserialized = adapterTriangle.fromJsonTree(jsonObject);
|
||||
newShape.setActualInstance(deserialized);
|
||||
return newShape;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for Shape. Possible values: Quadrilateral Triangle", jsonObject.get("shapeType").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -104,6 +104,26 @@ public class ShapeOrNull extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
ShapeOrNull newShapeOrNull = new ShapeOrNull();
|
||||
if (jsonObject.get("shapeType") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for ShapeOrNull as `shapeType` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `shapeType`
|
||||
switch (jsonObject.get("shapeType").getAsString()) {
|
||||
case "Quadrilateral":
|
||||
deserialized = adapterQuadrilateral.fromJsonTree(jsonObject);
|
||||
newShapeOrNull.setActualInstance(deserialized);
|
||||
return newShapeOrNull;
|
||||
case "Triangle":
|
||||
deserialized = adapterTriangle.fromJsonTree(jsonObject);
|
||||
newShapeOrNull.setActualInstance(deserialized);
|
||||
return newShapeOrNull;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for ShapeOrNull. Possible values: Quadrilateral Triangle", jsonObject.get("shapeType").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -113,6 +113,30 @@ public class Triangle extends AbstractOpenApiSchema {
|
||||
Object deserialized = null;
|
||||
JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject();
|
||||
|
||||
// use discriminator value for faster oneOf lookup
|
||||
Triangle newTriangle = new Triangle();
|
||||
if (jsonObject.get("triangleType") == null) {
|
||||
log.log(Level.WARNING, "Failed to lookup discriminator value for Triangle as `triangleType` was not found in the payload or the payload is empty.");
|
||||
} else {
|
||||
// look up the discriminator value in the field `triangleType`
|
||||
switch (jsonObject.get("triangleType").getAsString()) {
|
||||
case "EquilateralTriangle":
|
||||
deserialized = adapterEquilateralTriangle.fromJsonTree(jsonObject);
|
||||
newTriangle.setActualInstance(deserialized);
|
||||
return newTriangle;
|
||||
case "IsoscelesTriangle":
|
||||
deserialized = adapterIsoscelesTriangle.fromJsonTree(jsonObject);
|
||||
newTriangle.setActualInstance(deserialized);
|
||||
return newTriangle;
|
||||
case "ScaleneTriangle":
|
||||
deserialized = adapterScaleneTriangle.fromJsonTree(jsonObject);
|
||||
newTriangle.setActualInstance(deserialized);
|
||||
return newTriangle;
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for Triangle. Possible values: EquilateralTriangle IsoscelesTriangle ScaleneTriangle", jsonObject.get("triangleType").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
TypeAdapter actualAdapter = elementAdapter;
|
||||
|
||||
|
@ -364,6 +364,65 @@ public class JSONTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a oneOf schema can be deserialized into the expected class.
|
||||
* The oneOf schema has a discriminator.
|
||||
*/
|
||||
@Test
|
||||
public void testOneOfSchemaWithDiscriminator() throws Exception {
|
||||
{
|
||||
String str = "{ \"className\": \"whale\", \"hasBaleen\": false, \"hasTeeth\": false }";
|
||||
|
||||
// make sure deserialization works for pojo object
|
||||
Whale w = json.getGson().fromJson(str, Whale.class);
|
||||
assertEquals(w.getClassName(), "whale");
|
||||
assertEquals(w.getHasBaleen(), false);
|
||||
assertEquals(w.getHasTeeth(), false);
|
||||
|
||||
Mammal o = json.getGson().fromJson(str, Mammal.class);
|
||||
assertTrue(o.getActualInstance() instanceof Whale);
|
||||
Whale inst = (Whale) o.getActualInstance();
|
||||
assertEquals(inst.getClassName(), "whale");
|
||||
assertEquals(inst.getHasBaleen(), false);
|
||||
assertEquals(inst.getHasTeeth(), false);
|
||||
assertEquals(json.getGson().toJson(inst), "{\"hasBaleen\":false,\"hasTeeth\":false,\"className\":\"whale\"}");
|
||||
assertEquals(inst.toJson(), "{\"hasBaleen\":false,\"hasTeeth\":false,\"className\":\"whale\"}");
|
||||
assertEquals(json.getGson().toJson(o), "{\"hasBaleen\":false,\"hasTeeth\":false,\"className\":\"whale\"}");
|
||||
assertEquals(o.toJson(), "{\"hasBaleen\":false,\"hasTeeth\":false,\"className\":\"whale\"}");
|
||||
|
||||
String str2 = "{ \"className\": \"zebra\", \"type\": \"plains\" }";
|
||||
|
||||
// make sure deserialization works for pojo object
|
||||
Zebra z = Zebra.fromJson(str2);
|
||||
assertEquals(z.toJson(), "{\"className\":\"zebra\",\"type\":\"plains\"}");
|
||||
|
||||
Mammal o2 = json.getGson().fromJson(str2, Mammal.class);
|
||||
assertTrue(o2.getActualInstance() instanceof Zebra);
|
||||
Zebra inst2 = (Zebra) o2.getActualInstance();
|
||||
assertEquals(json.getGson().toJson(inst2), "{\"className\":\"zebra\",\"type\":\"plains\"}");
|
||||
assertEquals(inst2.toJson(), "{\"className\":\"zebra\",\"type\":\"plains\"}");
|
||||
assertEquals(json.getGson().toJson(o2), "{\"className\":\"zebra\",\"type\":\"plains\"}");
|
||||
assertEquals(o2.toJson(), "{\"className\":\"zebra\",\"type\":\"plains\"}");
|
||||
}
|
||||
{
|
||||
// incorrect payload results in exception
|
||||
String str = "{ \"cultivar\": \"golden delicious\", \"mealy\": false, \"garbage_prop\": \"abc\" }";
|
||||
Exception exception = assertThrows(com.google.gson.JsonSyntaxException.class, () -> {
|
||||
Mammal o = json.getGson().fromJson(str, Mammal.class);
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Failed deserialization for Mammal: 0 classes match result, expected 1. JSON: {\"cultivar\":\"golden delicious\",\"mealy\":false,\"garbage_prop\":\"abc\"}"));
|
||||
}
|
||||
{
|
||||
// Try to deserialize empty object. This should fail 'oneOf' because none will match
|
||||
// whale or zebra.
|
||||
String str = "{ }";
|
||||
Exception exception = assertThrows(com.google.gson.JsonSyntaxException.class, () -> {
|
||||
json.getGson().fromJson(str, Mammal.class);
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Failed deserialization for Mammal: 0 classes match result, expected 1"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a oneOf schema can be deserialized into the expected class.
|
||||
* The oneOf schema does not have a discriminator.
|
||||
|
Loading…
x
Reference in New Issue
Block a user