2021-06-27 20:44:35 +00:00
|
|
|
package com.esotericsoftware.kryo.serializers;
|
|
|
|
|
|
|
|
import c.e.a.a;
|
|
|
|
import com.esotericsoftware.kryo.Kryo;
|
|
|
|
import com.esotericsoftware.kryo.serializers.FieldSerializer;
|
|
|
|
import java.lang.reflect.Array;
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.GenericArrayType;
|
|
|
|
import java.lang.reflect.ParameterizedType;
|
|
|
|
import java.lang.reflect.Type;
|
|
|
|
import java.lang.reflect.TypeVariable;
|
|
|
|
import java.lang.reflect.WildcardType;
|
|
|
|
import java.util.HashMap;
|
|
|
|
public final class FieldSerializerGenericsUtil {
|
|
|
|
private Kryo kryo;
|
|
|
|
private FieldSerializer serializer;
|
|
|
|
|
|
|
|
public FieldSerializerGenericsUtil(FieldSerializer fieldSerializer) {
|
|
|
|
this.serializer = fieldSerializer;
|
|
|
|
this.kryo = fieldSerializer.getKryo();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Class[] getGenerics(Type type, Kryo kryo) {
|
|
|
|
Class concreteClass;
|
|
|
|
Class concreteClass2;
|
|
|
|
if (type instanceof GenericArrayType) {
|
|
|
|
Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
|
|
|
|
return genericComponentType instanceof Class ? new Class[]{(Class) genericComponentType} : getGenerics(genericComponentType, kryo);
|
|
|
|
} else if (!(type instanceof ParameterizedType)) {
|
|
|
|
return null;
|
|
|
|
} else {
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
|
|
|
|
Class[] clsArr = new Class[actualTypeArguments.length];
|
|
|
|
int length = actualTypeArguments.length;
|
|
|
|
int i = 0;
|
|
|
|
for (int i2 = 0; i2 < length; i2++) {
|
|
|
|
Type type2 = actualTypeArguments[i2];
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar2 = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
clsArr[i2] = Object.class;
|
|
|
|
if (type2 instanceof Class) {
|
|
|
|
clsArr[i2] = (Class) type2;
|
|
|
|
} else if (type2 instanceof ParameterizedType) {
|
|
|
|
clsArr[i2] = (Class) ((ParameterizedType) type2).getRawType();
|
|
|
|
} else if (type2 instanceof TypeVariable) {
|
|
|
|
GenericsResolver genericsResolver = kryo.getGenericsResolver();
|
|
|
|
if (genericsResolver.isSet() && (concreteClass2 = genericsResolver.getConcreteClass(((TypeVariable) type2).getName())) != null) {
|
|
|
|
clsArr[i2] = concreteClass2;
|
|
|
|
}
|
|
|
|
} else if (type2 instanceof GenericArrayType) {
|
|
|
|
Type genericComponentType2 = ((GenericArrayType) type2).getGenericComponentType();
|
|
|
|
if (genericComponentType2 instanceof Class) {
|
|
|
|
clsArr[i2] = Array.newInstance((Class) genericComponentType2, 0).getClass();
|
|
|
|
} else if (genericComponentType2 instanceof TypeVariable) {
|
|
|
|
GenericsResolver genericsResolver2 = kryo.getGenericsResolver();
|
|
|
|
if (genericsResolver2.isSet() && (concreteClass = genericsResolver2.getConcreteClass(((TypeVariable) genericComponentType2).getName())) != null) {
|
|
|
|
clsArr[i2] = Array.newInstance(concreteClass, 0).getClass();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Class[] generics = getGenerics(genericComponentType2, kryo);
|
|
|
|
if (generics != null) {
|
|
|
|
clsArr[i2] = generics[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (i == 0) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return clsArr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private Class<?> getTypeVarConcreteClass(Class[] clsArr, int i, String str) {
|
|
|
|
if (clsArr != null && clsArr.length > i) {
|
|
|
|
return clsArr[i];
|
|
|
|
}
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
GenericsResolver genericsResolver = this.kryo.getGenericsResolver();
|
|
|
|
if (genericsResolver.isSet()) {
|
|
|
|
return genericsResolver.getConcreteClass(str);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Generics buildGenericsScope(Class cls, Class[] clsArr) {
|
|
|
|
int i;
|
|
|
|
Type genericSuperclass;
|
|
|
|
TypeVariable[] typeVariableArr = null;
|
|
|
|
while (true) {
|
|
|
|
if (cls == null) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
FieldSerializer fieldSerializer = this.serializer;
|
|
|
|
typeVariableArr = cls == fieldSerializer.type ? fieldSerializer.typeParameters : cls.getTypeParameters();
|
|
|
|
if (!(typeVariableArr == null || typeVariableArr.length == 0)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
FieldSerializer fieldSerializer2 = this.serializer;
|
|
|
|
Class cls2 = fieldSerializer2.type;
|
|
|
|
if (cls == cls2) {
|
|
|
|
cls = fieldSerializer2.componentType;
|
|
|
|
if (cls == null) {
|
|
|
|
do {
|
|
|
|
genericSuperclass = cls2.getGenericSuperclass();
|
|
|
|
cls2 = cls2.getSuperclass();
|
|
|
|
if (genericSuperclass == null) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (!(genericSuperclass instanceof ParameterizedType));
|
|
|
|
if (genericSuperclass != null) {
|
|
|
|
Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
|
|
|
|
typeVariableArr = cls2.getTypeParameters();
|
|
|
|
clsArr = new Class[actualTypeArguments.length];
|
|
|
|
for (int i2 = 0; i2 < actualTypeArguments.length; i2++) {
|
|
|
|
clsArr[i2] = actualTypeArguments[i2] instanceof Class ? (Class) actualTypeArguments[i2] : Object.class;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cls = cls.getComponentType();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (typeVariableArr == null || typeVariableArr.length <= 0) {
|
|
|
|
return null;
|
|
|
|
}
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
HashMap hashMap = new HashMap();
|
|
|
|
int i3 = 0;
|
|
|
|
for (TypeVariable typeVariable : typeVariableArr) {
|
|
|
|
String name = typeVariable.getName();
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar2 = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
Class<?> typeVarConcreteClass = getTypeVarConcreteClass(clsArr, i3, name);
|
|
|
|
if (typeVarConcreteClass != null) {
|
|
|
|
hashMap.put(name, typeVarConcreteClass);
|
|
|
|
}
|
|
|
|
i3++;
|
|
|
|
}
|
|
|
|
return new Generics(hashMap);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Class[] computeFieldGenerics(Type type, Field field, Class[] clsArr) {
|
|
|
|
Generics genericsScope;
|
|
|
|
Class concreteClass;
|
|
|
|
if (type == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if ((type instanceof TypeVariable) && this.serializer.getGenericsScope() != null) {
|
|
|
|
Class concreteClass2 = this.serializer.getGenericsScope().getConcreteClass(((TypeVariable) type).getName());
|
|
|
|
if (concreteClass2 == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
clsArr[0] = concreteClass2;
|
|
|
|
Class[] clsArr2 = {clsArr[0]};
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
return clsArr2;
|
|
|
|
} else if (type instanceof ParameterizedType) {
|
|
|
|
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
|
|
|
|
if (actualTypeArguments == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Class[] clsArr3 = new Class[actualTypeArguments.length];
|
|
|
|
for (int i = 0; i < actualTypeArguments.length; i++) {
|
|
|
|
Type type2 = actualTypeArguments[i];
|
|
|
|
if (type2 instanceof Class) {
|
|
|
|
clsArr3[i] = (Class) type2;
|
|
|
|
} else if (type2 instanceof ParameterizedType) {
|
|
|
|
clsArr3[i] = (Class) ((ParameterizedType) type2).getRawType();
|
|
|
|
} else if ((type2 instanceof TypeVariable) && this.serializer.getGenericsScope() != null) {
|
|
|
|
clsArr3[i] = this.serializer.getGenericsScope().getConcreteClass(((TypeVariable) type2).getName());
|
|
|
|
if (clsArr3[i] == null) {
|
|
|
|
clsArr3[i] = Object.class;
|
|
|
|
}
|
|
|
|
} else if (type2 instanceof WildcardType) {
|
|
|
|
clsArr3[i] = Object.class;
|
|
|
|
} else if (type2 instanceof GenericArrayType) {
|
|
|
|
Type genericComponentType = ((GenericArrayType) type2).getGenericComponentType();
|
|
|
|
if (genericComponentType instanceof Class) {
|
|
|
|
clsArr3[i] = Array.newInstance((Class) genericComponentType, 0).getClass();
|
|
|
|
} else if (!(!(genericComponentType instanceof TypeVariable) || (genericsScope = this.serializer.getGenericsScope()) == null || (concreteClass = genericsScope.getConcreteClass(((TypeVariable) genericComponentType).getName())) == null)) {
|
|
|
|
clsArr3[i] = Array.newInstance(concreteClass, 0).getClass();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
clsArr3[i] = null;
|
|
|
|
}
|
|
|
|
}
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar2 = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
return clsArr3;
|
|
|
|
} else if (!(type instanceof GenericArrayType)) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
Class[] computeFieldGenerics = computeFieldGenerics(((GenericArrayType) type).getGenericComponentType(), field, new Class[]{clsArr[0]});
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar3 = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
return computeFieldGenerics;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public FieldSerializer.CachedField newCachedFieldOfGenericType(Field field, int i, Class[] clsArr, Type type) {
|
2021-07-13 20:23:20 +00:00
|
|
|
a.C0053a aVar = a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
buildGenericsScope(clsArr[0], getGenerics(type, this.kryo));
|
|
|
|
if (clsArr[0] == Object.class && (type instanceof TypeVariable) && this.serializer.getGenericsScope() != null) {
|
|
|
|
TypeVariable typeVariable = (TypeVariable) type;
|
|
|
|
Class concreteClass = this.serializer.getGenericsScope().getConcreteClass(typeVariable.getName());
|
|
|
|
if (concreteClass != null) {
|
|
|
|
new Generics().add(typeVariable.getName(), concreteClass);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Class[] computeFieldGenerics = computeFieldGenerics(type, field, clsArr);
|
|
|
|
FieldSerializer.CachedField newMatchingCachedField = this.serializer.newMatchingCachedField(field, i, clsArr[0], type, computeFieldGenerics);
|
|
|
|
if (computeFieldGenerics != null && (newMatchingCachedField instanceof ObjectField) && computeFieldGenerics.length > 0 && computeFieldGenerics[0] != null) {
|
|
|
|
((ObjectField) newMatchingCachedField).generics = computeFieldGenerics;
|
|
|
|
}
|
|
|
|
return newMatchingCachedField;
|
|
|
|
}
|
|
|
|
}
|