Skip to content

Commit

Permalink
- fixes a bug where enum set properties would not be serialized properly
Browse files Browse the repository at this point in the history
  • Loading branch information
baywet committed Dec 4, 2020
1 parent 664aa57 commit 7f57641
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 28 deletions.
30 changes: 18 additions & 12 deletions src/main/java/com/microsoft/graph/serializer/EnumSetSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
package com.microsoft.graph.serializer;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonPrimitive;
import com.microsoft.graph.logger.ILogger;

import java.lang.reflect.Type;
import java.util.EnumSet;
Expand All @@ -36,39 +38,43 @@
*/
public class EnumSetSerializer {

private final Gson gson;
/**
* Not available for instantiation
*/
private EnumSetSerializer() {
public EnumSetSerializer(final ILogger logger) {
gson = new GsonBuilder().registerTypeAdapterFactory(new FallbackTypeAdapterFactory(logger)).create();
}

/**
* Deserializes a comma-delimited string of enum values
*
*
* @param type the type
* @param jsonStrToDeserialize the string to deserialize
* @return EnumSet of values
*/
public static EnumSet<?> deserialize(Type type, String jsonStrToDeserialize) {
Gson gson = new Gson();
String arrayString = "[" + jsonStrToDeserialize + "]";
public EnumSet<?> deserialize(Type type, String jsonStrToDeserialize) {
final String arrayString = "[" + jsonStrToDeserialize + "]";
return jsonStrToDeserialize == null ? null : (EnumSet<?>) gson.fromJson(arrayString, type);
}

/**
* Serializes an EnumSet into a comma-delimited string
*
*
* @param src the source EnumSet
* @return a comma-delimited string of enum values
*/
public static JsonPrimitive serialize(EnumSet<?> src) {
String serializedString = "";
public JsonPrimitive serialize(EnumSet<?> src) {
final StringBuilder serializedStringBuilder = new StringBuilder();

Iterator<?> i = src.iterator();
final Iterator<?> i = src.iterator();
while (i.hasNext()) {
serializedString += i.next().toString() + ",";
final String jsonValue = gson.toJson(i.next());
serializedStringBuilder.append(jsonValue.substring(1, jsonValue.length() -1));
if(i.hasNext()) {
serializedStringBuilder.append(",");
}
}
serializedString = serializedString.substring(0, serializedString.length()-1);
return new JsonPrimitive(serializedString);
return new JsonPrimitive(serializedStringBuilder.toString());
}
}
11 changes: 6 additions & 5 deletions src/main/java/com/microsoft/graph/serializer/GsonFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
final class GsonFactory {

private static String PARSING_MESSAGE = "Parsing issue on ";

/**
* Default constructor
*/
Expand Down Expand Up @@ -163,6 +163,7 @@ public DateOnly deserialize(final JsonElement json,
}
}
};
final EnumSetSerializer eSetSerializer = new EnumSetSerializer(logger);

final JsonSerializer<EnumSet<?>> enumSetJsonSerializer = new JsonSerializer<EnumSet<?>>() {
@Override
Expand All @@ -173,7 +174,7 @@ public JsonElement serialize(final EnumSet<?> src,
return null;
}

return EnumSetSerializer.serialize(src);
return eSetSerializer.serialize(src);
}
};

Expand All @@ -186,7 +187,7 @@ public EnumSet<?> deserialize(final JsonElement json,
return null;
}

return EnumSetSerializer.deserialize(typeOfT, json.getAsString());
return eSetSerializer.deserialize(typeOfT, json.getAsString());
}
};

Expand All @@ -211,7 +212,7 @@ public Duration deserialize(final JsonElement json,
}
}
};

