diff --git a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java index 592e039d..3397f1e2 100644 --- a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java +++ b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java @@ -39,6 +39,7 @@ import com.zfoo.protocol.util.AssertionUtils; import com.zfoo.protocol.util.ClassUtils; import com.zfoo.protocol.util.ReflectionUtils; import com.zfoo.protocol.util.StringUtils; +import com.zfoo.protocol.xml.XmlModuleDefinition; import com.zfoo.protocol.xml.XmlProtocols; import javassist.CannotCompileException; import javassist.NotFoundException; @@ -74,6 +75,8 @@ public class ProtocolAnalysis { //临时变量,存储xml配置协议id,启动完成销毁 private static Map protocolNameMap = new HashMap<>(MAX_PROTOCOL_NUM); + //临时变量,每个模块定义的协议 + private static Map>> moduleDefinitionClassMap = new HashMap<>(128); static { // 初始化基础类型序列化器 @@ -164,6 +167,7 @@ public class ProtocolAnalysis { AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName()); var protocolDefinitionMap = new HashMap(); + var classModuleDefinitionMap = new HashMap, Byte>(); for (var moduleDefinition : xmlProtocols.getModules()) { var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName()); AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId()); @@ -173,103 +177,93 @@ public class ProtocolAnalysis { if (CollectionUtils.isEmpty(moduleDefinition.getProtocols())) { continue; } + //模块定义所有协议 + Set> clazzSet = moduleDefinitionClassMap.computeIfAbsent(module.getId(), k -> new HashSet<>()); for (var protocolDefinition : moduleDefinition.getProtocols()) { protocolDefinitionMap.put(protocolDefinition.getLocation(), protocolDefinition.isEnhance()); protocolNameMap.put(protocolDefinition.getLocation(), protocolDefinition.getId()); + var packetClazzList = scanClassList(protocolDefinition.getLocation()); + clazzSet.addAll(packetClazzList); + for (Class clazz : packetClazzList) { + var previous = classModuleDefinitionMap.put(clazz, module.getId()); + if (previous != null && previous != module.getId()) { + throw new RunException("[class:{}]定义到了两个不同的[module:[{}][{}]]", clazz.getName(), previous, module.getId()); + } else if (previous != null && previous == module.getId()) { + //相同模块配置重复协议忽略 + continue; + } + var protocolId = getProtocolIdAndCheckClass(clazz); + initProtocolClass(protocolId, clazz); + } } - - } - - // 获取所有IPack子类 - var packetClazzList = new HashSet>(); - if (xmlProtocols.isPackages()) { - packetClazzList.addAll(scanPackageList(protocolDefinitionMap.keySet())); - } else { - packetClazzList.addAll(scanClassList(protocolDefinitionMap.keySet())); - } - - for (Class clazz : packetClazzList) { - var protocolId = getProtocolIdAndCheckClass(clazz); - initProtocolClass(protocolId, clazz); } var enhanceList = new ArrayList(); for (var moduleDefinition : xmlProtocols.getModules()) { var module = modules[moduleDefinition.getId()]; + var packetClazzList = getModuleDefinitionClass(moduleDefinition); for (Class clazz : packetClazzList) { var protocolId = ProtocolManager.protocolId(clazz); - if (protocolId < moduleDefinition.getMinId() || protocolId >= moduleDefinition.getMaxId()) { - continue; - } - var registration = parseProtocolRegistration(clazz, module); - if (xmlProtocols.isPackages() && !clazz.isAnnotationPresent(NotEnhance.class)) { - enhanceList.add(registration); - } else if (!xmlProtocols.isPackages() && protocolDefinitionMap.getOrDefault(clazz.getName(), true)) { - enhanceList.add(registration); - } - // 注册协议 - protocols[protocolId] = registration; - } - } - enhance(generateOperation, enhanceList); - } - - public static void analyzePackage(XmlProtocols xmlProtocols, GenerateOperation generateOperation) { - AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName()); - var packageList = new HashSet(); - for (var moduleDefinition : xmlProtocols.getModules()) { - var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName()); - - AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId()); - AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId()); - AssertionUtils.notNull(moduleDefinition.getProtocols(), "[module:{}] does not have any protocols", module.getName()); - modules[module.getId()] = module; - - for (var protocolDefinition : moduleDefinition.getProtocols()) { - packageList.add(protocolDefinition.getLocation()); - } - } - - // 获取所有IPack子类 - var packetClazzList = scanClassList(packageList); - for (Class clazz : packetClazzList) { - var protocolId = getProtocolIdAndCheckClass(clazz); - initProtocolClass(protocolId, clazz); - } - - var enhanceList = new ArrayList(); - for (var moduleDefinition : xmlProtocols.getModules()) { - var module = modules[moduleDefinition.getId()]; - for (Class clazz : packetClazzList) { - var protocolId = ProtocolManager.protocolId(clazz); - if (protocolId < moduleDefinition.getMinId() || protocolId >= moduleDefinition.getMaxId()) { - continue; - } var registration = parseProtocolRegistration(clazz, module); if (!clazz.isAnnotationPresent(NotEnhance.class)) { enhanceList.add(registration); + } else if (protocolDefinitionMap.getOrDefault(clazz.getName(), true)) { + enhanceList.add(registration); } // 注册协议 protocols[protocolId] = registration; } } + enhance(generateOperation, enhanceList); } - public static Set> scanPackageList(Set packageList) { + private static Set> getModuleDefinitionClass(XmlModuleDefinition moduleDefinition) { + var classSet = new HashSet>(); + for (short id = moduleDefinition.getMinId(); id < moduleDefinition.getMaxId(); id++) { + var clazz = protocolClassMap.get(id); + if (Objects.isNull(clazz)) { + continue; + } + classSet.add(clazz); + } + if (CollectionUtils.isNotEmpty(classSet)) { + return classSet; + } + + var moduleClassSet = moduleDefinitionClassMap.get(moduleDefinition.getId()); + if (CollectionUtils.isEmpty(moduleClassSet)) { + return classSet; + } + return moduleClassSet; + } + + public static Set> scanPackageList(String packageName) { //获取该路径下所有类 var clazzSet = new HashSet(); - for (var packageName : packageList) { - try { - var clazzList = ClassUtils.getAllClasses(packageName); - clazzSet.addAll(clazzList); - } catch (Exception e) { - throw new RunException("[{}]包扫描类异常", packageName, e); - } + try { + var clazzList = ClassUtils.getAllClasses(packageName); + clazzSet.addAll(clazzList); + } catch (Exception e) { + throw new RunException("[{}]包扫描类异常", packageName, e); } return scanClassList(clazzSet); } + public static Set> scanClassList(String className) { + var clazzSet = new HashSet>(); + try { + Class clazz = Class.forName(className); + if (!IPacket.class.isAssignableFrom(clazz) || clazz.isInterface()) { + return clazzSet; + } + clazzSet.add(clazz); + } catch (Exception e) { + clazzSet.addAll(scanPackageList(className)); + } + return clazzSet; + } + public static Set> scanClassList(Set classList) { var clazzSet = new HashSet>(); for (var className : classList) { @@ -280,7 +274,7 @@ public class ProtocolAnalysis { } clazzSet.add(clazz); } catch (Exception e) { - throw new RunException("[class:{}]类不存在", className); + clazzSet.addAll(scanPackageList(className)); } } return clazzSet; @@ -335,6 +329,7 @@ public class ProtocolAnalysis { protocolReserved = null; baseSerializerMap = null; protocolNameMap = null; + moduleDefinitionClassMap = null; EnhanceUtils.clear(); diff --git a/protocol/src/main/java/com/zfoo/protocol/xml/XmlProtocols.java b/protocol/src/main/java/com/zfoo/protocol/xml/XmlProtocols.java index ad892c02..9509ef88 100644 --- a/protocol/src/main/java/com/zfoo/protocol/xml/XmlProtocols.java +++ b/protocol/src/main/java/com/zfoo/protocol/xml/XmlProtocols.java @@ -20,28 +20,14 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import java.util.List; -@JsonPropertyOrder({"author", "packages", "modules"}) +@JsonPropertyOrder({"modules"}) @JacksonXmlRootElement(localName = "protocols") public class XmlProtocols { - @JacksonXmlProperty(isAttribute = true, localName = "author") - private String author; - - @JacksonXmlProperty(isAttribute = true, localName = "packages") - private boolean packages; - @JacksonXmlProperty(localName = "module") @JacksonXmlElementWrapper(useWrapping = false) private List modules; - public String getAuthor() { - return author; - } - - public boolean isPackages() { - return packages; - } - public List getModules() { return modules; } diff --git a/protocol/src/test/java/com/zfoo/protocol/util/DomUtilsTest.java b/protocol/src/test/java/com/zfoo/protocol/util/DomUtilsTest.java index 0219ea18..926a60be 100644 --- a/protocol/src/test/java/com/zfoo/protocol/util/DomUtilsTest.java +++ b/protocol/src/test/java/com/zfoo/protocol/util/DomUtilsTest.java @@ -46,13 +46,11 @@ public class DomUtilsTest { @Test public void testXmlWithHead() { var protos = DomUtils.string2Object(XML_WITH_HEAD, XmlProtocols.class); - Assert.assertEquals("godotg", protos.getAuthor()); } @Test public void testXmlOfStandardText() { var protos = DomUtils.string2Object(XML_OF_STANDARD_TEXT, XmlProtocols.class); - Assert.assertEquals("godotg", protos.getAuthor()); } }