Skip to content

Commit 3f4486e

Browse files
authored
Merge pull request #693 from microsoftgraph/bugfix/default-content-type-and-boolean-deserialization
bugfix/default content type and boolean deserialization
2 parents 0b995b0 + 38b99aa commit 3f4486e

File tree

6 files changed

+228
-17
lines changed

6 files changed

+228
-17
lines changed

src/main/java/com/microsoft/graph/http/CoreHttpProvider.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public <Result, Body> Request getHttpRequest(final IHttpRequest request,
243243
if(this.connectionConfig == null) {
244244
this.connectionConfig = new DefaultConnectionConfig();
245245
}
246-
246+
247247
// Request level middleware options
248248
RedirectOptions redirectOptions = new RedirectOptions(request.getMaxRedirects() > 0? request.getMaxRedirects() : this.connectionConfig.getMaxRedirects(),
249249
request.getShouldRedirect() != null? request.getShouldRedirect() : this.connectionConfig.getShouldRedirect());
@@ -256,7 +256,7 @@ public <Result, Body> Request getHttpRequest(final IHttpRequest request,
256256
.newBuilder()
257257
.tag(RedirectOptions.class, redirectOptions)
258258
.tag(RetryOptions.class, retryOptions);
259-
259+
260260
String contenttype = null;
261261

262262
logger.logDebug("Request Method " + request.getHttpMethod().toString());
@@ -276,11 +276,7 @@ public <Result, Body> Request getHttpRequest(final IHttpRequest request,
276276
// This ensures that the Content-Length header is properly set
277277
if (request.getHttpMethod() == HttpMethod.POST) {
278278
bytesToWrite = new byte[0];
279-
if(contenttype == null) {
280-
contenttype = Constants.BINARY_CONTENT_TYPE;
281-
}
282-
}
283-
else {
279+
} else {
284280
bytesToWrite = null;
285281
}
286282
} else if (serializable instanceof byte[]) {
@@ -341,7 +337,11 @@ public void writeTo(BufferedSink sink) throws IOException {
341337

342338
@Override
343339
public MediaType contentType() {
344-
return MediaType.parse(mediaContentType);
340+
if(mediaContentType == null || mediaContentType.isEmpty()) {
341+
return null;
342+
} else {
343+
return MediaType.parse(mediaContentType);
344+
}
345345
}
346346
};
347347
}
@@ -401,7 +401,7 @@ public Request authenticateRequest(Request request) {
401401
try {
402402

403403
// Call being executed
404-
404+
405405

406406
if (handler != null) {
407407
handler.configConnection(response);
@@ -425,7 +425,7 @@ public Request authenticateRequest(Request request) {
425425

426426
if (response.code() == HttpResponseCode.HTTP_NOBODY
427427
|| response.code() == HttpResponseCode.HTTP_NOT_MODIFIED) {
428-
logger.logDebug("Handling response with no body");
428+
logger.logDebug("Handling response with no body");
429429
return handleEmptyResponse(responseHeadersHelper.getResponseHeadersAsMapOfStringList(response), resultClass);
430430
}
431431

@@ -442,7 +442,7 @@ public Request authenticateRequest(Request request) {
442442
return (Result) null;
443443

444444
final String contentType = headers.get(Constants.CONTENT_TYPE_HEADER_NAME);
445-
if (contentType != null && resultClass != InputStream.class &&
445+
if (contentType != null && resultClass != InputStream.class &&
446446
contentType.contains(Constants.JSON_CONTENT_TYPE)) {
447447
logger.logDebug("Response json");
448448
return handleJsonResponse(in, responseHeadersHelper.getResponseHeadersAsMapOfStringList(response), resultClass);
@@ -534,12 +534,12 @@ private <Result> Result handleJsonResponse(final InputStream in, Map<String, Lis
534534

535535
/**
536536
* Handles the case where the response body is empty
537-
*
537+
*
538538
* @param responseHeaders the response headers
539539
* @param clazz the type of the response object
540540
* @return the JSON object
541541
*/
542-
private <Result> Result handleEmptyResponse(Map<String, List<String>> responseHeaders, final Class<Result> clazz)
542+
private <Result> Result handleEmptyResponse(Map<String, List<String>> responseHeaders, final Class<Result> clazz)
543543
throws UnsupportedEncodingException{
544544
//Create an empty object to attach the response headers to
545545
InputStream in = new ByteArrayInputStream("{}".getBytes(Constants.JSON_ENCODING));
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
public class EdmNativeTypeSerializer {
12+
public static <T> T deserialize(final JsonElement json, final Class<T> type, final ILogger logger) throws JsonParseException {
13+
if (json == null || type == null) {
14+
return null;
15+
} else if(json.isJsonPrimitive()) {
16+
return getPrimitiveValue(json, type);
17+
} else if(json.isJsonObject()) {
18+
final JsonElement element = json.getAsJsonObject().get("@odata.null");
19+
if(element != null && element.isJsonPrimitive()) {
20+
return getPrimitiveValue(element, type);
21+
} else {
22+
return null;
23+
}
24+
}
25+
return null;
26+
}
27+
@SuppressWarnings("unchecked")
28+
private static <T> T getPrimitiveValue(final JsonElement json, final Class<T> type) {
29+
if(type == Boolean.class) {
30+
return (T) Boolean.valueOf(json.getAsBoolean());
31+
} else if(type == String.class) {
32+
return (T)json.getAsString();
33+
} else if(type == Integer.class) {
34+
return (T) Integer.valueOf(json.getAsInt());
35+
} else if(type == UUID.class) {
36+
return (T) UUID.fromString(json.getAsString());
37+
} else if(type == Long.class) {
38+
return (T) Long.valueOf(json.getAsLong());
39+
} else if (type == Float.class) {
40+
return (T) Float.valueOf(json.getAsFloat());
41+
} else if (type == BigDecimal.class) {
42+
return (T) json.getAsBigDecimal();
43+
} else {
44+
return null;
45+
}
46+
}
47+
}

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737

3838
import com.microsoft.graph.models.extensions.TimeOfDay;
3939
import java.lang.reflect.Type;
40+
import java.math.BigDecimal;
4041
import java.text.ParseException;
4142
import java.util.Calendar;
4243
import java.util.EnumSet;
4344
import java.util.GregorianCalendar;
45+
import java.util.UUID;
4446

4547
import javax.xml.datatype.DatatypeFactory;
4648
import javax.xml.datatype.Duration;
@@ -244,8 +246,78 @@ public TimeOfDay deserialize(final JsonElement json,
244246
}
245247
};
246248

249+
final JsonDeserializer<Boolean> booleanJsonDeserializer = new JsonDeserializer<Boolean>() {
250+
@Override
251+
public Boolean deserialize(final JsonElement json,
252+
final Type typeOfT,
253+
final JsonDeserializationContext context) throws JsonParseException {
254+
return EdmNativeTypeSerializer.deserialize(json, Boolean.class, logger);
255+
}
256+
};
257+
258+
final JsonDeserializer<String> stringJsonDeserializer = new JsonDeserializer<String>() {
259+
@Override
260+
public String deserialize(final JsonElement json,
261+
final Type typeOfT,
262+
final JsonDeserializationContext context) throws JsonParseException {
263+
return EdmNativeTypeSerializer.deserialize(json, String.class, logger);
264+
}
265+
};
266+
267+
final JsonDeserializer<BigDecimal> bigDecimalJsonDeserializer = new JsonDeserializer<BigDecimal>() {
268+
@Override
269+
public BigDecimal deserialize(final JsonElement json,
270+
final Type typeOfT,
271+
final JsonDeserializationContext context) throws JsonParseException {
272+
return EdmNativeTypeSerializer.deserialize(json, BigDecimal.class, logger);
273+
}
274+
};
275+
276+
final JsonDeserializer<Integer> integerJsonDeserializer = new JsonDeserializer<Integer>() {
277+
@Override
278+
public Integer deserialize(final JsonElement json,
279+
final Type typeOfT,
280+
final JsonDeserializationContext context) throws JsonParseException {
281+
return EdmNativeTypeSerializer.deserialize(json, Integer.class, logger);
282+
}
283+
};
284+
285+
final JsonDeserializer<Long> longJsonDeserializer = new JsonDeserializer<Long>() {
286+
@Override
287+
public Long deserialize(final JsonElement json,
288+
final Type typeOfT,
289+
final JsonDeserializationContext context) throws JsonParseException {
290+
return EdmNativeTypeSerializer.deserialize(json, Long.class, logger);
291+
}
292+
};
293+
294+
final JsonDeserializer<UUID> uuidJsonDeserializer = new JsonDeserializer<UUID>() {
295+
@Override
296+
public UUID deserialize(final JsonElement json,
297+
final Type typeOfT,
298+
final JsonDeserializationContext context) throws JsonParseException {
299+
return EdmNativeTypeSerializer.deserialize(json, UUID.class, logger);
300+
}
301+
};
302+
303+
final JsonDeserializer<Float> floatJsonDeserializer = new JsonDeserializer<Float>() {
304+
@Override
305+
public Float deserialize(final JsonElement json,
306+
final Type typeOfT,
307+
final JsonDeserializationContext context) throws JsonParseException {
308+
return EdmNativeTypeSerializer.deserialize(json, Float.class, logger);
309+
}
310+
};
311+
247312
return new GsonBuilder()
248313
.excludeFieldsWithoutExposeAnnotation()
314+
.registerTypeAdapter(Boolean.class, booleanJsonDeserializer)
315+
.registerTypeAdapter(String.class, stringJsonDeserializer)
316+
.registerTypeAdapter(Float.class, floatJsonDeserializer)
317+
.registerTypeAdapter(Integer.class, integerJsonDeserializer)
318+
.registerTypeAdapter(BigDecimal.class, bigDecimalJsonDeserializer)
319+
.registerTypeAdapter(UUID.class, uuidJsonDeserializer)
320+
.registerTypeAdapter(Long.class, longJsonDeserializer)
249321
.registerTypeAdapter(Calendar.class, calendarJsonSerializer)
250322
.registerTypeAdapter(Calendar.class, calendarJsonDeserializer)
251323
.registerTypeAdapter(GregorianCalendar.class, calendarJsonSerializer)

src/test/java/com/microsoft/graph/functional/UserTests.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.junit.Assert.assertNotEquals;
44
import static org.junit.Assert.assertEquals;
55
import static org.junit.Assert.assertNotNull;
6+
import static org.junit.Assert.assertNull;
67

78
import java.io.File;
89
import java.io.FileInputStream;
@@ -160,7 +161,7 @@ public void meInsightsUsed() {
160161
IUsedInsightCollectionPage usedInsightCollectionPage = graphServiceClient.me().insights().used().buildRequest().get();
161162
assertNotNull(usedInsightCollectionPage);
162163
}
163-
164+
164165
@Test
165166
public void mailFoldertest() {
166167
//GET me/mailFolders
@@ -172,7 +173,7 @@ public void mailFoldertest() {
172173
assertNotNull(messageCollectionPage);
173174
}
174175
}
175-
176+
176177
@Test
177178
public void meMemberof() {
178179
IDirectoryObjectCollectionWithReferencesPage page = graphServiceClient.me().memberOf().buildRequest().get();
@@ -201,7 +202,7 @@ public void run() {
201202
}
202203

203204
@Test
204-
public void emptyPostContentType() {
205+
public void emptyPostContentTypeIsNotReset() {
205206
final String contentTypeValue = "application/json";
206207
final HeaderOption ctype = new HeaderOption("Content-Type", contentTypeValue);
207208
final ArrayList<Option> options = new ArrayList<>();
@@ -211,7 +212,16 @@ public void emptyPostContentType() {
211212
.buildRequest(options)
212213
.withHttpMethod(HttpMethod.POST)
213214
.getHttpRequest();
214-
assertEquals(contentTypeValue, request.body().contentType().toString());
215+
assertEquals(contentTypeValue, request.body().contentType().toString());
216+
}
217+
@Test
218+
public void emptyPostContentTypeIsNotSet() {
219+
final Request request = graphServiceClient.me()
220+
.revokeSignInSessions()
221+
.buildRequest()
222+
.withHttpMethod(HttpMethod.POST)
223+
.getHttpRequest();
224+
assertNull(request.body().contentType());
215225
}
216226
@Test
217227
public void castTest() {
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.Assert.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.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+
}

typeSummary.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226307,6 +226307,12 @@
226307226307
method serializeObject
226308226308
return type java.lang.String
226309226309
param serializableObject : java.lang.Object
226310+
class com.microsoft.graph.serializer.EdmNativeTypeSerializer
226311+
method deserialize
226312+
return type java.lang.Object
226313+
param json : com.google.gson.JsonElement
226314+
param type : java.lang.Class
226315+
param logger : com.microsoft.graph.logger.ILogger
226310226316
class com.microsoft.graph.serializer.EnumSetSerializer
226311226317
method deserialize
226312226318
return type java.util.EnumSet

0 commit comments

Comments
 (0)