perf[protocol]: throw en exception

This commit is contained in:
godotg
2023-10-31 11:09:55 +08:00
parent 99a77172f6
commit c0d9023bc2
@@ -104,14 +104,14 @@ public class ProtocolAnalysis {
}
/**
* 真正的注册协议,将协议id和协议信息关联起来
* parse protocol type
*/
public static synchronized void analyze(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
AssertionUtils.notNull(subProtocolIdMap, "[{}] initialization has already been completed, please do not repeat the initialization", ProtocolManager.class.getSimpleName());
// 检查协议类是否合法
for (var protocolClass : protocolClassSet) {
var protocolId = getProtocolIdAndCheckClass(protocolClass);
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]必须使用注解@Protocol注解标注", protocolClass.getCanonicalName());
AssertionUtils.isTrue(protocolId >= 0, "[class:{}] must use annotation @Protocol annotation", protocolClass.getCanonicalName());
initProtocolClass(protocolId, protocolClass);
}
@@ -127,7 +127,7 @@ public class ProtocolAnalysis {
}
public static synchronized void analyzeAuto(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
AssertionUtils.notNull(subProtocolIdMap, "[{}] initialization has already been completed, please do not repeat the initialization", ProtocolManager.class.getSimpleName());
// 获取所有协议类
var relevantClassSet = new HashSet<>(protocolClassSet);
for (var clazz : protocolClassSet) {
@@ -168,7 +168,7 @@ public class ProtocolAnalysis {
}
public static synchronized void analyze(XmlProtocols xmlProtocols, GenerateOperation generateOperation) {
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
AssertionUtils.notNull(subProtocolIdMap, "[{}] initialization has already been completed, please do not repeat the initialization", ProtocolManager.class.getSimpleName());
var protocolXmlEnhanceMap = new HashMap<Class<?>, Boolean>();
var classModuleDefinitionMap = new HashMap<Class<?>, Byte>();
@@ -178,7 +178,7 @@ public class ProtocolAnalysis {
for (var moduleDefinition : xmlProtocols.getModules()) {
var moduleId = moduleDefinition.getId();
var module = new ProtocolModule(moduleId, moduleDefinition.getName());
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), moduleId);
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] must be greater than or equal to 1", module.getName(), moduleId);
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), moduleId);
modules[module.getId()] = module;
@@ -402,10 +402,12 @@ public class ProtocolAnalysis {
continue;
}
if (!clazz.isRecord() && Modifier.isFinal(modifiers)) {
throw new RunException("[{}]协议号中的[field:{}]属性的访问修饰符不能为final", clazz.getCanonicalName(), field.getName());
// 协议号中的属性的访问修饰符不能为final
throw new RunException("The access modifier for the [field:{}] attribute in the [{}] protocol number cannot be final", clazz.getCanonicalName(), field.getName());
}
if (!Modifier.isPublic(modifiers) && !Modifier.isPrivate(modifiers)) {
throw new RunException("[{}]协议号中的[field:{}]属性的访问修饰符必须是public或者private", clazz.getCanonicalName(), field.getName());
// 协议号中的属性的访问修饰符必须是public或者private
throw new RunException("The access modifier of the [field:{}] attribute in the [{}] protocol number must be public or private", clazz.getCanonicalName(), field.getName());
}
ReflectionUtils.makeAccessible(field);
@@ -422,7 +424,9 @@ public class ProtocolAnalysis {
var order = field.getAnnotation(Compatible.class).value();
var oldField = compatibleFieldMap.put(order, field);
if (oldField != null) {
throw new RunException("[{}]协议号中的[field:{}]和[field:{}]不能有相同的Compatible顺序[order:{}]", clazz.getCanonicalName(), oldField.getName(), field.getName(), oldField, order);
// 协议号中的属性不能有相同的Compatible order顺序
throw new RunException("[field:{}] and [field:{}] in the [{}] protocol number cannot have the same Compatible order [order:{}]"
, clazz.getCanonicalName(), oldField.getName(), field.getName(), oldField, order);
}
} else {
notCompatibleFields.add(field);
@@ -466,7 +470,7 @@ public class ProtocolAnalysis {
ReflectionUtils.makeAccessible(constructor);
return new ProtocolRegistration(protocolId, module.getId(), constructor, ArrayUtils.listToArray(fields, Field.class), ArrayUtils.listToArray(registrationList, IFieldRegistration.class));
} catch (Exception e) {
throw new RuntimeException(StringUtils.format("解析协议[class:{}]异常", clazz), e);
throw new RuntimeException(StringUtils.format("Resolve protocol [class:{}] exception", clazz), e);
}
}
@@ -486,19 +490,22 @@ public class ProtocolAnalysis {
return ArrayField.valueOf(registration, field.getType().getComponentType());
} else if (Set.class.isAssignableFrom(fieldTypeClazz)) {
if (!fieldTypeClazz.equals(Set.class)) {
throw new RunException("[class:{}]类型声明不正确,必须是Set接口类型", clazz.getCanonicalName());
// 必须是Set接口类型
throw new RunException("[class:{}] type declaration is incorrect, it must be of the Set interface type", clazz.getCanonicalName());
}
Type type = field.getGenericType();
if (!(type instanceof ParameterizedType)) {
throw new RunException("[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
// 必须是泛型类
throw new RunException("[class:{}] type declaration is incorrect, not a generic class[field:{}]", clazz.getCanonicalName(), field.getName());
}
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
if (types.length != 1) {
throw new RunException("[class:{}]中Set类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
// Set类型必须声明泛型类
throw new RunException("Set type declaration in [class:{}] is incorrect, and the generic class must be declared in [field:{}]", clazz.getCanonicalName(), field.getName());
}
IFieldRegistration registration = typeToRegistration(clazz, types[0]);
@@ -506,19 +513,22 @@ public class ProtocolAnalysis {
} else if (List.class.isAssignableFrom(fieldTypeClazz)) {
// 是一个List
if (!fieldTypeClazz.equals(List.class)) {
throw new RunException("[class:{}]类型声明不正确,必须是List接口类型", clazz.getCanonicalName());
// 必须是List接口类型
throw new RunException("[class:{}] type declaration is incorrect, it must be a List interface type", clazz.getCanonicalName());
}
Type type = field.getGenericType();
if (!(type instanceof ParameterizedType)) {
throw new RunException("[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
// List类型必须声明泛型类
throw new RunException("[class:{}] type declaration is incorrect, not a generic class[field:{}]", clazz.getCanonicalName(), field.getName());
}
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
if (types.length != 1) {
throw new RunException("[class:{}]中List类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
// List类型必须声明泛型类
throw new RunException("List type declaration in [class:{}] is incorrect, and the generic class must be declared in [field:{}]", clazz.getCanonicalName(), field.getName());
}
IFieldRegistration registration = typeToRegistration(clazz, types[0]);
@@ -526,19 +536,22 @@ public class ProtocolAnalysis {
} else if (Map.class.isAssignableFrom(fieldTypeClazz)) {
if (!fieldTypeClazz.equals(Map.class)) {
throw new RunException("[class:{}]类型声明不正确,必须是Map接口类型", clazz.getCanonicalName());
// 必须是Map接口类型
throw new RunException("[class:{}] type declaration is incorrect, it must be a Map interface type", clazz.getCanonicalName());
}
Type type = field.getGenericType();
if (!(type instanceof ParameterizedType)) {
throw new RunException("[class:{}]中Map类型声明不正确,[field:{}]不是泛型类", clazz.getCanonicalName(), field.getName());
// Map类型必须声明泛型类
throw new RunException("Map type declaration in [class:{}] is incorrect, and [field:{}] is not a generic class", clazz.getCanonicalName(), field.getName());
}
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
if (types.length != 2) {
throw new RunException("[class:{}]中Map类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
// Map类型必须声明泛型类
throw new RunException("Map type declaration in [class:{}] is incorrect, and the generic class must be declared in [field:{}]", clazz.getCanonicalName(), field.getName());
}
IFieldRegistration keyRegistration = typeToRegistration(clazz, types[0]);
@@ -583,8 +596,8 @@ public class ProtocolAnalysis {
// 基础类型
return BaseField.valueOf(serializer);
} else if (clazz.isArray()) {
// 是一个二维以上数组
throw new RunException("不支持多维数组或集合嵌套数组[type:{}]类型,仅支持一维数组", type);
// 不支持多维数组或集合嵌套数组类型,仅支持一维数组
throw new RunException("Multi-dimensional array or set nested arrays [type:{}] types are not supported, only one-dimensional arrays are supported", type);
} else if (clazz.equals(List.class) || clazz.equals(Set.class) || clazz.equals(Map.class)) {
throw new RunException("不支持数组和集合联合使用[type:{}]类型", type);
} else {
@@ -614,7 +627,8 @@ public class ProtocolAnalysis {
* 此方法仅在生成协议的时候调用,一旦运行,不能调用
*/
public static Set<Short> getAllSubProtocolIds(short protocolId) {
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,初始化完成过后不能调用getAllSubProtocolIds", ProtocolAnalysis.class.getSimpleName());
// 初始化完成过后不能调用getAllSubProtocolIds
AssertionUtils.notNull(subProtocolIdMap, "[{}] has been initially completed, and after the initialization is completed, you cannot call getAllSubProtocolIds", ProtocolAnalysis.class.getSimpleName());
if (!subProtocolIdMap.containsKey(protocolId)) {
return Collections.emptySet();
@@ -628,8 +642,10 @@ public class ProtocolAnalysis {
var firstSubProtocolId = queue.poll();
if (subProtocolIdMap.containsKey(firstSubProtocolId)) {
for (var subClassId : subProtocolIdMap.get(firstSubProtocolId)) {
// 不支持循环引用协议
if (subClassId == protocolId) {
throw new RunException("[class:{}]在下层协议[class:{}]包含循环引用协议[class:{}]", protocolClass.getSimpleName(), protocols[firstSubProtocolId].protocolConstructor().getDeclaringClass(), protocolClass.getSimpleName());
throw new RunException("[class:{}] contains circular reference protocol[class:{}] in the lower level protocol[class:{}]"
, protocolClass.getSimpleName(), protocols[firstSubProtocolId].protocolConstructor().getDeclaringClass(), protocolClass.getSimpleName());
}
if (!allSubProtocolIdSet.contains(subClassId)) {
@@ -648,8 +664,9 @@ public class ProtocolAnalysis {
protocolIdMap.put(clazz, protocolId);
protocolIdPrimitiveMap.putPrimitive(clazz.hashCode(), protocolId);
var previous = protocolClassMap.put(protocolId, clazz);
// 协议号重复
if (previous != null) {
throw new RunException("[{}][{}]协议号[protocolId:{}]重复", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId);
throw new RunException("[{}][{}] protocol number [protocolId:{}] is repeated", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId);
}
}
@@ -658,7 +675,7 @@ public class ProtocolAnalysis {
// 是否为一个简单的javabean
ReflectionUtils.assertIsPojoClass(clazz);
// 不能是泛型类
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}] can't be a generic class", clazz.getCanonicalName());
// 普通Pojo必须要有一个空的构造器
if (!clazz.isRecord()) {
@@ -688,14 +705,14 @@ public class ProtocolAnalysis {
var moduleIdSet = new HashSet<Byte>();
Arrays.stream(modules)
.filter(Objects::nonNull)
.peek(it -> AssertionUtils.isTrue(!moduleIdSet.contains(it.getId()), "模块[{}]存在重复的id,模块的id不能重复", it))
.peek(it -> AssertionUtils.isTrue(!moduleIdSet.contains(it.getId()), "duplicate id in module [{}], and the id of modules cannot be duplicated", it))
.forEach(it -> moduleIdSet.add(it.getId()));
// 模块名称不能重复
var moduleNameSet = new HashSet<String>();
Arrays.stream(modules)
.filter(Objects::nonNull)
.peek(it -> AssertionUtils.isTrue(!moduleNameSet.contains(it.getName()), "模块[{}]存在重复的name,模块名称不能重复", it))
.peek(it -> AssertionUtils.isTrue(!moduleNameSet.contains(it.getName()), "duplicate name in module [{}], and the module name cannot be duplicated", it))
.forEach(it -> moduleNameSet.add(it.getName()));
}
@@ -711,12 +728,15 @@ public class ProtocolAnalysis {
var protocolClass = protocolRegistration.protocolConstructor().getDeclaringClass();
var protocolName = protocolClass.getSimpleName();
// 协议不能含有重复的名称
if (allProtocolNameMap.containsKey(protocolName)) {
throw new RunException("[class:{}][class:{}]协议名称重复,协议不能含有重复的名称", protocolClass.getCanonicalName(), allProtocolNameMap.get(protocolName).getCanonicalName());
throw new RunException("[class:{}] and [class:{}] has duplicate protocol name, protocol cannot contain duplicate names"
, protocolClass.getCanonicalName(), allProtocolNameMap.get(protocolName).getCanonicalName());
}
//协议的名称不能是保留名称
if (protocolReserved.stream().anyMatch(it -> it.equalsIgnoreCase(protocolName))) {
throw new RunException("协议的名称[class:{}]不能是保留名称[{}]", protocolClass.getCanonicalName(), protocolName);
throw new RunException("The name of the protocol [class:{}] cannot be a reserved name [{}]", protocolClass.getCanonicalName(), protocolName);
}
allProtocolNameMap.put(protocolName, protocolClass);
@@ -733,7 +753,7 @@ public class ProtocolAnalysis {
var subProtocolSet = protocolEntry.getValue();
if (subProtocolSet.contains(protocolId)) {
var protocolClass = protocols[protocolId].protocolConstructor().getDeclaringClass();
throw new RunException("[class:{}]中存在自循环引用", protocolClass.getSimpleName());
throw new RunException("[class:{}] cannot be circular reference protocol", protocolClass.getSimpleName());
}
}
// 入度
@@ -774,7 +794,7 @@ public class ProtocolAnalysis {
}
// 抛出所有存在循环引用的协议类名
if (!circularReferenceProtocols.isEmpty()) {
throw new RunException("[class:{}]中存在循环引用", StringUtils.joinWith(",", circularReferenceProtocols.toArray()));
throw new RunException("[class:{}] cannot be circular reference protocol", StringUtils.joinWith(",", circularReferenceProtocols.toArray()));
}
}