Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/tjroach/prevent-loadCredential-d…
Browse files Browse the repository at this point in the history
…ouble-continuation' into tjroach/prevent-loadCredential-double-continuation
  • Loading branch information
tylerjroach committed Aug 9, 2023
2 parents be50107 + 1655027 commit dae0624
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@

package com.amplifyframework.datastore.appsync;

import com.amplifyframework.core.Amplify;
import com.amplifyframework.core.category.CategoryType;
import com.amplifyframework.core.model.CustomTypeField;
import com.amplifyframework.core.model.CustomTypeSchema;
import com.amplifyframework.core.model.SerializedCustomType;
import com.amplifyframework.logging.Logger;
import com.amplifyframework.util.GsonObjectConverter;

import com.google.gson.GsonBuilder;
Expand All @@ -40,6 +43,9 @@
*/
public final class SerializedCustomTypeAdapter
implements JsonDeserializer<SerializedCustomType>, JsonSerializer<SerializedCustomType> {
private static final Logger LOGGER = Amplify.Logging.logger(
CategoryType.DATASTORE, SerializedCustomTypeAdapter.class.getName());

private SerializedCustomTypeAdapter() {
}

Expand All @@ -54,6 +60,7 @@ public static void register(GsonBuilder builder) {

@Override
public JsonElement serialize(SerializedCustomType src, Type typeOfSrc, JsonSerializationContext context) {
LOGGER.verbose(String.format("serialize: src=%s, typeOfSrc=%s", src, typeOfSrc));
CustomTypeSchema schema = src.getCustomTypeSchema();
JsonObject result = new JsonObject();
result.add("customTypeSchema", context.serialize(schema));
Expand All @@ -77,6 +84,7 @@ public JsonElement serialize(SerializedCustomType src, Type typeOfSrc, JsonSeria
@Override
public SerializedCustomType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
LOGGER.verbose(String.format("deserialize: json=%s, typeOfT=%s", json, typeOfT));
JsonObject object = json.getAsJsonObject();
CustomTypeSchema schema = context.deserialize(
object.get("customTypeSchema"), CustomTypeSchema.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@

package com.amplifyframework.datastore.appsync;

import com.amplifyframework.core.Amplify;
import com.amplifyframework.core.category.CategoryType;
import com.amplifyframework.core.model.ModelField;
import com.amplifyframework.core.model.ModelSchema;
import com.amplifyframework.core.model.SchemaRegistry;
import com.amplifyframework.core.model.SerializedCustomType;
import com.amplifyframework.core.model.SerializedModel;
import com.amplifyframework.logging.Logger;
import com.amplifyframework.util.GsonObjectConverter;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
Expand All @@ -34,6 +38,7 @@
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -42,6 +47,9 @@
*/
public final class SerializedModelAdapter
implements JsonDeserializer<SerializedModel>, JsonSerializer<SerializedModel> {
private static final Logger LOGGER = Amplify.Logging.logger(
CategoryType.DATASTORE, SerializedModelAdapter.class.getName());

private SerializedModelAdapter() {
}

Expand All @@ -56,6 +64,7 @@ public static void register(GsonBuilder builder) {

@Override
public JsonElement serialize(SerializedModel src, Type typeOfSrc, JsonSerializationContext context) {
LOGGER.verbose(String.format("serialize: src=%s, typeOfSrc=%s", src, typeOfSrc));
ModelSchema schema = src.getModelSchema();

JsonObject result = new JsonObject();
Expand All @@ -66,23 +75,34 @@ public JsonElement serialize(SerializedModel src, Type typeOfSrc, JsonSerializat
for (Map.Entry<String, Object> entry : src.getSerializedData().entrySet()) {
String fieldName = entry.getKey();
Object fieldValue = entry.getValue();
if (fieldValue instanceof SerializedModel) {

boolean isModel = fieldValue instanceof SerializedModel;
boolean isCustomType = fieldValue instanceof SerializedCustomType;
LOGGER.verbose(String.format(
"Serializing field %s: isModel=%s, isCustom=%s",
fieldName, isModel, isCustomType));

if (isModel) {
SerializedModel serializedModel = (SerializedModel) fieldValue;
serializedData.add(fieldName, context.serialize(serializedModel.getSerializedData()));
} else if (fieldValue instanceof SerializedCustomType) {
} else if (isCustomType) {
// serialize via SerializedCustomTypeAdapter
serializedData.add(fieldName, context.serialize(fieldValue));
} else {
serializedData.add(fieldName, context.serialize(fieldValue));
}
}

LOGGER.verbose(String.format("Successfully serialized model: %s", serializedData));

result.add("serializedData", serializedData);
return result;
}

@Override
public SerializedModel deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
LOGGER.verbose(String.format("deserialize: json=%s, typeOfT=%s", json, typeOfT));
JsonObject object = json.getAsJsonObject();
ModelSchema modelSchema = context.deserialize(object.get("modelSchema"), ModelSchema.class);

Expand All @@ -99,8 +119,15 @@ public SerializedModel deserialize(JsonElement json, Type typeOfT, JsonDeseriali
JsonElement fieldValue = item.getValue();
String fieldName = field.getName();

boolean isModel = field.isModel();
boolean isCustomType = field.isCustomType();
boolean isArray = field.isArray();
LOGGER.verbose(String.format(
"Deserializing field %s: isModel=%s, isCustom=%s, isArray=%s",
fieldName, isModel, isCustomType, isArray));

// if the field type is a Model - convert the nested data into SerializedModel
if (field.isModel()) {
if (isModel) {
SchemaRegistry schemaRegistry = SchemaRegistry.instance();
ModelSchema nestedModelSchema = schemaRegistry.getModelSchemaForModelClass(field.getTargetType());
Gson gson = new Gson();
Expand All @@ -110,9 +137,19 @@ public SerializedModel deserialize(JsonElement json, Type typeOfT, JsonDeseriali
.modelSchema(nestedModelSchema)
.serializedData(gson.fromJson(fieldValue, mapType))
.build());
} else if (field.isCustomType()) {
} else if (isCustomType) {
// if the field type is a CustomType - convert the nested data into SerializedCustomType
serializedData.put(fieldName, context.deserialize(fieldValue, SerializedCustomType.class));
if (isArray) {
JsonArray serializedValues = fieldValue.getAsJsonArray();
ArrayList<SerializedCustomType> deserializedValues = new ArrayList<>();
for (int i = 0; i < serializedValues.size(); i++) {
JsonElement serializedValue = serializedValues.get(i);
deserializedValues.add(context.deserialize(serializedValue, SerializedCustomType.class));
}
serializedData.put(fieldName, deserializedValues);
} else {
serializedData.put(fieldName, context.deserialize(fieldValue, SerializedCustomType.class));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -154,9 +155,13 @@ public void serdeForNestedCustomTypes() throws JSONException, AmplifyException {
.customTypeSchema(phoneSchema)
.build();

List<SerializedCustomType> additionalPhoneNumbers = new ArrayList<>();
additionalPhoneNumbers.add(phone);
additionalPhoneNumbers.add(phone);
Map<String, Object> contactSerializedData = new HashMap<>();
contactSerializedData.put("email", "[email protected]");
contactSerializedData.put("phone", phone);
contactSerializedData.put("additionalPhoneNumbers", additionalPhoneNumbers);
SerializedCustomType contact = SerializedCustomType.builder()
.serializedData(contactSerializedData)
.customTypeSchema(contactSchema)
Expand Down Expand Up @@ -314,6 +319,14 @@ private CustomTypeSchema customTypeSchemaForContact() {
.isCustomType(true)
.isRequired(true)
.build());
contactFields.put("additionalPhoneNumbers", CustomTypeField.builder()
.name("additionalPhoneNumbers")
.targetType("Phone")
.javaClassForValue(Map.class)
.isCustomType(true)
.isArray(true)
.isRequired(true)
.build());
return CustomTypeSchema.builder()
.name("Contact")
.pluralName("Contacts")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,68 @@
"serializedData": {
"contact": {
"serializedData": {
"additionalPhoneNumbers": [
{
"serializedData": {
"number": "41555555555",
"countryCode": "+1"
},
"customTypeSchema": {
"pluralName": "Phones",
"name": "Phone",
"fields": {
"number": {
"javaClassForValue": "java.lang.String",
"isRequired": true,
"isCustomType": false,
"name": "number",
"isEnum": false,
"targetType": "String",
"isArray": false
},
"countryCode": {
"javaClassForValue": "java.lang.String",
"isRequired": true,
"isCustomType": false,
"name": "countryCode",
"isEnum": false,
"targetType": "String",
"isArray": false
}
}
}
},
{
"serializedData": {
"number": "41555555555",
"countryCode": "+1"
},
"customTypeSchema": {
"pluralName": "Phones",
"name": "Phone",
"fields": {
"number": {
"javaClassForValue": "java.lang.String",
"isRequired": true,
"isCustomType": false,
"name": "number",
"isEnum": false,
"targetType": "String",
"isArray": false
},
"countryCode": {
"javaClassForValue": "java.lang.String",
"isRequired": true,
"isCustomType": false,
"name": "countryCode",
"isEnum": false,
"targetType": "String",
"isArray": false
}
}
}
}
],
"phone": {
"serializedData": {
"number": "41555555555",
Expand Down Expand Up @@ -38,6 +100,15 @@
"pluralName": "Contacts",
"name": "Contact",
"fields": {
"additionalPhoneNumbers": {
"javaClassForValue": "java.util.Map",
"isRequired": true,
"isCustomType": true,
"name": "additionalPhoneNumbers",
"isEnum": false,
"targetType": "Phone",
"isArray": true
},
"phone": {
"javaClassForValue": "java.util.Map",
"isRequired": true,
Expand Down Expand Up @@ -109,4 +180,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import androidx.annotation.Nullable;
import androidx.core.util.ObjectsCompat;

import com.amplifyframework.core.Amplify;
import com.amplifyframework.core.category.CategoryType;
import com.amplifyframework.logging.Logger;
import com.amplifyframework.util.Immutable;

import java.util.ArrayList;
Expand All @@ -32,6 +35,9 @@
* Needs to be paired with an {@link CustomTypeSchema} to understand the structure.
*/
public final class SerializedCustomType {
private static final Logger LOGGER = Amplify.Logging.logger(
CategoryType.DATASTORE, SerializedCustomType.class.getName());

private final Map<String, Object> serializedData;
private Map<String, Object> flatSerializedData;
private final CustomTypeSchema customTypeSchema;
Expand Down Expand Up @@ -61,6 +67,10 @@ public static SerializedCustomType.BuilderSteps.SerializedDataStep builder() {
*/
public static Map<String, Object> parseSerializedData(Map<String, Object> serializedData,
String customTypeName, SchemaRegistry schemaRegistry) {
LOGGER.verbose(String.format(
"parseSerializedData: serializedData=%s, customTypeName=%s",
serializedData, customTypeName));

Map<String, Object> result = new HashMap<>();
CustomTypeSchema customTypeSchema = schemaRegistry.getCustomTypeSchemaForCustomTypeClass(customTypeName);

Expand All @@ -79,10 +89,14 @@ public static Map<String, Object> parseSerializedData(Map<String, Object> serial
continue;
}

if (field.isCustomType()) {
CustomTypeSchema fieldCustomTypeSchema =
schemaRegistry.getCustomTypeSchemaForCustomTypeClass(field.getTargetType());
if (field.isArray()) {
boolean isCustomType = field.isCustomType();
boolean isArray = field.isArray();
LOGGER.verbose(String.format(
"Deserializing field %s: isCustomType=%s, isArray=%s",
key, isCustomType, isArray));

if (isCustomType) {
if (isArray) {
@SuppressWarnings("unchecked")
List<Map<String, Object>> fieldListData = (List<Map<String, Object>>) fieldValue;
List<SerializedCustomType> fieldList = new ArrayList<>();
Expand Down Expand Up @@ -113,7 +127,6 @@ public static Map<String, Object> parseSerializedData(Map<String, Object> serial
result.put(key, fieldValue);
}
}

return result;
}

Expand All @@ -139,6 +152,8 @@ public Map<String, Object> getFlatSerializedData() {
return flatSerializedData;
}

LOGGER.verbose(String.format("getFlatSerializedData: serializedData=%s", serializedData));

flatSerializedData = new HashMap<>();

for (Map.Entry<String, Object> entry : serializedData.entrySet()) {
Expand All @@ -150,6 +165,12 @@ public Map<String, Object> getFlatSerializedData() {

Object fieldValue = entry.getValue();

boolean isCustomType = field.isCustomType();
boolean isArray = field.isArray();
LOGGER.verbose(String.format(
"Flattening field %s: isCustomType=%s, isArray=%s",
field.getName(), isCustomType, isArray));

if (field.isCustomType() && fieldValue != null) {
if (field.isArray()) {
ArrayList<SerializedCustomType> items = (ArrayList<SerializedCustomType>) fieldValue;
Expand Down

0 comments on commit dae0624

Please sign in to comment.