[Default] update isAdditionalPropertiesTrue tag to cover more types (#16227)

* enhance additional properties support

* update samples

* update tests

* add more tests

* update samples

* fix samples
This commit is contained in:
William Cheng
2023-08-05 13:32:43 +08:00
committed by GitHub
parent c080660cc1
commit f6fb83878b
142 changed files with 2965 additions and 332 deletions

View File

@@ -169,6 +169,50 @@ public class Drawing {
this.shapes = shapes;
}
/**
* A container for additional, undeclared properties.
* This is a holder for any undeclared properties as specified with
* the 'additionalProperties' keyword in the OAS document.
*/
private Map<String, Object> additionalProperties;
/**
* Set the additional (undeclared) property with the specified name and value.
* If the property does not already exist, create it otherwise replace it.
*
* @param key name of the property
* @param value value of the property
* @return the Drawing instance itself
*/
public Drawing putAdditionalProperty(String key, Object value) {
if (this.additionalProperties == null) {
this.additionalProperties = new HashMap<String, Object>();
}
this.additionalProperties.put(key, value);
return this;
}
/**
* Return the additional (undeclared) property.
*
* @return a map of objects
*/
public Map<String, Object> getAdditionalProperties() {
return additionalProperties;
}
/**
* Return the additional (undeclared) property with the specified name.
*
* @param key name of the property
* @return an object
*/
public Object getAdditionalProperty(String key) {
if (this.additionalProperties == null) {
return null;
}
return this.additionalProperties.get(key);
}
@Override
@@ -183,7 +227,8 @@ public class Drawing {
return Objects.equals(this.mainShape, drawing.mainShape) &&
Objects.equals(this.shapeOrNull, drawing.shapeOrNull) &&
Objects.equals(this.nullableShape, drawing.nullableShape) &&
Objects.equals(this.shapes, drawing.shapes);
Objects.equals(this.shapes, drawing.shapes)&&
Objects.equals(this.additionalProperties, drawing.additionalProperties);
}
private static <T> boolean equalsNullable(JsonNullable<T> a, JsonNullable<T> b) {
@@ -192,7 +237,7 @@ public class Drawing {
@Override
public int hashCode() {
return Objects.hash(mainShape, shapeOrNull, nullableShape, shapes);
return Objects.hash(mainShape, shapeOrNull, nullableShape, shapes, additionalProperties);
}
private static <T> int hashCodeNullable(JsonNullable<T> a) {
@@ -210,6 +255,7 @@ public class Drawing {
sb.append(" shapeOrNull: ").append(toIndentedString(shapeOrNull)).append("\n");
sb.append(" nullableShape: ").append(toIndentedString(nullableShape)).append("\n");
sb.append(" shapes: ").append(toIndentedString(shapes)).append("\n");
sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
sb.append("}");
return sb.toString();
}
@@ -253,14 +299,6 @@ public class Drawing {
throw new IllegalArgumentException(String.format("The required field(s) %s in Drawing is not found in the empty JSON string", Drawing.openapiRequiredFields.toString()));
}
}
Set<Entry<String, JsonElement>> entries = jsonElement.getAsJsonObject().entrySet();
// check to see if the JSON string contains additional fields
for (Entry<String, JsonElement> entry : entries) {
if (!Drawing.openapiFields.contains(entry.getKey())) {
throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `Drawing` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
}
}
JsonObject jsonObj = jsonElement.getAsJsonObject();
// validate the optional field `mainShape`
if (jsonObj.get("mainShape") != null && !jsonObj.get("mainShape").isJsonNull()) {
@@ -305,6 +343,23 @@ public class Drawing {
@Override
public void write(JsonWriter out, Drawing value) throws IOException {
JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
obj.remove("additionalProperties");
// serialize additional properties
if (value.getAdditionalProperties() != null) {
for (Map.Entry<String, Object> entry : value.getAdditionalProperties().entrySet()) {
if (entry.getValue() instanceof String)
obj.addProperty(entry.getKey(), (String) entry.getValue());
else if (entry.getValue() instanceof Number)
obj.addProperty(entry.getKey(), (Number) entry.getValue());
else if (entry.getValue() instanceof Boolean)
obj.addProperty(entry.getKey(), (Boolean) entry.getValue());
else if (entry.getValue() instanceof Character)
obj.addProperty(entry.getKey(), (Character) entry.getValue());
else {
obj.add(entry.getKey(), gson.toJsonTree(entry.getValue()).getAsJsonObject());
}
}
}
elementAdapter.write(out, obj);
}
@@ -312,7 +367,28 @@ public class Drawing {
public Drawing read(JsonReader in) throws IOException {
JsonElement jsonElement = elementAdapter.read(in);
validateJsonElement(jsonElement);
return thisAdapter.fromJsonTree(jsonElement);
JsonObject jsonObj = jsonElement.getAsJsonObject();
// store additional fields in the deserialized instance
Drawing instance = thisAdapter.fromJsonTree(jsonObj);
for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
if (!openapiFields.contains(entry.getKey())) {
if (entry.getValue().isJsonPrimitive()) { // primitive type
if (entry.getValue().getAsJsonPrimitive().isString())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString());
else if (entry.getValue().getAsJsonPrimitive().isNumber())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber());
else if (entry.getValue().getAsJsonPrimitive().isBoolean())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean());
else
throw new IllegalArgumentException(String.format("The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString()));
} else if (entry.getValue().isJsonArray()) {
instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), List.class));
} else { // JSON object
instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class));
}
}
}
return instance;
}
}.nullSafe();

View File

