Skip to content

Commit e318b84

Browse files
Merge branch 'main' into 519
2 parents 9fda6d0 + dadfe7f commit e318b84

17 files changed

Lines changed: 466 additions & 36 deletions

File tree

client/implementation/src/main/java/io/smallrye/graphql/client/dynamic/ResponseImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public ResponseImpl(JsonObject data, List<Error> errors) {
2323

2424
public <T> T getObject(Class<T> dataType, String rootField) {
2525
JsonObject jsonObject = data.getJsonObject(rootField);
26-
return (T) JsonReader.readJson(rootField, TypeInfo.of(dataType), jsonObject);
26+
return (T) JsonReader.readJson(rootField, TypeInfo.of(dataType), jsonObject, null);
2727
}
2828

2929
public <T> List<T> getList(Class<T> dataType, String rootField) {
@@ -38,7 +38,7 @@ public <T> List<T> getList(Class<T> dataType, String rootField) {
3838

3939
JsonArray jsonArray = (JsonArray) item;
4040
TypeInfo type = TypeInfo.of(dataType);
41-
jsonArray.forEach(o -> result.add((T) JsonReader.readJson(rootField, type, o)));
41+
jsonArray.forEach(o -> result.add((T) JsonReader.readJson(rootField, type, o, null)));
4242

4343
return result;
4444
}

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/ResultBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public Object read() {
4242
if (data == null)
4343
return null;
4444
JsonValue value = method.isSingle() ? data.get(method.getName()) : data;
45-
return JsonReader.readJson(method.toString(), method.getReturnType(), value);
45+
return JsonReader.readJson(method.toString(), method.getReturnType(), value, null);
4646
}
4747

4848
private JsonObject readData() {

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonArrayReader.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616
import javax.json.JsonValue.ValueType;
1717

1818
import io.smallrye.graphql.client.typesafe.api.GraphQLClientException;
19+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
1920
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
2021

2122
class JsonArrayReader extends Reader<JsonArray> {
2223

2324
private Class<?> collectionType;
2425
private TypeInfo itemType;
2526

26-
JsonArrayReader(TypeInfo type, Location location, JsonArray value) {
27-
super(type, location, value);
27+
JsonArrayReader(TypeInfo type, Location location, JsonArray value, FieldInfo field) {
28+
super(type, location, value, field);
2829
}
2930

3031
@Override
@@ -39,7 +40,7 @@ private Object readItem(IndexedLocationBuilder locationBuilder, JsonValue itemVa
3940
TypeInfo itemType = getItemType();
4041
if (itemValue.getValueType() == ValueType.NULL && itemType.isNonNull())
4142
throw new GraphQLClientException("invalid null " + itemLocation);
42-
return readJson(itemLocation, itemType, itemValue);
43+
return readJson(itemLocation, itemType, itemValue, field);
4344
}
4445

4546
private Collector<Object, ?, ?> collector() {

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonBooleanReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66

77
import javax.json.JsonValue;
88

9+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
910
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
1011

1112
class JsonBooleanReader extends Reader<JsonValue> {
12-
JsonBooleanReader(TypeInfo type, Location location, JsonValue value) {
13-
super(type, location, value);
13+
JsonBooleanReader(TypeInfo type, Location location, JsonValue value, FieldInfo field) {
14+
super(type, location, value, field);
1415
}
1516

1617
@Override

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonNullReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
import javax.json.JsonValue;
66

7+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
78
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
89

910
class JsonNullReader extends Reader<JsonValue> {
10-
JsonNullReader(TypeInfo type, Location location, JsonValue value) {
11-
super(type, location, value);
11+
JsonNullReader(TypeInfo type, Location location, JsonValue value, FieldInfo field) {
12+
super(type, location, value, field);
1213
}
1314

1415
@Override

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonNumberReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
import javax.json.JsonNumber;
99

10+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
1011
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
1112

1213
class JsonNumberReader extends Reader<JsonNumber> {
13-
JsonNumberReader(TypeInfo type, Location location, JsonNumber value) {
14-
super(type, location, value);
14+
JsonNumberReader(TypeInfo type, Location location, JsonNumber value, FieldInfo field) {
15+
super(type, location, value, field);
1516
}
1617

1718
@Override

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonObjectReader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
1515

1616
class JsonObjectReader extends Reader<JsonObject> {
17-
JsonObjectReader(TypeInfo type, Location location, JsonObject value) {
18-
super(type, location, value);
17+
JsonObjectReader(TypeInfo type, Location location, JsonObject value, FieldInfo field) {
18+
super(type, location, value, field);
1919
}
2020

2121
@Override
@@ -52,6 +52,6 @@ private Object buildValue(Location location, JsonObject value, FieldInfo field)
5252
throw new GraphQLClientException("missing " + fieldLocation);
5353
return null;
5454
}
55-
return readJson(fieldLocation, field.getType(), jsonFieldValue);
55+
return readJson(fieldLocation, field.getType(), jsonFieldValue, field);
5656
}
5757
}

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonReader.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,26 @@
1515
import io.smallrye.graphql.client.typesafe.api.ErrorOr;
1616
import io.smallrye.graphql.client.typesafe.api.GraphQLClientError;
1717
import io.smallrye.graphql.client.typesafe.api.GraphQLClientException;
18+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
1819
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
1920

2021
public class JsonReader extends Reader<JsonValue> {
21-
public static Object readJson(String description, TypeInfo type, JsonValue value) {
22-
return readJson(new Location(type, description), type, value);
22+
public static Object readJson(String description, TypeInfo type, JsonValue value, FieldInfo field) {
23+
return readJson(new Location(type, description), type, value, field);
2324
}
2425

25-
static Object readJson(Location location, TypeInfo type, JsonValue value) {
26-
return new JsonReader(type, location, value).read();
26+
static Object readJson(Location location, TypeInfo type, JsonValue value, FieldInfo field) {
27+
return new JsonReader(type, location, value, field).read();
2728
}
2829

29-
private JsonReader(TypeInfo type, Location location, JsonValue value) {
30-
super(type, location, value);
30+
private JsonReader(TypeInfo type, Location location, JsonValue value, FieldInfo field) {
31+
super(type, location, value, field);
3132
}
3233

3334
@Override
3435
Object read() {
3536
if (type.isOptional())
36-
return Optional.ofNullable(readJson(location, type.getItemType(), value));
37+
return Optional.ofNullable(readJson(location, type.getItemType(), value, field));
3738
if (type.isErrorOr())
3839
return readErrorOr();
3940
if (isListOfErrors(value) && !isGraphQlErrorsType())
@@ -44,12 +45,12 @@ Object read() {
4445
private ErrorOr<Object> readErrorOr() {
4546
if (isListOfErrors(value))
4647
return ErrorOr.ofErrors(readGraphQlClientErrors());
47-
return ErrorOr.of(readJson(location, type.getItemType(), value));
48+
return ErrorOr.of(readJson(location, type.getItemType(), value, field));
4849
}
4950

5051
private List<GraphQLClientError> readGraphQlClientErrors() {
5152
return value.asJsonArray().stream()
52-
.map(item -> (GraphQLClientError) readJson(location, TypeInfo.of(GraphQLClientErrorImpl.class), item))
53+
.map(item -> (GraphQLClientError) readJson(location, TypeInfo.of(GraphQLClientErrorImpl.class), item, field))
5354
.collect(toList());
5455
}
5556

@@ -69,18 +70,18 @@ private GraphQLClientException cantApplyErrors(List<GraphQLClientError> errors)
6970
private Reader<?> reader(Location location) {
7071
switch (value.getValueType()) {
7172
case ARRAY:
72-
return new JsonArrayReader(type, location, (JsonArray) value);
73+
return new JsonArrayReader(type, location, (JsonArray) value, field);
7374
case OBJECT:
74-
return new JsonObjectReader(type, location, (JsonObject) value);
75+
return new JsonObjectReader(type, location, (JsonObject) value, field);
7576
case STRING:
76-
return new JsonStringReader(type, location, (JsonString) value);
77+
return new JsonStringReader(type, location, (JsonString) value, field);
7778
case NUMBER:
78-
return new JsonNumberReader(type, location, (JsonNumber) value);
79+
return new JsonNumberReader(type, location, (JsonNumber) value, field);
7980
case TRUE:
8081
case FALSE:
81-
return new JsonBooleanReader(type, location, value);
82+
return new JsonBooleanReader(type, location, value, field);
8283
case NULL:
83-
return new JsonNullReader(type, location, value);
84+
return new JsonNullReader(type, location, value, field);
8485
}
8586
throw new GraphQLClientException("unreachable code");
8687
}

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/JsonStringReader.java

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
package io.smallrye.graphql.client.typesafe.impl.json;
22

3+
import java.text.DecimalFormat;
4+
import java.text.ParseException;
5+
import java.text.SimpleDateFormat;
36
import java.time.Instant;
7+
import java.util.Date;
8+
import java.util.Locale;
49

510
import javax.json.JsonString;
11+
import javax.json.bind.annotation.JsonbDateFormat;
12+
import javax.json.bind.annotation.JsonbNumberFormat;
13+
14+
import org.eclipse.microprofile.graphql.DateFormat;
15+
import org.eclipse.microprofile.graphql.NumberFormat;
616

717
import io.smallrye.graphql.client.typesafe.api.GraphQLClientException;
818
import io.smallrye.graphql.client.typesafe.impl.reflection.ConstructionInfo;
19+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
920
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
1021

1122
class JsonStringReader extends Reader<JsonString> {
12-
JsonStringReader(TypeInfo type, Location location, JsonString value) {
13-
super(type, location, value);
23+
JsonStringReader(TypeInfo type, Location location, JsonString value, FieldInfo field) {
24+
super(type, location, value, field);
1425
}
1526

1627
@Override
@@ -25,11 +36,19 @@ Object read() {
2536
if (type.isEnum())
2637
return enumValue();
2738

28-
if (java.util.Date.class.equals(this.type.getRawType()))
29-
return java.util.Date.from(Instant.parse(value.getString()));
39+
if (java.util.Date.class.equals(this.type.getRawType())) {
40+
return formattedDate(value.getString());
41+
}
3042
if (java.util.UUID.class.equals(this.type.getRawType()))
3143
return java.util.UUID.fromString(value.getString());
3244

45+
if (Number.class.isAssignableFrom(this.type.getRawType())
46+
&& field != null &&
47+
((field.getAnnotation(NumberFormat.class) != null) ||
48+
field.getAnnotation(JsonbNumberFormat.class) != null)) {
49+
return formattedNumber(value.getString());
50+
}
51+
3352
ConstructionInfo constructor = type.scalarConstructor()
3453
.orElseThrow(() -> new GraphQLClientValueException(location, value));
3554
try {
@@ -39,6 +58,77 @@ Object read() {
3958
}
4059
}
4160

61+
/**
62+
* Parse the date taking into account potential date-formatting annotations
63+
*/
64+
private Date formattedDate(String value) {
65+
if (field != null) {
66+
String format = null;
67+
String locale = null;
68+
69+
JsonbDateFormat jsonbDateFormat = field.getAnnotation(JsonbDateFormat.class);
70+
if (jsonbDateFormat != null) {
71+
format = jsonbDateFormat.value();
72+
locale = jsonbDateFormat.locale();
73+
}
74+
75+
DateFormat dateFormat = field.getAnnotation(DateFormat.class);
76+
if (dateFormat != null) {
77+
format = dateFormat.value();
78+
locale = dateFormat.locale();
79+
}
80+
81+
java.text.DateFormat df;
82+
if (format != null) {
83+
if (!locale.isEmpty()) {
84+
df = new SimpleDateFormat(format, Locale.forLanguageTag(locale));
85+
} else {
86+
df = new SimpleDateFormat(format);
87+
}
88+
} else {
89+
df = new SimpleDateFormat();
90+
}
91+
try {
92+
return df.parse(value);
93+
} catch (ParseException e) {
94+
throw new GraphQLClientException("Cannot parse date", e);
95+
}
96+
} else {
97+
return java.util.Date.from(Instant.parse(value));
98+
}
99+
}
100+
101+
private Number formattedNumber(String input) {
102+
String locale = null;
103+
String format = null;
104+
105+
JsonbNumberFormat jsonbNumberFormat = field.getAnnotation(JsonbNumberFormat.class);
106+
if (jsonbNumberFormat != null) {
107+
locale = jsonbNumberFormat.locale();
108+
format = jsonbNumberFormat.value();
109+
}
110+
111+
NumberFormat numberFormat = field.getAnnotation(NumberFormat.class);
112+
if (numberFormat != null) {
113+
locale = numberFormat.locale();
114+
format = numberFormat.value();
115+
}
116+
117+
java.text.NumberFormat nf;
118+
if (format != null && !format.isEmpty()) {
119+
nf = new DecimalFormat(format);
120+
} else if (locale != null && !locale.isEmpty()) {
121+
nf = java.text.NumberFormat.getInstance(Locale.forLanguageTag(locale));
122+
} else {
123+
nf = new DecimalFormat();
124+
}
125+
try {
126+
return nf.parse(input);
127+
} catch (ParseException e) {
128+
throw new GraphQLClientException("Can't parse number", e);
129+
}
130+
}
131+
42132
@SuppressWarnings({ "rawtypes", "unchecked" })
43133
private Enum<?> enumValue() {
44134
return Enum.valueOf((Class) type.getRawType(), value.getString());

client/implementation/src/main/java/io/smallrye/graphql/client/typesafe/impl/json/Reader.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44

55
import javax.json.JsonValue;
66

7+
import io.smallrye.graphql.client.typesafe.impl.reflection.FieldInfo;
78
import io.smallrye.graphql.client.typesafe.impl.reflection.TypeInfo;
89

910
abstract class Reader<T extends JsonValue> {
1011
protected final TypeInfo type;
1112
protected final Location location;
1213
protected final T value;
14+
protected final FieldInfo field;
1315

14-
Reader(TypeInfo type, Location location, T value) {
16+
Reader(TypeInfo type, Location location, T value, FieldInfo field) {
1517
this.type = type;
1618
this.location = location;
1719
this.value = requireNonNull(value);
20+
this.field = field;
1821
}
1922

2023
abstract Object read();

0 commit comments

Comments
 (0)