Skip to content

Commit 0c6f373

Browse files
committed
- fixes a bug where native EDM return types would not be deserialized properly
1 parent 886811a commit 0c6f373

File tree

3 files changed

+208
-0
lines changed

3 files changed

+208
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.microsoft.graph.serializer;
2+
3+
import java.lang.reflect.Type;
4+
import java.math.BigDecimal;
5+
import java.util.UUID;
6+
7+
import com.google.gson.JsonElement;
8+
import com.google.gson.JsonParseException;
9+
import com.microsoft.graph.logger.ILogger;
10+
11+
import javax.annotation.Nonnull;
12+
import javax.annotation.Nullable;
13+
14+
/** Deserializer for native EDM types from the service. Used for actions and functions that return native types for example. */
15+
public class EdmNativeTypeSerializer {
16+
/**
17+
* Deserializes native EDM types from the service. Used for actions and functions that return native types for example.
18+
* @param <T> Expected return type.
19+
* @param json json to deserialize.
20+
* @param type class of the expected return type.
21+
* @param logger logger to use.
22+
* @return the deserialized type or null.
23+
*/
24+
@Nullable
25+
public static <T> T deserialize(@Nonnull final JsonElement json, @Nonnull final Class<T> type, @Nonnull final ILogger logger) {
26+
if (json == null || type == null) {
27+
return null;
28+
} else if(json.isJsonPrimitive()) {
29+
return getPrimitiveValue(json, type);
30+
} else if(json.isJsonObject()) {
31+
final JsonElement element = json.getAsJsonObject().get("@odata.null");
32+
if(element != null && element.isJsonPrimitive()) {
33+
return getPrimitiveValue(element, type);
34+
} else {
35+
return null;
36+
}
37+
}
38+
return null;
39+
}
40+
@SuppressWarnings("unchecked")
41+
private static <T> T getPrimitiveValue(final JsonElement json, final Class<T> type) {
42+
if(type == Boolean.class) {
43+
return (T) Boolean.valueOf(json.getAsBoolean());
44+
} else if(type == String.class) {
45+
return (T)json.getAsString();
46+
} else if(type == Integer.class) {
47+
return (T) Integer.valueOf(json.getAsInt());
48+
} else if(type == UUID.class) {
49+
return (T) UUID.fromString(json.getAsString());
50+
} else if(type == Long.class) {
51+
return (T) Long.valueOf(json.getAsLong());
52+
} else if (type == Float.class) {
53+
return (T) Float.valueOf(json.getAsFloat());
54+
} else if (type == BigDecimal.class) {
55+
return (T) json.getAsBigDecimal();
56+
} else {
57+
return null;
58+
}
59+
}
60+
}

src/main/java/com/microsoft/graph/serializer/GsonFactory.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@
3838

3939
import com.microsoft.graph.core.TimeOfDay;
4040
import java.lang.reflect.Type;
41+
import java.math.BigDecimal;
4142
import java.text.ParseException;
4243
import java.time.OffsetDateTime;
4344
import java.util.Arrays;
4445
import java.util.EnumSet;
4546
import java.util.GregorianCalendar;
47+
import java.util.UUID;
4648

4749
import javax.xml.datatype.DatatypeFactory;
4850
import javax.xml.datatype.Duration;
@@ -254,8 +256,78 @@ public TimeOfDay deserialize(final JsonElement json,
254256
}
255257
};
256258

