Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// ------------------------------------------------------------------------------
// Copyright (c) 2017 Microsoft Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// ------------------------------------------------------------------------------

package com.microsoft.graph.serializer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.common.reflect.TypeToken;
import com.microsoft.graph.http.BaseCollectionPage;
import com.microsoft.graph.http.IRequestBuilder;
import com.microsoft.graph.logger.ILogger;

// keep these imports: even though they are not used, it's a good way to call
// for maintainer's attention en the event code generation naming conventions
// change. If the name change, these import will build at build time rather than
// reflection building at run time.
import com.microsoft.graph.models.extensions.Attachment;
import com.microsoft.graph.requests.extensions.AttachmentCollectionPage;
import com.microsoft.graph.requests.extensions.AttachmentCollectionResponse;
import com.microsoft.graph.requests.extensions.IAttachmentCollectionRequestBuilder;

public class CollectionPageSerializer {

private static DefaultSerializer serializer;
/** length of the word "page" */
private final static Integer pageLength = 4;
/** length of the word "collection" */
private final static Integer collectionLength = 10;
/** length of the work "response" */
private final static Integer responseLength = 8;
/** the extensions segment in the package name of target classes */
private final static String extensionsPath = "extensions.";

/**
* Not available for instantiation
*/
private CollectionPageSerializer() {
}

/**
* Serializes an CollectionPage
*
* @param src the CollectionPage variable for serialization
* @param logger the logger
* @return JsonElement of CollectionPage
*/
public static <T1, T2 extends IRequestBuilder> JsonElement serialize(final BaseCollectionPage<T1, T2> src, final ILogger logger) {
if(src == null) {
return null;
}
JsonArray jsonArray = new JsonArray();
List<T1> items = src.getCurrentPage();
serializer = new DefaultSerializer(logger);
for(T1 item : items) {
final String json = serializer.serializeObject(item);
final JsonElement element = JsonParser.parseString(json);
if(element != null && element.isJsonObject()) {
final JsonObject jsonObject = element.getAsJsonObject();
jsonArray.add(jsonObject);
}
}
return jsonArray;
}

/**
* Deserializes the JsonElement
*
* @param json the source CollectionPage's Json
* @param typeOfT The type of the CollectionPage to deserialize to
* @param logger the logger
* @throws JsonParseException the parse exception
* @return the deserialized CollectionPage
*/
@SuppressWarnings("unchecked")
public static <T1, T2 extends IRequestBuilder> BaseCollectionPage<T1, T2> deserialize(final JsonElement json, Type typeOfT, final ILogger logger) throws JsonParseException {
if (json == null) {
return null;
}
serializer = new DefaultSerializer(logger);
final JsonObject[] sourceArray = serializer.deserializeObject(json.toString(), JsonObject[].class);
final ArrayList<T1> list = new ArrayList<T1>(sourceArray.length);
/** eg: com.microsoft.graph.requests.extensions.AttachmentCollectionPage */
final String collectionPageClassCanonicalName = typeOfT.getTypeName();
/** eg: com.microsoft.graph.models.extensions.Attachment */
final String baseEntityClassCanonicalName = collectionPageClassCanonicalName
.substring(0, collectionPageClassCanonicalName.length() - pageLength - collectionLength)
.replace("requests", "models");
try {
final Class<?> baseEntityClass = Class.forName(baseEntityClassCanonicalName);
for (JsonObject sourceObject : sourceArray) {
Class<?> entityClass = serializer.getDerivedClass(sourceObject, baseEntityClass);
if(entityClass == null)
entityClass = baseEntityClass;
final T1 targetObject = (T1)serializer.deserializeObject(sourceObject.toString(), entityClass);
((IJsonBackedObject)targetObject).setRawObject(serializer, sourceObject);
list.add(targetObject);
}
/** eg: com.microsoft.graph.requests.extensions.AttachmentCollectionResponse */
final String responseClassCanonicalName = collectionPageClassCanonicalName
.substring(0, collectionPageClassCanonicalName.length() - pageLength) + "Response";
final Class<?> responseClass = Class.forName(responseClassCanonicalName);
final Object response = responseClass.getConstructor().newInstance();
responseClass.getField("value").set(response, list);
final Class<?> collectionPageClass = Class.forName(collectionPageClassCanonicalName);
/** eg: com.microsoft.graph.requests.extensions.IAttachmentCollectionRequestBuilder */
final String responseBuilderInterfaceCanonicalName = responseClassCanonicalName
.substring(0, responseClassCanonicalName.length() - responseLength)
.replace(extensionsPath, extensionsPath + "I") + "RequestBuilder";
final Class<?> responseBuilderInterfaceClass = Class.forName(responseBuilderInterfaceCanonicalName);
return (BaseCollectionPage<T1, T2>)collectionPageClass.getConstructor(responseClass, responseBuilderInterfaceClass).newInstance(response, null);
} catch(ClassNotFoundException ex) {
logger.logError("Could not find class during deserialization", ex);
} catch(NoSuchMethodException | InstantiationException | InvocationTargetException ex) {
logger.logError("Could not instanciate type during deserialization", ex);
} catch(NoSuchFieldException | IllegalAccessException ex) {
logger.logError("Unable to set field value during deserialization", ex);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,18 @@ private void addAdditionalDataToJson(AdditionalDataManager additionalDataManager
* @param parentClass the parent class the derived class should inherit from
* @return the derived class if found, or null if not applicable
*/
private Class<?> getDerivedClass(JsonObject jsonObject, Class<?> parentClass) {
//Identify the odata.type information if provided
if (jsonObject.get("@odata.type") != null) {
String odataType = jsonObject.get("@odata.type").getAsString();
String derivedType = odataType.substring(odataType.lastIndexOf('.') + 1); //Remove microsoft.graph prefix
derivedType = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, derivedType);
derivedType = "com.microsoft.graph.models.extensions." + derivedType; //Add full package path

private final static String ODATA_TYPE_KEY = "@odata.type";
public Class<?> getDerivedClass(JsonObject jsonObject, Class<?> parentClass) {
//Identify the odata.type information if provided
if (jsonObject.get(ODATA_TYPE_KEY) != null) {
/** #microsoft.graph.user or #microsoft.graph.callrecords.callrecord */
final String odataType = jsonObject.get(ODATA_TYPE_KEY).getAsString();
final Integer lastDotIndex = odataType.lastIndexOf(".");
final String derivedType = (odataType.substring(0, lastDotIndex) +
".models.extensions." +
CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL,
odataType.substring(lastDotIndex + 1)))
.replace("#", "com.");
try {
Class<?> derivedClass = Class.forName(derivedType);
//Check that the derived class inherits from the given parent class
Expand Down
18 changes: 9 additions & 9 deletions src/main/java/com/microsoft/graph/serializer/GsonFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.microsoft.graph.http.BaseCollectionPage;
import com.microsoft.graph.logger.ILogger;
import com.microsoft.graph.models.extensions.DateOnly;
import com.microsoft.graph.requests.extensions.AttachmentCollectionPage;

import com.microsoft.graph.models.extensions.TimeOfDay;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -212,21 +212,21 @@ public Duration deserialize(final JsonElement json,
}
};

final JsonSerializer<AttachmentCollectionPage> attachmentCollectionPageSerializer = new JsonSerializer<AttachmentCollectionPage>() {
final JsonSerializer<BaseCollectionPage<?,?>> collectionPageSerializer = new JsonSerializer<BaseCollectionPage<?,?>>() {
@Override
public JsonElement serialize(final AttachmentCollectionPage src,
public JsonElement serialize(final BaseCollectionPage<?,?> src,
final Type typeOfSrc,
final JsonSerializationContext context) {
return AttachmentCollectionPageSerializer.serialize(src, logger);
return CollectionPageSerializer.serialize(src, logger);
}
};

final JsonDeserializer<AttachmentCollectionPage> attachmentCollectionPageDeserializer = new JsonDeserializer<AttachmentCollectionPage>() {
final JsonDeserializer<BaseCollectionPage<?,?>> collectionPageDeserializer = new JsonDeserializer<BaseCollectionPage<?,?>>() {
@Override
public AttachmentCollectionPage deserialize(final JsonElement json,
public BaseCollectionPage<?,?> deserialize(final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
return AttachmentCollectionPageSerializer.deserialize(json, logger);
return CollectionPageSerializer.deserialize(json, typeOfT, logger);
}
};

Expand Down Expand Up @@ -257,8 +257,8 @@ public TimeOfDay deserialize(final JsonElement json,
.registerTypeAdapter(EnumSet.class, enumSetJsonDeserializer)
.registerTypeAdapter(Duration.class, durationJsonSerializer)
.registerTypeAdapter(Duration.class, durationJsonDeserializer)
.registerTypeAdapter(AttachmentCollectionPage.class, attachmentCollectionPageSerializer)
.registerTypeAdapter(AttachmentCollectionPage.class, attachmentCollectionPageDeserializer)
.registerTypeHierarchyAdapter(BaseCollectionPage.class, collectionPageSerializer)
.registerTypeHierarchyAdapter(BaseCollectionPage.class, collectionPageDeserializer)
.registerTypeAdapter(TimeOfDay.class, timeOfDayJsonDeserializer)
.registerTypeAdapterFactory(new FallbackTypeAdapterFactory(logger))
.create();
Expand Down
Loading