Skip to content

Commit cca0cbd

Browse files
author
shenwen.yin
committed
feat: support explictly null set in model(poc)
1 parent 47fd3b0 commit cca0cbd

File tree

5 files changed

+231
-46
lines changed

5 files changed

+231
-46
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.smartx.tower;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.smartx.tower.ApiClient;
6+
import com.smartx.tower.ApiException;
7+
import com.smartx.tower.ClientUtil;
8+
import com.smartx.tower.JSON;
9+
import com.smartx.tower.TaskUtil;
10+
import com.smartx.tower.api.BrickTopoApi;
11+
import com.smartx.tower.api.ContentLibraryVmTemplateApi;
12+
import com.smartx.tower.api.MetricsApi;
13+
import com.smartx.tower.api.VmApi;
14+
import com.smartx.tower.api.VmDiskApi;
15+
import com.smartx.tower.model.*;
16+
import java.io.IOException;
17+
import java.util.List;
18+
import java.util.ArrayList;
19+
import java.util.stream.Collectors;
20+
import java.util.Objects;
21+
22+
public class App {
23+
public static void main(String[] args) throws ApiException, IOException {
24+
test();
25+
}
26+
27+
public static void test() throws ApiException, IOException {
28+
VmUpdateHostOptionsParams params = new VmUpdateHostOptionsParams();
29+
VmUpdateHostOptionsParamsData data = new VmUpdateHostOptionsParamsData();
30+
data.hostname(null).presentDnsServers();
31+
params.setData(data);
32+
Gson gson = new JSON().getGson();
33+
System.out.println(gson.toJson(data));
34+
System.out.println(gson.toJson(params));
35+
VmUpdateHostOptionsParamsData data2 = gson.fromJson("{\"dns_servers\":[\"114.114.114.114\"]}",
36+
VmUpdateHostOptionsParamsData.class);
37+
VmUpdateHostOptionsParams params2 = gson.fromJson("{\"data\":{\"dns_servers\":[\"114.114.114.114\"]}}",
38+
VmUpdateHostOptionsParams.class);
39+
System.out.println(data2);
40+
System.out.println(params2);
41+
}
42+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.smartx.tower;
2+
3+
import java.lang.reflect.Field;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
7+
import com.google.gson.Gson;
8+
import com.google.gson.JsonElement;
9+
import com.google.gson.JsonObject;
10+
import com.google.gson.TypeAdapter;
11+
import com.google.gson.TypeAdapterFactory;
12+
import com.google.gson.annotations.SerializedName;
13+
import com.google.gson.reflect.TypeToken;
14+
import com.google.gson.stream.JsonReader;
15+
import com.google.gson.stream.JsonWriter;
16+
17+
public class ConditionalNullable {
18+
private final static String IS_PRESENT = "_isPresent_";
19+
20+
public static class ConditionalNullablePojo {
21+
protected Set<String> _isPresent_ = new HashSet<String>();
22+
}
23+
24+
public static class ConditionalNullablePojoAdapterFactory implements TypeAdapterFactory {
25+
@Override
26+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
27+
Class<? super T> rawType = type.getRawType();
28+
if (!ConditionalNullablePojo.class.isAssignableFrom(rawType)) {
29+
return null;
30+
}
31+
Set<String> jsonField = new HashSet<>();
32+
Field[] fields = rawType.getDeclaredFields();
33+
for (int i = 0; i < fields.length; i++) {
34+
Field field = fields[i];
35+
if (field.isAnnotationPresent(SerializedName.class)) {
36+
jsonField.add(field.getAnnotation(SerializedName.class).value());
37+
}
38+
}
39+
return new TypeAdapter<T>() {
40+
@Override
41+
public void write(JsonWriter out, T value) throws java.io.IOException {
42+
if (value == null) {
43+
out.nullValue();
44+
return;
45+
}
46+
ConditionalNullablePojo pojo = (ConditionalNullablePojo) value;
47+
TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(ConditionalNullablePojoAdapterFactory.this,
48+
type);
49+
TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
50+
JsonObject jobj = delegateAdapter.toJsonTree(value).getAsJsonObject();
51+
for (String fieldName : jsonField) {
52+
if (jobj.has(fieldName) && jobj.get(fieldName).isJsonNull()
53+
&& !pojo._isPresent_.contains(fieldName)) {
54+
jobj.remove(fieldName);
55+
}
56+
}
57+
if (jobj.has(IS_PRESENT)) {
58+
jobj.remove(IS_PRESENT);
59+
}
60+
if (!out.getSerializeNulls()) {
61+
out.setSerializeNulls(true);
62+
elementAdapter.write(out, jobj);
63+
out.setSerializeNulls(false);
64+
} else {
65+
elementAdapter.write(out, jobj);
66+
}
67+
}
68+
69+
public T read(JsonReader in) throws java.io.IOException {
70+
JsonObject jsonObject = gson.getAdapter(JsonElement.class).read(in).getAsJsonObject();
71+
T instance = gson.getDelegateAdapter(ConditionalNullablePojoAdapterFactory.this, type)
72+
.fromJsonTree(jsonObject);
73+
return instance;
74+
}
75+
};
76+
}
77+
}
78+
}