@@ -410,6 +410,50 @@ public class NullableClass {
this.objectItemsNullable = objectItemsNullable;
}
/**
* A container for additional, undeclared properties.
* This is a holder for any undeclared properties as specified with
* the 'additionalProperties' keyword in the OAS document.
*/
private Map<String, Object> additionalProperties;
/**
* Set the additional (undeclared) property with the specified name and value.
* If the property does not already exist, create it otherwise replace it.
*
* @param key name of the property
* @param value value of the property
* @return the NullableClass instance itself
*/
public NullableClass putAdditionalProperty(String key, Object value) {
if (this.additionalProperties == null) {
this.additionalProperties = new HashMap<String, Object>();
}
this.additionalProperties.put(key, value);
return this;
}
/**
* Return the additional (undeclared) property.
*
* @return a map of objects
*/
public Map<String, Object> getAdditionalProperties() {
return additionalProperties;
}
/**
* Return the additional (undeclared) property with the specified name.
*
* @param key name of the property
* @return an object
*/
public Object getAdditionalProperty(String key) {
if (this.additionalProperties == null) {
return null;
}
return this.additionalProperties.get(key);
}
@Override
@@ -432,7 +476,8 @@ public class NullableClass {
Objects.equals(this.arrayItemsNullable, nullableClass.arrayItemsNullable) &&
Objects.equals(this.objectNullableProp, nullableClass.objectNullableProp) &&
Objects.equals(this.objectAndItemsNullableProp, nullableClass.objectAndItemsNullableProp) &&
Objects.equals(this.objectItemsNullable, nullableClass.objectItemsNullable);
Objects.equals(this.objectItemsNullable, nullableClass.objectItemsNullable)&&
Objects.equals(this.additionalProperties, nullableClass.additionalProperties);
}
private static <T> boolean equalsNullable(JsonNullable<T> a, JsonNullable<T> b) {
@@ -441,7 +486,7 @@ public class NullableClass {
@Override
public int hashCode() {
return Objects.hash(integerProp, numberProp, booleanProp, stringProp, dateProp, datetimeProp, arrayNullableProp, arrayAndItemsNullableProp, arrayItemsNullable, objectNullableProp, objectAndItemsNullableProp, objectItemsNullable);
return Objects.hash(integerProp, numberProp, booleanProp, stringProp, dateProp, datetimeProp, arrayNullableProp, arrayAndItemsNullableProp, arrayItemsNullable, objectNullableProp, objectAndItemsNullableProp, objectItemsNullable, additionalProperties);
}
private static <T> int hashCodeNullable(JsonNullable<T> a) {
@@ -467,6 +512,7 @@ public class NullableClass {
sb.append(" objectNullableProp: ").append(toIndentedString(objectNullableProp)).append("\n");
sb.append(" objectAndItemsNullableProp: ").append(toIndentedString(objectAndItemsNullableProp)).append("\n");
sb.append(" objectItemsNullable: ").append(toIndentedString(objectItemsNullable)).append("\n");
sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
sb.append("}");
return sb.toString();
}
@@ -518,14 +564,6 @@ public class NullableClass {
throw new IllegalArgumentException(String.format("The required field(s) %s in NullableClass is not found in the empty JSON string", NullableClass.openapiRequiredFields.toString()));
}
}
Set<Entry<String, JsonElement>> entries = jsonElement.getAsJsonObject().entrySet();
// check to see if the JSON string contains additional fields
for (Entry<String, JsonElement> entry : entries) {
if (!NullableClass.openapiFields.contains(entry.getKey())) {
throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `NullableClass` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
}
}
JsonObject jsonObj = jsonElement.getAsJsonObject();
if ((jsonObj.get("string_prop") != null && !jsonObj.get("string_prop").isJsonNull()) && !jsonObj.get("string_prop").isJsonPrimitive()) {
throw new IllegalArgumentException(String.format("Expected the field `string_prop` to be a primitive type in the JSON string but got `%s`", jsonObj.get("string_prop").toString()));
@@ -559,6 +597,23 @@ public class NullableClass {
@Override
public void write(JsonWriter out, NullableClass value) throws IOException {
JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
obj.remove("additionalProperties");
// serialize additional properties
if (value.getAdditionalProperties() != null) {
for (Map.Entry<String, Object> entry : value.getAdditionalProperties().entrySet()) {
if (entry.getValue() instanceof String)
obj.addProperty(entry.getKey(), (String) entry.getValue());
else if (entry.getValue() instanceof Number)
obj.addProperty(entry.getKey(), (Number) entry.getValue());
else if (entry.getValue() instanceof Boolean)
obj.addProperty(entry.getKey(), (Boolean) entry.getValue());
else if (entry.getValue() instanceof Character)
obj.addProperty(entry.getKey(), (Character) entry.getValue());
else {
obj.add(entry.getKey(), gson.toJsonTree(entry.getValue()).getAsJsonObject());
}
}
}
elementAdapter.write(out, obj);
}
@@ -566,7 +621,28 @@ public class NullableClass {
public NullableClass read(JsonReader in) throws IOException {
JsonElement jsonElement = elementAdapter.read(in);
validateJsonElement(jsonElement);
return thisAdapter.fromJsonTree(jsonElement);
JsonObject jsonObj = jsonElement.getAsJsonObject();
// store additional fields in the deserialized instance
NullableClass instance = thisAdapter.fromJsonTree(jsonObj);
for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
if (!openapiFields.contains(entry.getKey())) {
if (entry.getValue().isJsonPrimitive()) { // primitive type
if (entry.getValue().getAsJsonPrimitive().isString())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString());
else if (entry.getValue().getAsJsonPrimitive().isNumber())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber());
else if (entry.getValue().getAsJsonPrimitive().isBoolean())
instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean());
else
throw new IllegalArgumentException(String.format("The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString()));
} else if (entry.getValue().isJsonArray()) {
instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), List.class));
} else { // JSON object
instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class));
}
}
}
return instance;
}
}.nullSafe();