feat[protocol]: 在使用xml方式注册协议不使用注解或者协议字段

This commit is contained in:
godotg committed 2022-10-22 18:23:15 +08:00
1 parent b2bd66a9ec
commit 27abc72cd8
1 file changed
+35 -41
@@ -99,7 +99,9 @@ public class ProtocolAnalysis {
try { try {
// 检查协议类是否合法 // 检查协议类是否合法
for (var protocolClass : protocolClassSet) { for (var protocolClass : protocolClassSet) {
checkProtocol(protocolClass); var protocolId = getProtocolIdAndCheckClass(protocolClass);
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]必须使用注解@Protocol注解标注或者使用[{}]字段", protocolClass.getCanonicalName(), PROTOCOL_ID);
initProtocolClass(protocolId, protocolClass);
} }
// 协议id和协议信息对应起来 // 协议id和协议信息对应起来
@@ -134,17 +136,22 @@ public class ProtocolAnalysis {
for (var protocolDefinition : moduleDefinition.getProtocols()) { for (var protocolDefinition : moduleDefinition.getProtocols()) {
var location = protocolDefinition.getLocation(); var location = protocolDefinition.getLocation();
var clazz = Class.forName(location); var clazz = Class.forName(location);
var id = getProtocolIdAndCheckClass(clazz); var protocolId = protocolDefinition.getId();
AssertionUtils.isTrue(id >= moduleDefinition.getMinId(), "模块[{}]中的协议[{}]的协议号必须大于或者等于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMinId()); // 如果xml文件中没有填protocolId则只需要获取到protocolId即可
AssertionUtils.isTrue(id < moduleDefinition.getMaxId(), "模块[{}]中的协议[{}]的协议号必须小于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMaxId()); if (protocolId < 0) {
AssertionUtils.isNull(protocols[id], "duplicate definition [id:{}] Exception!", id); protocolId = getProtocolIdAndCheckClass(clazz);
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]在使用xml方式注册协议,如果xml没有提供协议号,则需要使用注解或者协议字段标注协议号", clazz.getCanonicalName());
// 协议号是否和id是否相等,如果xml文件中没有填protocolId则不检测 } else {
if (protocolDefinition.getId() >= 0) { var id = getProtocolIdAndCheckClass(clazz);
AssertionUtils.isTrue(protocolDefinition.getId() == id, "[class:{}]协议序列号[{}]和协议文件里的协议序列号不相等", clazz.getCanonicalName(), PROTOCOL_ID); // 使用xml方式注册协议可以,协议class不需要使用注解或者字段标注协议号
if (id >= 0) {
AssertionUtils.isTrue(protocolId == id, "[class:{}]协议序列号[{}]和协议文件里的协议序列号不相等", clazz.getCanonicalName(), PROTOCOL_ID);
}
} }
checkProtocol(clazz); AssertionUtils.isTrue(protocolId >= moduleDefinition.getMinId(), "模块[{}]中的协议[{}]的协议号必须大于或者等于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMinId());
AssertionUtils.isTrue(protocolId < moduleDefinition.getMaxId(), "模块[{}]中的协议[{}]的协议号必须小于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMaxId());
initProtocolClass(protocolId, clazz);
} }
} }
@@ -169,30 +176,11 @@ public class ProtocolAnalysis {
} }
private static void enhance(GenerateOperation generateOperation, List<IProtocolRegistration> enhanceList) throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException { private static void enhance(GenerateOperation generateOperation, List<IProtocolRegistration> enhanceList) throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException {
initProtocolIdMap();
enhanceProtocolBefore(generateOperation); enhanceProtocolBefore(generateOperation);
enhanceProtocolRegistration(enhanceList); enhanceProtocolRegistration(enhanceList);
enhanceProtocolAfter(generateOperation); enhanceProtocolAfter(generateOperation);
} }
private static void initProtocolIdMap() {
for (var protocol : protocols) {
if (protocol == null) {
continue;
}
var clazz = protocol.protocolConstructor().getDeclaringClass();
var protocolId = protocol.protocolId();
protocolIdMap.put(clazz, protocolId);
protocolIdPrimitiveMap.putPrimitive(clazz.hashCode(), protocolId);
}
var distinctHashcode = protocolIdMap.keySet().stream().map(Object::hashCode).distinct().count();
if (distinctHashcode == protocolIdMap.size()) {
protocolIdMap = null;
} else {
protocolIdPrimitiveMap = null;
}
}
private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException, ClassNotFoundException { private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException, ClassNotFoundException {
// 检查协议格式 // 检查协议格式
checkAllProtocolClass(); checkAllProtocolClass();
@@ -221,6 +209,13 @@ public class ProtocolAnalysis {
} }
private static void enhanceProtocolAfter(GenerateOperation generateOperation) { private static void enhanceProtocolAfter(GenerateOperation generateOperation) {
var distinctHashcode = protocolIdMap.keySet().stream().map(Object::hashCode).distinct().count();
if (distinctHashcode == protocolIdMap.size()) {
protocolIdMap = null;
} else {
protocolIdPrimitiveMap = null;
}
subProtocolIdMap = null; subProtocolIdMap = null;
protocolReserved = null; protocolReserved = null;
baseSerializerMap = null; baseSerializerMap = null;
@@ -426,7 +421,7 @@ public class ProtocolAnalysis {
} else { } else {
// 是一个协议引用变量 // 是一个协议引用变量
var referenceProtocolId = getProtocolIdAndCheckClass(clazz); var referenceProtocolId = getProtocolIdAndCheckClass(clazz);
checkSubProtocol(clazz, referenceProtocolId, clazz); checkSubProtocol(currentProtocolClass, referenceProtocolId, clazz);
subProtocolIdMap.computeIfAbsent(getProtocolIdAndCheckClass(currentProtocolClass), it -> new HashSet<>()).add(referenceProtocolId); subProtocolIdMap.computeIfAbsent(getProtocolIdAndCheckClass(currentProtocolClass), it -> new HashSet<>()).add(referenceProtocolId);
return ObjectProtocolField.valueOf(referenceProtocolId); return ObjectProtocolField.valueOf(referenceProtocolId);
} }
@@ -469,17 +464,9 @@ public class ProtocolAnalysis {
// 协议智能语法分析,错误的协议定义将无法启动程序并给出错误警告 // 协议智能语法分析,错误的协议定义将无法启动程序并给出错误警告
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
private static void initProtocolClass(short protocolId, Class<?> clazz) {
private static void checkProtocol(Class<?> clazz) { protocolIdMap.put(clazz, protocolId);
// 是否为一个简单的javabean protocolIdPrimitiveMap.putPrimitive(clazz.hashCode(), protocolId);
ReflectionUtils.assertIsPojoClass(clazz);
// 是否实现了IPacket接口
AssertionUtils.isTrue(IPacket.class.isAssignableFrom(clazz), "[class:{}]没有实现接口[IPacket:{}]", clazz.getCanonicalName(), IPacket.class.getCanonicalName());
// 不能是泛型类
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
var protocolId = getProtocolIdAndCheckClass(clazz);
var previous = protocolClassMap.put(protocolId, clazz); var previous = protocolClassMap.put(protocolId, clazz);
if (previous != null) { if (previous != null) {
throw new RunException("[{}][{}]协议号[protocolId:{}]重复", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId); throw new RunException("[{}][{}]协议号[protocolId:{}]重复", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId);
@@ -487,6 +474,13 @@ public class ProtocolAnalysis {
} }
public static short getProtocolIdAndCheckClass(Class<?> clazz) { public static short getProtocolIdAndCheckClass(Class<?> clazz) {
// 是否为一个简单的javabean
ReflectionUtils.assertIsPojoClass(clazz);
// 是否实现了IPacket接口
AssertionUtils.isTrue(IPacket.class.isAssignableFrom(clazz), "[class:{}]没有实现接口[IPacket:{}]", clazz.getCanonicalName(), IPacket.class.getCanonicalName());
// 不能是泛型类
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
Field protocolIdField = null; Field protocolIdField = null;
try { try {
protocolIdField = clazz.getDeclaredField(PROTOCOL_ID); protocolIdField = clazz.getDeclaredField(PROTOCOL_ID);