perf[protocol]: check unsupported type

This commit is contained in:
godotg
2023-09-26 22:27:53 +08:00
parent 56e1280fea
commit 4bb87e8b90
3 changed files with 34 additions and 15 deletions
@@ -42,7 +42,6 @@ import javassist.NotFoundException;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.*;
import java.util.Map.Entry;
import static com.zfoo.protocol.ProtocolManager.*;
@@ -52,10 +51,10 @@ import static com.zfoo.protocol.ProtocolManager.*;
public class ProtocolAnalysis {
/**
* EN: Temporary variables will be destroyed after startup, and the class corresponding to the protocolId
* EN: Temp field will be destroyed after startup, and the class corresponding to the protocolId
* CN: 临时变量,启动完成就会销毁,协议Id对应的Class类
*/
private static final Map<Short, Class<?>> protocolClassMap = new HashMap<>(MAX_PROTOCOL_NUM);
private static Map<Short, Class<?>> protocolClassMap = new HashMap<>(MAX_PROTOCOL_NUM);
/**
* EN: Temp field, sub protocols
@@ -73,7 +72,16 @@ public class ProtocolAnalysis {
, "Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double", "String", "Character", "Object"
, "Collections", "Iterator", "List", "ArrayList", "Map", "HashMap", "Set", "HashSet");
// 临时变量,启动完成就会销毁,是一个基本类型序列化器
/**
* EN: Temp field, unsupported type
* CN: 临时变量,启动完成就会销毁,不支持的类型
*/
private static Set<Class<?>> unsupportedTypes = Set.of(char.class, Character.class);
/**
* EN: Temp field, base type serializer
* CN: 临时变量,启动完成就会销毁,是基本类型序列化器
*/
private static Map<Class<?>, ISerializer> baseSerializerMap = new HashMap<>(128);
static {
@@ -361,9 +369,11 @@ public class ProtocolAnalysis {
protocolIdPrimitiveMap = null;
}
protocolClassMap = null;
subProtocolIdMap = null;
protocolReserved = null;
baseSerializerMap = null;
unsupportedTypes = null;
EnhanceUtils.clear();
@@ -537,12 +547,13 @@ public class ProtocolAnalysis {
return MapField.valueOf(keyRegistration, valueRegistration, type);
} else {
checkUnsupportedType(fieldTypeClazz);
// 是一个协议引用变量
if (!protocolIdMap.containsKey(field.getType())) {
throw new RunException("协议[{}]的子协议[{}]没有注册", clazz.getCanonicalName(), field.getType().getCanonicalName());
if (!protocolIdMap.containsKey(fieldTypeClazz)) {
throw new RunException("sub protocol:[{}] needs to register in protocol:[{}]", fieldTypeClazz.getCanonicalName(), clazz.getCanonicalName());
}
var protocolId = ProtocolManager.protocolId(clazz);
var subProtocolId = ProtocolManager.protocolId(field.getType());
var subProtocolId = ProtocolManager.protocolId(fieldTypeClazz);
subProtocolIdMap.computeIfAbsent(protocolId, it -> new HashSet<>()).add(subProtocolId);
return ObjectProtocolField.valueOf(subProtocolId);
}
@@ -578,9 +589,10 @@ public class ProtocolAnalysis {
} else if (clazz.equals(List.class) || clazz.equals(Set.class) || clazz.equals(Map.class)) {
throw new RunException("不支持数组和集合联合使用[type:{}]类型", type);
} else {
checkUnsupportedType(clazz);
// 是一个协议引用变量
if (!protocolIdMap.containsKey(clazz)) {
throw new RunException("协议[{}]的子协议[{}]没有注册", currentProtocolClass.getCanonicalName(), clazz.getCanonicalName());
throw new RunException("sub protocol:[{}] needs to register in protocol:[{}]", clazz.getCanonicalName(), currentProtocolClass.getCanonicalName());
}
var protocolId = ProtocolManager.protocolId(currentProtocolClass);
var subProtocolId = ProtocolManager.protocolId(clazz);
@@ -588,7 +600,7 @@ public class ProtocolAnalysis {
return ObjectProtocolField.valueOf(subProtocolId);
}
}
throw new RunException("[type:{}]类型不正确", type);
throw new RunException("[type:{}] is incorrect", type);
}
@@ -643,6 +655,7 @@ public class ProtocolAnalysis {
}
public static short getProtocolIdAndCheckClass(Class<?> clazz) {
checkUnsupportedType(clazz);
// 是否为一个简单的javabean
ReflectionUtils.assertIsPojoClass(clazz);
// 不能是泛型类
@@ -662,6 +675,15 @@ public class ProtocolAnalysis {
return protocolId;
}
private static void checkUnsupportedType(Class<?> clazz) {
if (clazz.isEnum()) {
throw new RunException("[{}] enum is not supported, since other language not support enum", clazz.getSimpleName());
}
if (unsupportedTypes.stream().anyMatch(it -> clazz.isAssignableFrom(it))) {
throw new RunException("[{}] is not supported, since other language not support it", clazz.getSimpleName());
}
}
private static void checkAllModules() {
// 模块id不能重复
var moduleIdSet = new HashSet<Byte>();
@@ -380,13 +380,8 @@ public abstract class ClassUtils {
}
// 是否为一个简单的javabean,为了防止不同层对象混用造成潜在的并发问题,特别是网络层和po层混用
ReflectionUtils.assertIsPojoClass(clazz);
// 不能是泛型类
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
// 普通Pojo必须要有一个空的构造器
if (!clazz.isRecord()) {
ReflectionUtils.publicEmptyConstructor(clazz);
}
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}] cannot be generic class", clazz.getCanonicalName());
var filedList = ReflectionUtils.notStaticAndTransientFields(clazz);
@@ -107,6 +107,8 @@ public class StorageManager implements IStorageManager {
if (clazz.isRecord()) {
continue;
}
ReflectionUtils.assertIsPojoClass(clazz);
ReflectionUtils.publicEmptyConstructor(clazz);
var fieldList = ReflectionUtils.notStaticAndTransientFields(clazz);
for (var field : fieldList) {
if (Modifier.isPublic(field.getModifiers())) {