package io.rx_cache2.internal.cache;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.rx_cache2.internal.Memory;
import io.victoralbertos.jolyglot.JolyglotGenerics;
public final class GetDeepCopy extends Action {
private final JolyglotGenerics jolyglot;
@Inject public GetDeepCopy(Memory memory, io.rx_cache2.internal.Persistence persistence, JolyglotGenerics jolyglot) {
super(memory, persistence);
this.jolyglot = jolyglot;
}
public <T> T deepCopy(T data) {
try {
Class classData = data.getClass();
boolean isCollection = Collection.class.isAssignableFrom(classData);
boolean isArray = classData.isArray();
boolean isMap = Map.class.isAssignableFrom(classData);
if (isCollection) {
return getDeepCopyCollection(data);
} else if (isArray) {
return getDeepCopyArray(data);
} else if (isMap) {
return getDeepCopyMap(data);
} else {
return getDeepCopyObject(data);
}
} catch (Exception ignore) {
return data;
}
}
private <T> T getDeepCopyCollection(T data) {
Collection<T> collection = (Collection<T>) data;
if (collection.isEmpty()) return data;
Class classData = data.getClass();
if (List.class.isAssignableFrom(classData)) classData = List.class;
Class classItemCollection = collection.toArray()[0].getClass();
Type typeCollection = jolyglot.newParameterizedType(classData, classItemCollection);
String dataString = jolyglot.toJson(data);
return jolyglot.fromJson(dataString, typeCollection);
}
private <T> T getDeepCopyArray(T data) {
T[] array = (T[]) data;
if (array.length == 0) return data;
Class classItemArray = array[0].getClass();
Type typeRecord = jolyglot.arrayOf(classItemArray);
String dataString = jolyglot.toJson(data);
return jolyglot.fromJson(dataString, typeRecord);
}
private <T, K, V> T getDeepCopyMap(T data) {
Map<K, V> map = (Map<K, V>) data;
if (map.isEmpty()) return data;
Class classData = Map.class;
Class classValueMap = map.values().toArray()[0].getClass();
Class classKeyMap = map.keySet().toArray()[0].getClass();
Type typeMap = jolyglot.newParameterizedType(classData, classKeyMap, classValueMap);
String dataString = jolyglot.toJson(data);
return jolyglot.fromJson(dataString, typeMap);
}
private <T> T getDeepCopyObject(T data) {
if (data == null) return data;
Class classData = data.getClass();
Type type = jolyglot.newParameterizedType(classData);
String dataString = jolyglot.toJson(data);
return jolyglot.fromJson(dataString, type);
}
}