final JsonSerializer<BaseCollectionPage<?,?>> collectionPageSerializer = new JsonSerializer<BaseCollectionPage<?,?>>() {
@Override
public JsonElement serialize(final BaseCollectionPage<?,?> src,
Expand All @@ -229,7 +230,7 @@ public BaseCollectionPage<?,?> deserialize(final JsonElement json,
return CollectionPageSerializer.deserialize(json, typeOfT, logger);
}
};

final JsonDeserializer<TimeOfDay> timeOfDayJsonDeserializer = new JsonDeserializer<TimeOfDay>() {
@Override
public TimeOfDay deserialize(final JsonElement json,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.microsoft.graph.callrecords.models.extensions.MediaStream;
import com.microsoft.graph.functional.TestBase;
import com.microsoft.graph.http.HttpMethod;
import com.microsoft.graph.http.MockConnection;
import com.microsoft.graph.logger.DefaultLogger;
import com.microsoft.graph.models.extensions.Attachment;
Expand All @@ -17,11 +23,18 @@
import com.microsoft.graph.models.extensions.FileAttachment;
import com.microsoft.graph.models.extensions.RecurrenceRange;
import com.microsoft.graph.models.extensions.User;
import com.microsoft.graph.models.extensions.UserGetMailTipsBody;
import com.microsoft.graph.models.generated.MailTipsType;
import com.microsoft.graph.models.generated.RecurrenceRangeType;
import com.microsoft.graph.requests.extensions.DriveItemDeltaCollectionResponse;
import com.microsoft.graph.models.extensions.UploadSession;

import org.junit.Assert;
import org.junit.Test;

import okhttp3.Request;
import okio.Buffer;

public class DefaultSerializerTests {

/**
Expand Down Expand Up @@ -111,19 +124,19 @@ public void testRecurrenceRangeSerialization() throws Exception {
assertNotNull(jsonOut);
assertEquals(expected, jsonOut);
}

@Test
public void testResponseHeaders() throws Exception {
MockConnection connection = new MockConnection(null);
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
User user = serializer.deserializeObject("{\"id\":\"1\"}", User.class, connection.getResponseHeaders());

JsonElement responseHeaders = user.additionalDataManager().get("graphResponseHeaders");
assertNotNull(responseHeaders);

JsonElement responseHeader = responseHeaders.getAsJsonObject().get("header1");
assertNotNull(responseHeader);

assertEquals("value1", responseHeader.getAsJsonArray().get(0).getAsString());
}

Expand All @@ -132,25 +145,25 @@ public void testDeserializeDerivedType() throws Exception {
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
final String source = "{\"@odata.context\": \"/attachments/$entity\",\"@odata.type\": \"#microsoft.graph.fileAttachment\",\"id\": \"AAMkAGQ0MjBmNWVkLTYxZjUtNDRmYi05Y2NiLTBlYjIwNzJjNmM1NgBGAAAAAAC6ff7latYeQqu_gLrhSAIhBwCF7iGjpaOmRqVwbZc-xXzwAAAAAAEMAACF7iGjpaOmRqVwbZc-xXzwAABQStA0AAABEgAQAFbGmeisbjtLnQdp7kC_9Fk=\",\"lastModifiedDateTime\": \"2018-01-23T21:50:22Z\",\"name\": \"Test Book.xlsx\",\"contentType\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\"size\": 8457,\"isInline\": false,\"contentId\": null,\"contentLocation\": null,\"contentBytes\": \"bytedata\"}";
final Attachment result = serializer.deserializeObject(source, Attachment.class);

assert(result instanceof FileAttachment);

final FileAttachment fileAttachment = (FileAttachment) result;
assertNotNull(fileAttachment.contentBytes);
final JsonObject o = fileAttachment.getRawObject();
assertNotNull(o);
assertEquals("#microsoft.graph.fileAttachment", o. get("@odata.type").getAsString());
}

@Test
public void testSerializerCanSerializeVoidWithoutEmittingWarning() {
// Unfortunately does not assert for existence of Java 9 illegal access warnings
// which seem to written to the console without use of System.err/System.out (so cannot be captured AFAIK).
// which seem to written to the console without use of System.err/System.out (so cannot be captured AFAIK).
// @davidmoten
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
HasVoidMember t = new HasVoidMember();
String json = serializer.serializeObject(t);
// this line will emit a warning from Java 9 about illegal access to the constructor of Void
// this line will emit a warning from Java 9 about illegal access to the constructor of Void
// if gson TypeAdapterFactory is not handling Void properly
HasVoidMember t2 = serializer.deserializeObject(json, HasVoidMember.class);
assertEquals(t.x, t2.x);
Expand All @@ -173,12 +186,28 @@ public void testDurationDeserialization() {
assertNotNull(result);
assertNotNull(result.maxRoundTripTime);
}

@Test
public void testEnumActionParameterDeserialization() throws IOException {
final ArrayList<String> users = new ArrayList<String>();
users.add("michael@chambele.onmicrosoft.com");
final EnumSet<MailTipsType> mailtips = EnumSet.of(MailTipsType.MAILBOX_FULL_STATUS, MailTipsType.MAX_MESSAGE_SIZE);
final UserGetMailTipsBody body = new UserGetMailTipsBody();
body.emailAddresses = users;
body.mailTipsOptions = mailtips;
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
final String serialized = serializer.serializeObject(body);
Assert.assertTrue("result contains camelCasedValues", serialized.contains("mailboxFullStatus"));

final UserGetMailTipsBody deserialized = serializer.deserializeObject(serialized, UserGetMailTipsBody.class);

Assert.assertEquals(2, deserialized.mailTipsOptions.size());
}

public static final class HasVoidMember {
@SerializedName("x")
@Expose
int x = 1;

@SerializedName("y")
@Expose
Void y;
Expand Down

0 comments on commit 7f57641

Please sign in to comment.