Skip to content

Commit

Permalink
Failsafe mode improvements, adapted for modular structure
Browse files Browse the repository at this point in the history
  • Loading branch information
SoKnight committed Jan 12, 2022
1 parent addb264 commit 9351060
Show file tree
Hide file tree
Showing 37 changed files with 518 additions and 542 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,7 @@ protected SimpleEasyDonateClient(
.create();

this.jsonSerialization = ModuleRegistrator.jsonSerializationService();
this.jsonSerialization.registerImplementationAliasesGroup(JsonModelsGroup.API_V3_SHOP_MODELS);
this.jsonSerialization.registerImplementationAliasesGroup(JsonModelsGroup.API_V3_SHOP_RESPONSES);
this.jsonSerialization.registerImplementationAliasesGroup(JsonModelsGroup.API_V3_PLUGIN_MODELS);
this.jsonSerialization.registerImplementationAliasesGroup(JsonModelsGroup.API_V3_PLUGIN_RESPONSES);
this.jsonSerialization.registerImplementationAliasesGroup(JsonModelsGroup.API_V3_MODELS);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

public enum JsonModelsGroup {

API_V3_SHOP_MODELS,
API_V3_SHOP_RESPONSES,
API_V3_PLUGIN_MODELS,
API_V3_PLUGIN_RESPONSES,
API_V3_MODELS,
CALLBACK_API_MODELS

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package ru.easydonate.easydonate4j.api.v3.data.model.gson.shop.purchase;

import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.easydonate.easydonate4j.api.v3.data.model.shop.purchase.CouponDiscount;
import ru.easydonate.easydonate4j.api.v3.data.model.shop.purchase.Discounts;
import ru.easydonate.easydonate4j.api.v3.data.model.shop.purchase.MassSaleDiscount;
import ru.easydonate.easydonate4j.json.serialization.Implementing;
import ru.easydonate.easydonate4j.util.Wrapper;

import java.lang.reflect.Type;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -19,6 +23,10 @@ public class DiscountsModel implements Discounts {
@SerializedName("coupon")
private CouponDiscount usedCoupon;

public static @NotNull DiscountsArrayDeserializer getDeserializer(@NotNull Gson unsafeGsonInstance) {
return new DiscountsArrayDeserializer(unsafeGsonInstance);
}

@Override
public @NotNull Optional<MassSaleDiscount> getActiveMassSale() {
return Wrapper.wrapNullable(activeMassSale);
Expand Down Expand Up @@ -52,4 +60,23 @@ public int hashCode() {
'}';
}

@AllArgsConstructor
private static final class DiscountsArrayDeserializer implements JsonDeserializer<DiscountsModel> {

private final Gson unsafeGsonInstance;

@Override
public @Nullable DiscountsModel deserialize(
@Nullable JsonElement json,
@NotNull Type type,
@NotNull JsonDeserializationContext context
) throws JsonParseException {
if(json == null || json.isJsonNull() || json.isJsonArray())
return null;

return unsafeGsonInstance.fromJson(json, type);
}

}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package ru.easydonate.easydonate4j.callback.data.model.gson.purchase;

import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.easydonate.easydonate4j.callback.data.model.purchase.CouponDiscount;
import ru.easydonate.easydonate4j.callback.data.model.purchase.Discounts;
import ru.easydonate.easydonate4j.callback.data.model.purchase.MassSaleDiscount;
import ru.easydonate.easydonate4j.json.serialization.Implementing;
import ru.easydonate.easydonate4j.util.Wrapper;

import java.lang.reflect.Type;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -19,6 +23,10 @@ public class DiscountsModel implements Discounts {
@SerializedName("coupon")
private CouponDiscount usedCoupon;

public static @NotNull DiscountsArrayDeserializer getDeserializer(@NotNull Gson unsafeGsonInstance) {
return new DiscountsArrayDeserializer(unsafeGsonInstance);
}

@Override
public @NotNull Optional<MassSaleDiscount> getActiveMassSale() {
return Wrapper.wrapNullable(activeMassSale);
Expand Down Expand Up @@ -52,4 +60,23 @@ public int hashCode() {
'}';
}

@AllArgsConstructor
private static final class DiscountsArrayDeserializer implements JsonDeserializer<DiscountsModel> {

private final Gson unsafeGsonInstance;

@Override
public @Nullable DiscountsModel deserialize(
@Nullable JsonElement json,
@NotNull Type type,
@NotNull JsonDeserializationContext context
) throws JsonParseException {
if(json == null || json.isJsonNull() || json.isJsonArray())
return null;

return unsafeGsonInstance.fromJson(json, type);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
import com.google.gson.TypeAdapterFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.easydonate.easydonate4j.api.v3.data.model.gson.shop.purchase.DiscountsModel;
import ru.easydonate.easydonate4j.exception.JsonSerializationException;
import ru.easydonate.easydonate4j.json.serialization.deserializer.gson.BooleanIntDeserializer;
import ru.easydonate.easydonate4j.json.serialization.deserializer.gson.DiscountsArrayDeserializer;
import ru.easydonate.easydonate4j.json.serialization.deserializer.gson.LocalDateTimeAdapter;
import ru.easydonate.easydonate4j.json.serialization.exclusion.GsonDeserializationExclusionStrategy;
import ru.easydonate.easydonate4j.json.serialization.exclusion.GsonSerializationExclusionStrategy;
import ru.easydonate.easydonate4j.json.serialization.failsafe.gson.ApiV3FailsafeModule;
import ru.easydonate.easydonate4j.json.serialization.failsafe.gson.CallbackApiFailsafeModule;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.JsonModelsGroup;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.api.v3.gson.PluginModelsRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.api.v3.gson.PluginResponsesRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.api.v3.gson.ShopModelsRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.api.v3.gson.ShopResponsesRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.callback.gson.CallbackApiModelsRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.gson.ApiV3ModelsRegistry;
import ru.easydonate.easydonate4j.json.serialization.implementation.registry.gson.CallbackApiModelsRegistry;
import ru.easydonate.easydonate4j.module.ModuleAlreadyRegisteredException;
import ru.easydonate.easydonate4j.module.ModuleRegistrator;
import ru.easydonate.easydonate4j.module.ModuleType;
Expand All @@ -27,15 +24,19 @@

public final class GsonSerializationService extends AbstractJsonSerializationService {

private final Gson defaultGson;
private final Gson prettyGson;
private final GsonBuilder defaultGsonBuilder;
private final GsonBuilder prettyGsonBuilder;
private final Gson unsafeGsonInstance;

private Gson defaultGson;
private Gson prettyGson;

public GsonSerializationService() {
TypeAdapterFactory typeAdapterFactory = new GsonTypeAdapterResolver(this);

Gson unsafeGsonInstance = createGsonBuilder(typeAdapterFactory, null).create();
this.defaultGson = createGsonBuilder(typeAdapterFactory, unsafeGsonInstance).create();
this.prettyGson = createGsonBuilder(typeAdapterFactory, unsafeGsonInstance).setPrettyPrinting().create();
this.defaultGsonBuilder = createGsonBuilder(typeAdapterFactory);
this.prettyGsonBuilder = createGsonBuilder(typeAdapterFactory).setPrettyPrinting();
this.unsafeGsonInstance = createGsonBuilder(typeAdapterFactory).create();
updateGsonInstances();
}

public static void register() throws ModuleAlreadyRegisteredException {
Expand All @@ -62,20 +63,15 @@ public static boolean isRegistered() {
@Override
public <T> void registerImplementationAliasesGroup(@NotNull JsonModelsGroup jsonModelsGroup) {
switch (jsonModelsGroup) {
case API_V3_SHOP_MODELS:
registerModelsGroup(jsonModelsGroup, ShopModelsRegistry.getSingleton());
break;
case API_V3_SHOP_RESPONSES:
registerModelsGroup(jsonModelsGroup, ShopResponsesRegistry.getSingleton());
break;
case API_V3_PLUGIN_MODELS:
registerModelsGroup(jsonModelsGroup, PluginModelsRegistry.getSingleton());
break;
case API_V3_PLUGIN_RESPONSES:
registerModelsGroup(jsonModelsGroup, PluginResponsesRegistry.getSingleton());
case API_V3_MODELS:
registerModelsGroup(jsonModelsGroup, ApiV3ModelsRegistry.getSingleton());
new ApiV3FailsafeModule(unsafeGsonInstance).register(defaultGsonBuilder, prettyGsonBuilder);
updateGsonInstances();
break;
case CALLBACK_API_MODELS:
registerModelsGroup(jsonModelsGroup, CallbackApiModelsRegistry.getSingleton());
new CallbackApiFailsafeModule(unsafeGsonInstance).register(defaultGsonBuilder, prettyGsonBuilder);
updateGsonInstances();
break;
default:
throw new IllegalArgumentException(String.format("An unexpected json models group received: %s!", jsonModelsGroup));
Expand Down Expand Up @@ -109,7 +105,12 @@ public <T> void registerImplementationAliasesGroup(@NotNull JsonModelsGroup json
}
}

private @NotNull GsonBuilder createGsonBuilder(@NotNull TypeAdapterFactory typeAdapterFactory, @Nullable Gson unsafeGsonInstance) {
private void updateGsonInstances() {
this.defaultGson = defaultGsonBuilder.create();
this.prettyGson = prettyGsonBuilder.create();
}

private @NotNull GsonBuilder createGsonBuilder(@NotNull TypeAdapterFactory typeAdapterFactory) {
GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.serializeNulls();
Expand All @@ -121,11 +122,6 @@ public <T> void registerImplementationAliasesGroup(@NotNull JsonModelsGroup json
gsonBuilder.registerTypeAdapter(boolean.class, BooleanIntDeserializer.getSingleton());
gsonBuilder.registerTypeAdapter(LocalDateTime.class, LocalDateTimeAdapter.getSingleton());

if(unsafeGsonInstance != null) {
// Bug [12.01.22]: some payment objects has an empty array instead of `null` for the `sales` field
gsonBuilder.registerTypeAdapter(DiscountsModel.class, new DiscountsArrayDeserializer(unsafeGsonInstance));
}

gsonBuilder.registerTypeAdapterFactory(typeAdapterFactory);
return gsonBuilder;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.easydonate.easydonate4j.json.serialization.failsafe.gson;

import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import ru.easydonate.easydonate4j.api.v3.data.model.gson.shop.purchase.DiscountsModel;

public final class ApiV3FailsafeModule extends GsonFailsafeModule {

public ApiV3FailsafeModule(@NotNull Gson unsafeGsonInstance) {
// Bug [12.01.22]: some payment objects has an empty array instead of `null` for the `sales` field
super.registerTypeAdapter(DiscountsModel.class, DiscountsModel.getDeserializer(unsafeGsonInstance));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.easydonate.easydonate4j.json.serialization.failsafe.gson;

import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import ru.easydonate.easydonate4j.callback.data.model.gson.purchase.DiscountsModel;

public final class CallbackApiFailsafeModule extends GsonFailsafeModule {

public CallbackApiFailsafeModule(@NotNull Gson unsafeGsonInstance) {
// Bug [12.01.22]: some payment objects has an empty array instead of `null` for the `sales` field
super.registerTypeAdapter(DiscountsModel.class, DiscountsModel.getDeserializer(unsafeGsonInstance));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.easydonate.easydonate4j.json.serialization.failsafe.gson;

import com.google.gson.GsonBuilder;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;

public abstract class GsonFailsafeModule {

protected final Map<Type, Object> typeAdapters;

protected GsonFailsafeModule() {
this.typeAdapters = new LinkedHashMap<>();
}

protected void registerTypeAdapter(@NotNull Type type, @NotNull Object typeAdapter) {
typeAdapters.put(type, typeAdapter);
}

public void register(@NotNull GsonBuilder... gsonBuilders) {
for(GsonBuilder gsonBuilder : gsonBuilders)
typeAdapters.forEach(gsonBuilder::registerTypeAdapter);
}

}

This file was deleted.

Loading

0 comments on commit 9351060

Please sign in to comment.