src/main/java/com/smartx/tower/JSON.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ public class JSON {
3939

4040
@SuppressWarnings("unchecked")
4141
public static GsonBuilder createGson() {
42-
GsonFireBuilder fireBuilder = new GsonFireBuilder()
43-
;
42+
GsonFireBuilder fireBuilder = new GsonFireBuilder();
4443
GsonBuilder builder = fireBuilder.createGsonBuilder();
4544
return builder;
4645
}
@@ -54,10 +53,13 @@ private static String getDiscriminatorValue(JsonElement readElement, String disc
5453
}
5554

5655
/**
57-
* Returns the Java class that implements the OpenAPI schema for the specified discriminator value.
56+
* Returns the Java class that implements the OpenAPI schema for the specified
57+
* discriminator value.
5858
*
59-
* @param classByDiscriminatorValue The map of discriminator values to Java classes.
60-
* @param discriminatorValue The value of the OpenAPI discriminator in the input data.
59+
* @param classByDiscriminatorValue The map of discriminator values to Java
60+
* classes.
61+
* @param discriminatorValue The value of the OpenAPI discriminator in
62+
* the input data.
6163
* @return The Java class that implements the OpenAPI schema
6264
*/
6365
private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) {
@@ -70,12 +72,13 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri
7072

7173
public JSON() {
7274
gson = createGson()
73-
.registerTypeAdapter(Date.class, dateTypeAdapter)
74-
.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
75-
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
76-
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
77-
.registerTypeAdapter(byte[].class, byteArrayAdapter)
78-
.create();
75+
.registerTypeAdapter(Date.class, dateTypeAdapter)
76+
.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
77+
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
78+
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
79+
.registerTypeAdapter(byte[].class, byteArrayAdapter)
80+
.registerTypeAdapterFactory(new ConditionalNullable.ConditionalNullablePojoAdapterFactory())
81+
.create();
7982
}
8083

8184
/**
@@ -103,7 +106,8 @@ public JSON setGson(Gson gson) {
103106
*
104107
* @param lenientOnJson Set it to true to ignore some syntax errors
105108
* @return JSON
106-
* @see <a href="https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html">https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html</a>
109+
* @see <a href=
110+
* "https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html">https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html</a>
107111
*/
108112
public JSON setLenientOnJson(boolean lenientOnJson) {
109113
isLenientOnJson = lenientOnJson;
@@ -133,7 +137,8 @@ public <T> T deserialize(String body, Type returnType) {
133137
try {
134138
if (isLenientOnJson) {
135139
JsonReader jsonReader = new JsonReader(new StringReader(body));
136-
// see https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html
140+
// see
141+
// https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html
137142
jsonReader.setLenient(true);
138143
return gson.fromJson(jsonReader, returnType);
139144
} else {
@@ -215,7 +220,7 @@ public OffsetDateTime read(JsonReader in) throws IOException {
215220
default:
216221
String date = in.nextString();
217222
if (date.endsWith("+0000")) {
218-
date = date.substring(0, date.length()-5) + "Z";
223+
date = date.substring(0, date.length() - 5) + "Z";
219224
}
220225
return OffsetDateTime.parse(date, formatter);
221226
}
@@ -282,7 +287,8 @@ public static class SqlDateTypeAdapter extends TypeAdapter<java.sql.Date> {
282287

283288
private DateFormat dateFormat;
284289

285-
public SqlDateTypeAdapter() {}
290+
public SqlDateTypeAdapter() {
291+
}
286292

287293
public SqlDateTypeAdapter(DateFormat dateFormat) {
288294
this.dateFormat = dateFormat;
@@ -335,7 +341,8 @@ public static class DateTypeAdapter extends TypeAdapter<Date> {
335341

336342
private DateFormat dateFormat;
337343

338-
public DateTypeAdapter() {}
344+
public DateTypeAdapter() {
345+
}
339346

340347
public DateTypeAdapter(DateFormat dateFormat) {
341348
this.dateFormat = dateFormat;

src/main/java/com/smartx/tower/model/VmUpdateHostOptionsParams.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.google.gson.annotations.SerializedName;
88
import com.google.gson.stream.JsonReader;
99
import com.google.gson.stream.JsonWriter;
10+
import com.smartx.tower.ConditionalNullable;
1011
import com.smartx.tower.model.VmUpdateHostOptionsParamsData;
1112
import com.smartx.tower.model.VmWhereInput;
1213
import io.swagger.annotations.ApiModel;
@@ -17,7 +18,7 @@
1718
* VmUpdateHostOptionsParams
1819
*/
1920
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaSmartxClientCodegen")
20-
public class VmUpdateHostOptionsParams {
21+
public class VmUpdateHostOptionsParams extends ConditionalNullable.ConditionalNullablePojo {
2122
public static final String SERIALIZED_NAME_DATA = "data";
2223
@SerializedName(SERIALIZED_NAME_DATA)
2324
private VmUpdateHostOptionsParamsData data;
@@ -26,55 +27,53 @@ public class VmUpdateHostOptionsParams {
2627
@SerializedName(SERIALIZED_NAME_WHERE)
2728
private VmWhereInput where;
2829

29-
public VmUpdateHostOptionsParams() {
30+
public VmUpdateHostOptionsParams() {
3031
}
3132

3233
public VmUpdateHostOptionsParams data(VmUpdateHostOptionsParamsData data) {
33-
34+
3435
this.data = data;
3536
return this;
3637
}
3738

38-
/**
39+
/**
3940
* Get data
41+
*
4042
* @return data
41-
**/
43+
**/
4244
@javax.annotation.Nonnull
4345
@ApiModelProperty(required = true, value = "")
4446

4547
public VmUpdateHostOptionsParamsData getData() {
4648
return data;
4749
}
4850

49-
5051
public void setData(VmUpdateHostOptionsParamsData data) {
5152
this.data = data;
5253
}
5354

54-
5555
public VmUpdateHostOptionsParams where(VmWhereInput where) {
56-
56+
5757
this.where = where;
5858
return this;
5959
}
6060

61-
/**
61+
/**
6262
* Get where
63+
*
6364
* @return where
64-
**/
65+
**/
6566
@javax.annotation.Nonnull
6667
@ApiModelProperty(required = true, value = "")
6768

6869
public VmWhereInput getWhere() {
6970
return where;
7071
}
7172

72-
7373
public void setWhere(VmWhereInput where) {
7474
this.where = where;
7575
}
7676

77-
7877
@Override
7978
public boolean equals(Object o) {
8079
if (this == o) {
@@ -113,6 +112,4 @@ private String toIndentedString(Object o) {
113112
}
114113
return o.toString().replace("\n", "\n ");
115114
}
116-
117115
}
118-

0 commit comments

Comments
 (0)