diff --git a/src/main/java/com/smartx/tower/App.java b/src/main/java/com/smartx/tower/App.java new file mode 100644 index 00000000..bd239dbf --- /dev/null +++ b/src/main/java/com/smartx/tower/App.java @@ -0,0 +1,27 @@ +package com.smartx.tower; + +import com.google.gson.Gson; +import com.smartx.tower.model.*; +import java.io.IOException; + +public class App { + public static void main(String[] args) throws ApiException, IOException { + test(); + } + + public static void test() throws ApiException, IOException { + VmUpdateHostOptionsParams params = new VmUpdateHostOptionsParams(); + VmUpdateHostOptionsParamsData data = new VmUpdateHostOptionsParamsData(); + data.hostname(null).presentDnsServers(); + params.setData(data); + Gson gson = new JSON().getGson(); + System.out.println(gson.toJson(data)); + System.out.println(gson.toJson(params)); + VmUpdateHostOptionsParamsData data2 = gson.fromJson("{\"dns_servers\":[\"114.114.114.114\"]}", + VmUpdateHostOptionsParamsData.class); + VmUpdateHostOptionsParams params2 = gson.fromJson("{\"data\":{\"dns_servers\":[\"114.114.114.114\"]}}", + VmUpdateHostOptionsParams.class); + System.out.println(data2); + System.out.println(params2); + } +} \ No newline at end of file diff --git a/src/main/java/com/smartx/tower/ConditionalNullable.java b/src/main/java/com/smartx/tower/ConditionalNullable.java new file mode 100644 index 00000000..4d88b838 --- /dev/null +++ b/src/main/java/com/smartx/tower/ConditionalNullable.java @@ -0,0 +1,100 @@ +package com.smartx.tower; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +public class ConditionalNullable { + private final static String IS_PRESENT = "_isPresent_"; + + public static class ConditionalNullablePojo { + protected Set _isPresent_ = new HashSet(); + } + + public static class ConditionalNullablePojoAdapterFactory implements TypeAdapterFactory { + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + Class rawType = type.getRawType(); + if (!ConditionalNullablePojo.class.isAssignableFrom(rawType)) { + return null; + } + Map jsonField = new HashMap<>(); + Field[] fields = rawType.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (field.isAnnotationPresent(SerializedName.class)) { + jsonField.put(field.getAnnotation(SerializedName.class).value(), field); + } + } + return new TypeAdapter() { + @Override + public void write(JsonWriter out, T value) + throws java.io.IOException { + if (value == null) { + out.nullValue(); + return; + } + out.beginObject(); + ConditionalNullablePojo pojo = (ConditionalNullablePojo) value; + // TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + for (Map.Entry entry : jsonField.entrySet()) { + String fieldName = entry.getKey(); + Field field = entry.getValue(); + // get the value of the field + Object fieldValue; + try { + // mostly the field is private, so we need to make it accessible + if (!field.canAccess(value)) { + field.setAccessible(true); + } + fieldValue = field.get(value); + } catch (IllegalArgumentException | IllegalAccessException e) { + fieldValue = null; + } + if (fieldValue == null) { + if (pojo._isPresent_.contains(fieldName)) { + out.name(fieldName); + if (!out.getSerializeNulls()) { + out.setSerializeNulls(true); + out.nullValue(); + out.setSerializeNulls(false); + } else { + out.nullValue(); + } + } + } else { + // write the non null field with native adapter + out.name(fieldName); + @SuppressWarnings("unchecked") + TypeAdapter delegatedAdapter = (TypeAdapter) gson + .getAdapter(field.getType()); + if (delegatedAdapter != null && fieldValue != null) { + delegatedAdapter.write(out, fieldValue); + } + } + } + out.endObject(); + } + + public T read(JsonReader in) throws java.io.IOException { + JsonObject jsonObject = gson.getAdapter(JsonElement.class).read(in).getAsJsonObject(); + T instance = gson.getDelegateAdapter(ConditionalNullablePojoAdapterFactory.this, type) + .fromJsonTree(jsonObject); + return instance; + } + }; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/smartx/tower/JSON.java b/src/main/java/com/smartx/tower/JSON.java index ba03d111..b8643ede 100644 --- a/src/main/java/com/smartx/tower/JSON.java +++ b/src/main/java/com/smartx/tower/JSON.java @@ -39,8 +39,7 @@ public class JSON { @SuppressWarnings("unchecked") public static GsonBuilder createGson() { - GsonFireBuilder fireBuilder = new GsonFireBuilder() - ; + GsonFireBuilder fireBuilder = new GsonFireBuilder(); GsonBuilder builder = fireBuilder.createGsonBuilder(); return builder; } @@ -54,10 +53,13 @@ private static String getDiscriminatorValue(JsonElement readElement, String disc } /** - * Returns the Java class that implements the OpenAPI schema for the specified discriminator value. + * Returns the Java class that implements the OpenAPI schema for the specified + * discriminator value. * - * @param classByDiscriminatorValue The map of discriminator values to Java classes. - * @param discriminatorValue The value of the OpenAPI discriminator in the input data. + * @param classByDiscriminatorValue The map of discriminator values to Java + * classes. + * @param discriminatorValue The value of the OpenAPI discriminator in + * the input data. * @return The Java class that implements the OpenAPI schema */ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) { @@ -70,12 +72,13 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri public JSON() { gson = createGson() - .registerTypeAdapter(Date.class, dateTypeAdapter) - .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) - .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) - .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) - .registerTypeAdapter(byte[].class, byteArrayAdapter) - .create(); + .registerTypeAdapter(Date.class, dateTypeAdapter) + .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) + .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) + .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) + .registerTypeAdapter(byte[].class, byteArrayAdapter) + .registerTypeAdapterFactory(new ConditionalNullable.ConditionalNullablePojoAdapterFactory()) + .create(); } /** @@ -103,7 +106,8 @@ public JSON setGson(Gson gson) { * * @param lenientOnJson Set it to true to ignore some syntax errors * @return JSON - * @see https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html + * @see https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html */ public JSON setLenientOnJson(boolean lenientOnJson) { isLenientOnJson = lenientOnJson; @@ -133,7 +137,8 @@ public T deserialize(String body, Type returnType) { try { if (isLenientOnJson) { JsonReader jsonReader = new JsonReader(new StringReader(body)); - // see https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html + // see + // https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html jsonReader.setLenient(true); return gson.fromJson(jsonReader, returnType); } else { @@ -215,7 +220,7 @@ public OffsetDateTime read(JsonReader in) throws IOException { default: String date = in.nextString(); if (date.endsWith("+0000")) { - date = date.substring(0, date.length()-5) + "Z"; + date = date.substring(0, date.length() - 5) + "Z"; } return OffsetDateTime.parse(date, formatter); } @@ -282,7 +287,8 @@ public static class SqlDateTypeAdapter extends TypeAdapter { private DateFormat dateFormat; - public SqlDateTypeAdapter() {} + public SqlDateTypeAdapter() { + } public SqlDateTypeAdapter(DateFormat dateFormat) { this.dateFormat = dateFormat; @@ -335,7 +341,8 @@ public static class DateTypeAdapter extends TypeAdapter { private DateFormat dateFormat; - public DateTypeAdapter() {} + public DateTypeAdapter() { + } public DateTypeAdapter(DateFormat dateFormat) { this.dateFormat = dateFormat; diff --git a/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParams.java b/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParams.java index 5c434779..3191c038 100644 --- a/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParams.java +++ b/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParams.java @@ -7,6 +7,7 @@ import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import com.smartx.tower.ConditionalNullable; import com.smartx.tower.model.VmUpdateHostOptionsParamsData; import com.smartx.tower.model.VmWhereInput; import io.swagger.annotations.ApiModel; @@ -17,7 +18,7 @@ * VmUpdateHostOptionsParams */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaSmartxClientCodegen") -public class VmUpdateHostOptionsParams { +public class VmUpdateHostOptionsParams extends ConditionalNullable.ConditionalNullablePojo { public static final String SERIALIZED_NAME_DATA = "data"; @SerializedName(SERIALIZED_NAME_DATA) private VmUpdateHostOptionsParamsData data; @@ -26,19 +27,20 @@ public class VmUpdateHostOptionsParams { @SerializedName(SERIALIZED_NAME_WHERE) private VmWhereInput where; - public VmUpdateHostOptionsParams() { + public VmUpdateHostOptionsParams() { } public VmUpdateHostOptionsParams data(VmUpdateHostOptionsParamsData data) { - + this.data = data; return this; } - /** + /** * Get data + * * @return data - **/ + **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") @@ -46,22 +48,21 @@ public VmUpdateHostOptionsParamsData getData() { return data; } - public void setData(VmUpdateHostOptionsParamsData data) { this.data = data; } - public VmUpdateHostOptionsParams where(VmWhereInput where) { - + this.where = where; return this; } - /** + /** * Get where + * * @return where - **/ + **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") @@ -69,12 +70,10 @@ public VmWhereInput getWhere() { return where; } - public void setWhere(VmWhereInput where) { this.where = where; } - @Override public boolean equals(Object o) { if (this == o) { @@ -113,6 +112,4 @@ private String toIndentedString(Object o) { } return o.toString().replace("\n", "\n "); } - } - diff --git a/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParamsData.java b/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParamsData.java index f4c2558a..78432ef1 100644 --- a/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParamsData.java +++ b/src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParamsData.java @@ -1,23 +1,35 @@ package com.smartx.tower.model; import java.util.Objects; +import java.util.Set; import java.util.Arrays; +import java.util.HashSet; + +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import com.smartx.tower.ConditionalNullable.*; + import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.IOException; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; /** * VmUpdateHostOptionsParamsData */ +// @JsonAdapter(VmUpdateHostOptionsParamsData.Serializer.class) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaSmartxClientCodegen") -public class VmUpdateHostOptionsParamsData { +public class VmUpdateHostOptionsParamsData extends ConditionalNullablePojo { public static final String SERIALIZED_NAME_NTP_SERVERS = "ntp_servers"; @SerializedName(SERIALIZED_NAME_NTP_SERVERS) private List ntpServers = null; @@ -30,15 +42,25 @@ public class VmUpdateHostOptionsParamsData { @SerializedName(SERIALIZED_NAME_HOSTNAME) private String hostname; - public VmUpdateHostOptionsParamsData() { + public VmUpdateHostOptionsParamsData() { } public VmUpdateHostOptionsParamsData ntpServers(List ntpServers) { - + this.ntpServers = ntpServers; return this; } + public VmUpdateHostOptionsParamsData presentNtpServers() { + _isPresent_.add(SERIALIZED_NAME_NTP_SERVERS); + return this; + } + + public VmUpdateHostOptionsParamsData absentNtpServers() { + _isPresent_.remove(SERIALIZED_NAME_NTP_SERVERS); + return this; + } + public VmUpdateHostOptionsParamsData addNtpServersItem(String ntpServersItem) { if (this.ntpServers == null) { this.ntpServers = new ArrayList(); @@ -47,10 +69,11 @@ public VmUpdateHostOptionsParamsData addNtpServersItem(String ntpServersItem) { return this; } - /** + /** * Get ntpServers + * * @return ntpServers - **/ + **/ @javax.annotation.Nullable @ApiModelProperty(value = "") @@ -58,18 +81,34 @@ public List getNtpServers() { return ntpServers; } + public void setPresentNtpServers(boolean present) { + if (present) { + _isPresent_.add(SERIALIZED_NAME_NTP_SERVERS); + } else { + _isPresent_.remove(SERIALIZED_NAME_NTP_SERVERS); + } + } public void setNtpServers(List ntpServers) { this.ntpServers = ntpServers; } - public VmUpdateHostOptionsParamsData dnsServers(List dnsServers) { - + this.dnsServers = dnsServers; return this; } + public VmUpdateHostOptionsParamsData presentDnsServers() { + _isPresent_.add(SERIALIZED_NAME_DNS_SERVERS); + return this; + } + + public VmUpdateHostOptionsParamsData absentDnsServers() { + _isPresent_.remove(SERIALIZED_NAME_DNS_SERVERS); + return this; + } + public VmUpdateHostOptionsParamsData addDnsServersItem(String dnsServersItem) { if (this.dnsServers == null) { this.dnsServers = new ArrayList(); @@ -78,10 +117,11 @@ public VmUpdateHostOptionsParamsData addDnsServersItem(String dnsServersItem) { return this; } - /** + /** * Get dnsServers + * * @return dnsServers - **/ + **/ @javax.annotation.Nullable @ApiModelProperty(value = "") @@ -89,22 +129,39 @@ public List getDnsServers() { return dnsServers; } - public void setDnsServers(List dnsServers) { this.dnsServers = dnsServers; } + public void setPresentDnsServers(boolean present) { + if (present) { + _isPresent_.add(SERIALIZED_NAME_DNS_SERVERS); + } else { + _isPresent_.remove(SERIALIZED_NAME_DNS_SERVERS); + } + } public VmUpdateHostOptionsParamsData hostname(String hostname) { - + this.hostname = hostname; return this; } - /** + public VmUpdateHostOptionsParamsData presentHostname() { + _isPresent_.add(SERIALIZED_NAME_HOSTNAME); + return this; + } + + public VmUpdateHostOptionsParamsData absentHostname() { + _isPresent_.remove(SERIALIZED_NAME_HOSTNAME); + return this; + } + + /** * Get hostname + * * @return hostname - **/ + **/ @javax.annotation.Nullable @ApiModelProperty(value = "") @@ -112,11 +169,17 @@ public String getHostname() { return hostname; } - public void setHostname(String hostname) { this.hostname = hostname; } + public void setPresentHostname(boolean present) { + if (present) { + _isPresent_.add(SERIALIZED_NAME_HOSTNAME); + } else { + _isPresent_.remove(SERIALIZED_NAME_HOSTNAME); + } + } @Override public boolean equals(Object o) { @@ -158,6 +221,4 @@ private String toIndentedString(Object o) { } return o.toString().replace("\n", "\n "); } - } -