Skip to content

Commit cde5553

Browse files
committed
- fixes a bug where the serializer would only look at first level properties for additional data
1 parent 739b59e commit cde5553

File tree

3 files changed

+65
-54
lines changed

3 files changed

+65
-54
lines changed

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

Lines changed: 19 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -223,65 +223,29 @@ else if (fieldObject instanceof IJsonBackedObject) {
223223
public <T> String serializeObject(@Nonnull final T serializableObject) {
224224
Objects.requireNonNull(serializableObject, "parameter serializableObject cannot be null");
225225
logger.logDebug("Serializing type " + serializableObject.getClass().getSimpleName());
226-
JsonElement outJsonTree = gson.toJsonTree(serializableObject);
227-
228-
if (serializableObject instanceof IJsonBackedObject) {
229-
outJsonTree = getDataFromAdditionalDataManager(outJsonTree, serializableObject);
230-
} else if (outJsonTree.isJsonObject()) {
231-
final Field[] fields = serializableObject.getClass().getDeclaredFields();
232-
JsonObject outJson = outJsonTree.getAsJsonObject();
233-
for(Field field : fields) {
234-
if(outJson.has(field.getName())) {
235-
final Type[] interfaces = field.getType().getGenericInterfaces();
236-
for(Type interfaceType : interfaces) {
237-
if(interfaceType == IJsonBackedObject.class && outJson.get(field.getName()).isJsonObject()) {
238-
try {
239-
final JsonElement outdatedValue = outJson.remove(field.getName());
240-
outJson.add(field.getName(), getDataFromAdditionalDataManager(outdatedValue.getAsJsonObject(), field.get(serializableObject)));
241-
} catch (IllegalAccessException ex ) {
242-
logger.logDebug("Couldn't access prop" + field.getName());
243-
}
244-
break;
245-
}
246-
}
247-
}
248-
}
249-
}
250-
251-
return outJsonTree.toString();
252-
}
253-
private <T> JsonElement getDataFromAdditionalDataManager(JsonElement outJsonTree, final T serializableObject) {
254-
final IJsonBackedObject serializableJsonObject = (IJsonBackedObject) serializableObject;
255-
final AdditionalDataManager additionalData = serializableJsonObject.additionalDataManager();
256-
257-
// If the item is a valid Graph object, add its additional data
258-
if (outJsonTree.isJsonObject()) {
259-
final JsonObject outJson = outJsonTree.getAsJsonObject();
260-
261-
addAdditionalDataFromManagerToJson(additionalData, outJson);
262-
getChildAdditionalData(serializableJsonObject, outJson);
263-
264-
return outJson;
265-
} else {
266-
return outJsonTree;
226+
final JsonElement outJsonTree = gson.toJsonTree(serializableObject);
227+
if(outJsonTree != null) {
228+
getChildAdditionalData(serializableObject, outJsonTree);
229+
return outJsonTree.toString();
267230
}
231+
return "";
268232
}
269-
270233
/**
271234
* Recursively populates additional data for each child object
272235
*
273236
* @param serializableObject the child to get additional data for
274237
* @param outJson the serialized output JSON to add to
275238
*/
276239
@SuppressWarnings("unchecked")
277-
private void getChildAdditionalData(final IJsonBackedObject serializableObject, final JsonObject outJson) {
278-
if(outJson == null)
240+
private void getChildAdditionalData(final Object serializableObject, final JsonElement outJson) {
241+
if(outJson == null || serializableObject == null || !outJson.isJsonObject())
279242
return;
243+
final JsonObject outJsonObject = outJson.getAsJsonObject();
280244
// Use reflection to iterate through fields for eligible Graph children
281245
for (java.lang.reflect.Field field : serializableObject.getClass().getFields()) {
282246
try {
283247
final Object fieldObject = field.get(serializableObject);
284-
final JsonElement fieldJsonElement = outJson.get(field.getName());
248+
final JsonElement fieldJsonElement = outJsonObject.get(field.getName());
285249
if(fieldObject == null || fieldJsonElement == null)
286250
continue;
287251

@@ -296,7 +260,7 @@ private void getChildAdditionalData(final IJsonBackedObject serializableObject,
296260
final Object child = pair.getValue();
297261
final JsonElement childJsonElement = fieldJsonObject.get(pair.getKey().toString());
298262
// If the item is a valid Graph object, add its additional data
299-
addAdditionalDataFromJsonElementToJson(child, childJsonElement);
263+
getChildAdditionalData(child, childJsonElement);
300264
}
301265
}
302266
// If the object is a list of Graph objects, iterate through elements
@@ -306,11 +270,13 @@ else if (fieldObject instanceof List && fieldJsonElement.isJsonArray()) {
306270
for (int index = 0; index < fieldObjectList.size(); index++) {
307271
final Object item = fieldObjectList.get(index);
308272
final JsonElement itemJsonElement = fieldArrayValue.get(index);
309-
addAdditionalDataFromJsonElementToJson(item, itemJsonElement);
273+
getChildAdditionalData(item, itemJsonElement);
310274
}
311-
}
312-
// If the object is a valid Graph object, add its additional data
313-
addAdditionalDataFromJsonElementToJson(fieldObject, fieldJsonElement);
275+
} else if(fieldJsonElement.isJsonObject()) {
276+
// If the object is a valid Graph object, add its additional data
277+
final JsonObject fieldJsonObject = fieldJsonElement.getAsJsonObject();
278+
addAdditionalDataFromJsonElementToJson(fieldObject, fieldJsonObject);
279+
}
314280
} catch (IllegalArgumentException | IllegalAccessException e) {
315281
logger.logError("Unable to access child fields of " + serializableObject.getClass().getSimpleName(), e);
316282
}
@@ -321,11 +287,10 @@ else if (fieldObject instanceof List && fieldJsonElement.isJsonArray()) {
321287
* Add each non-transient additional data property to the given JSON node
322288
*
323289
* @param item the object containing additional data
324-
* @param itemJsonElement the JSON node to add the additional data properties to
290+
* @param itemJsonObject the JSON node to add the additional data properties to
325291
*/
326-
private void addAdditionalDataFromJsonElementToJson (final Object item, final JsonElement itemJsonElement) {
327-
if (item instanceof IJsonBackedObject && itemJsonElement.isJsonObject()) {
328-
final JsonObject itemJsonObject = itemJsonElement.getAsJsonObject();
292+
private void addAdditionalDataFromJsonElementToJson (final Object item, final JsonObject itemJsonObject) {
293+
if (item instanceof IJsonBackedObject && itemJsonObject != null) {
329294
final IJsonBackedObject serializableItem = (IJsonBackedObject) item;
330295
final AdditionalDataManager itemAdditionalData = serializableItem.additionalDataManager();
331296
addAdditionalDataFromManagerToJson(itemAdditionalData, itemJsonObject);

src/test/java/com/microsoft/graph/content/BatchRequestContentTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static org.junit.jupiter.api.Assertions.assertNotNull;
55
import static org.junit.jupiter.api.Assertions.assertNull;
66
import static org.junit.jupiter.api.Assertions.assertThrows;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
78
import static org.mockito.ArgumentMatchers.any;
89
import static org.mockito.Mockito.mock;
910
import static org.mockito.Mockito.when;
@@ -14,6 +15,7 @@
1415
import java.util.ArrayList;
1516

1617
import com.google.gson.JsonObject;
18+
import com.google.gson.JsonPrimitive;
1719
import com.microsoft.graph.authentication.IAuthenticationProvider;
1820
import com.microsoft.graph.core.BaseClient;
1921
import com.microsoft.graph.core.IBaseClient;
@@ -235,4 +237,18 @@ public AdditionalDataManager additionalDataManager() {
235237
assertNotNull(step4.headers);
236238
assertEquals("application/octet-stream", step4.headers.get("content-type"));
237239
}
240+
@Test
241+
public void serializesAdditionalData() throws MalformedURLException {
242+
IHttpRequest requestStep = mock(IHttpRequest.class);
243+
when(requestStep.getRequestUrl()).thenReturn(new URL(testurl));
244+
final BatchRequestContent batchRequest = new BatchRequestContent();
245+
final String bindValue = "https://somebindvalue";
246+
final BatchRequestTestBody body = new BatchRequestTestBody(); // using a dynamic implementation doesn't work as "this" maps to the current test class
247+
body.additionalDataManager().put("teamsApp@odata.bind", new JsonPrimitive(bindValue));
248+
batchRequest.addBatchRequestStep(requestStep, HttpMethod.POST, body);
249+
final ISerializer serializer = new DefaultSerializer(mock(ILogger.class));
250+
final String result = serializer.serializeObject(batchRequest);
251+
assertNotNull(result);
252+
assertTrue(result.contains(bindValue));
253+
}
238254
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.microsoft.graph.content;
2+
3+
import javax.annotation.Nullable;
4+
5+
import com.google.gson.JsonObject;
6+
import com.google.gson.annotations.Expose;
7+
import com.google.gson.annotations.SerializedName;
8+
import com.microsoft.graph.serializer.AdditionalDataManager;
9+
import com.microsoft.graph.serializer.IJsonBackedObject;
10+
import com.microsoft.graph.serializer.ISerializer;
11+
12+
public class BatchRequestTestBody implements IJsonBackedObject {
13+
@Expose
14+
@Nullable
15+
@SerializedName("id")
16+
public String id;
17+
18+
@Override
19+
public void setRawObject(ISerializer serializer, JsonObject json) {
20+
// TODO Auto-generated method stub
21+
22+
}
23+
final AdditionalDataManager manager = new AdditionalDataManager(this);
24+
25+
@Override
26+
public AdditionalDataManager additionalDataManager() {
27+
return manager;
28+
}
29+
30+
}

0 commit comments

Comments
 (0)