259+
final JsonDeserializer<Boolean> booleanJsonDeserializer = new JsonDeserializer<Boolean>() {
260+
@Override
261+
public Boolean deserialize(final JsonElement json,
262+
final Type typeOfT,
263+
final JsonDeserializationContext context) throws JsonParseException {
264+
return EdmNativeTypeSerializer.deserialize(json, Boolean.class, logger);
265+
}
266+
};
267+
268+
final JsonDeserializer<String> stringJsonDeserializer = new JsonDeserializer<String>() {
269+
@Override
270+
public String deserialize(final JsonElement json,
271+
final Type typeOfT,
272+
final JsonDeserializationContext context) throws JsonParseException {
273+
return EdmNativeTypeSerializer.deserialize(json, String.class, logger);
274+
}
275+
};
276+
277+
final JsonDeserializer<BigDecimal> bigDecimalJsonDeserializer = new JsonDeserializer<BigDecimal>() {
278+
@Override
279+
public BigDecimal deserialize(final JsonElement json,
280+
final Type typeOfT,
281+
final JsonDeserializationContext context) throws JsonParseException {
282+
return EdmNativeTypeSerializer.deserialize(json, BigDecimal.class, logger);
283+
}
284+
};
285+
286+
final JsonDeserializer<Integer> integerJsonDeserializer = new JsonDeserializer<Integer>() {
287+
@Override
288+
public Integer deserialize(final JsonElement json,
289+
final Type typeOfT,
290+
final JsonDeserializationContext context) throws JsonParseException {
291+
return EdmNativeTypeSerializer.deserialize(json, Integer.class, logger);
292+
}
293+
};
294+
295+
final JsonDeserializer<Long> longJsonDeserializer = new JsonDeserializer<Long>() {
296+
@Override
297+
public Long deserialize(final JsonElement json,
298+
final Type typeOfT,
299+
final JsonDeserializationContext context) throws JsonParseException {
300+
return EdmNativeTypeSerializer.deserialize(json, Long.class, logger);
301+
}
302+
};
303+
304+
final JsonDeserializer<UUID> uuidJsonDeserializer = new JsonDeserializer<UUID>() {
305+
@Override
306+
public UUID deserialize(final JsonElement json,
307+
final Type typeOfT,
308+
final JsonDeserializationContext context) throws JsonParseException {
309+
return EdmNativeTypeSerializer.deserialize(json, UUID.class, logger);
310+
}
311+
};
312+
313+
final JsonDeserializer<Float> floatJsonDeserializer = new JsonDeserializer<Float>() {
314+
@Override
315+
public Float deserialize(final JsonElement json,
316+
final Type typeOfT,
317+
final JsonDeserializationContext context) throws JsonParseException {
318+
return EdmNativeTypeSerializer.deserialize(json, Float.class, logger);
319+
}
320+
};
321+
257322
return new GsonBuilder()
258323
.excludeFieldsWithoutExposeAnnotation()
324+
.registerTypeAdapter(Boolean.class, booleanJsonDeserializer)
325+
.registerTypeAdapter(String.class, stringJsonDeserializer)
326+
.registerTypeAdapter(Float.class, floatJsonDeserializer)
327+
.registerTypeAdapter(Integer.class, integerJsonDeserializer)
328+
.registerTypeAdapter(BigDecimal.class, bigDecimalJsonDeserializer)
329+
.registerTypeAdapter(UUID.class, uuidJsonDeserializer)
330+
.registerTypeAdapter(Long.class, longJsonDeserializer)
259331
.registerTypeAdapter(OffsetDateTime.class, calendarJsonSerializer)
260332
.registerTypeAdapter(OffsetDateTime.class, calendarJsonDeserializer)
261333
.registerTypeAdapter(GregorianCalendar.class, calendarJsonSerializer)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.microsoft.graph.serializer;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.math.BigDecimal;
6+
import java.util.UUID;
7+
8+
import com.microsoft.graph.logger.DefaultLogger;
9+
10+
import org.junit.jupiter.api.Test;
11+
12+
public class EdmNativeTypeSerializerTests {
13+
@Test
14+
public void testBoolean() throws Exception {
15+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
16+
17+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":true}";
18+
final Boolean result = serializer.deserializeObject(source, Boolean.class);
19+
20+
assertEquals(Boolean.valueOf(true), result);
21+
}
22+
@Test
23+
public void testInteger() throws Exception {
24+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
25+
26+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":12}";
27+
final Integer result = serializer.deserializeObject(source, Integer.class);
28+
29+
assertEquals(Integer.valueOf(12), result);
30+
}
31+
@Test
32+
public void testString() throws Exception {
33+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
34+
35+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":\"toto\"}";
36+
final String result = serializer.deserializeObject(source, String.class);
37+
38+
assertEquals("toto", result);
39+
}
40+
@Test
41+
public void testFloat() throws Exception {
42+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
43+
44+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":12.5}";
45+
final Float result = serializer.deserializeObject(source, Float.class);
46+
47+
assertEquals(Float.valueOf("12.5"), result);
48+
}
49+
@Test
50+
public void testLong() throws Exception {
51+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
52+
53+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":12}";
54+
final Long result = serializer.deserializeObject(source, Long.class);
55+
56+
assertEquals(Long.valueOf(12), result);
57+
}
58+
@Test
59+
public void testBigDecimal() throws Exception {
60+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
61+
62+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":12}";
63+
final BigDecimal result = serializer.deserializeObject(source, BigDecimal.class);
64+
65+
assertEquals(BigDecimal.valueOf(12), result);
66+
}
67+
@Test
68+
public void testUUID() throws Exception {
69+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
70+
71+
final String source = "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#Edm.Null\",\"@odata.null\":\"0E6558C3-9640-4385-860A-2A894AC5C246\"}";
72+
final UUID result = serializer.deserializeObject(source, UUID.class);
73+
74+
assertEquals(UUID.fromString("0E6558C3-9640-4385-860A-2A894AC5C246"), result);
75+
}
76+
}

0 commit comments

Comments
 (0)