diff --git a/net/src/main/java/com/zfoo/net/config/manager/ConfigManager.java b/net/src/main/java/com/zfoo/net/config/manager/ConfigManager.java index 53d20b4d..3384d2c4 100644 --- a/net/src/main/java/com/zfoo/net/config/manager/ConfigManager.java +++ b/net/src/main/java/com/zfoo/net/config/manager/ConfigManager.java @@ -61,9 +61,9 @@ public class ConfigManager implements IConfigManager { public void initRegistry() { // 通过protocol,写入provider的module的id和version var providerConfig = localConfig.getProvider(); - // 服务提供者名字Set列表 - var providerSet = new HashSet(); if (Objects.nonNull(providerConfig) && CollectionUtils.isNotEmpty(providerConfig.getProviders())) { + // 服务提供者名字Set列表 + var providerSet = new HashSet(); // 检查并且替换配置文件中的ProtocolModule for (var providerModule : providerConfig.getProviders()) { var provider = providerModule.getProvider(); @@ -93,8 +93,6 @@ public class ConfigManager implements IConfigManager { AssertionUtils.isTrue(protocolModuleSet.add(protocolModuleName), "服务消费者[name:{}]重复消费了协议模块", protocolModuleName); var consumerName = StringUtils.joinWith(StringUtils.HYPHEN, protocolModuleName, consumer); AssertionUtils.isTrue(consumerSet.add(consumerName), "服务消费者[name:{}]重复消费了协议模块[consumer:{}]", protocolModuleName, consumer); - //检查是否消费了自己 - AssertionUtils.isTrue(!providerSet.contains(consumerName), "服务消费者[name:{}]不允许消费自己[consumer:{}]", protocolModuleName, consumer); } } diff --git a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolDocument.java b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolDocument.java index 56cb330b..e7631d4c 100644 --- a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolDocument.java +++ b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolDocument.java @@ -15,18 +15,15 @@ package com.zfoo.protocol.generate; import com.zfoo.protocol.model.Pair; import com.zfoo.protocol.registration.IProtocolRegistration; +import com.zfoo.protocol.registration.ProtocolRegistration; +import com.zfoo.protocol.serializer.anno.Description; import com.zfoo.protocol.util.AssertionUtils; -import com.zfoo.protocol.util.FileUtils; import com.zfoo.protocol.util.StringUtils; -import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; - -import static com.zfoo.protocol.util.FileUtils.LS; /** * 生成协议的时候,协议的文档注释和字段注释会使用这个类 @@ -77,109 +74,25 @@ public abstract class GenerateProtocolDocument { AssertionUtils.notNull(protocolDocumentMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolDocument", GenerateProtocolDocument.class.getSimpleName()); // 文件的注释生成 - var proAbsFile = new File(FileUtils.getProAbsPath()); - var list = FileUtils.getAllReadableFiles(proAbsFile.getParentFile() == null ? proAbsFile : proAbsFile.getParentFile()) - .stream() - .filter(it -> it.getName().endsWith(".java")) - .collect(Collectors.toList()); - for (var protocolRegistration : protocolRegistrations) { var protocolClazz = protocolRegistration.protocolConstructor().getDeclaringClass(); - var protocolClazzName = protocolClazz.getName(); - - var protocolFile = list.stream() - .filter(it -> it.getAbsolutePath().replace(StringUtils.SLASH, StringUtils.PERIOD).replace(StringUtils.BACK_SLASH, StringUtils.PERIOD).endsWith(StringUtils.format("{}.java", protocolClazzName))) - .findFirst(); - - // 如果搜索不到协议文件则直接返回 - if (protocolFile.isEmpty()) { - continue; - } - var docFieldMap = new HashMap(); var docTitle = StringUtils.EMPTY; - - var protocolStringList = FileUtils.readFileToStringList(protocolFile.get()) - .stream() - .dropWhile(it -> !it.startsWith("package")) // 过滤掉package之上的版权信息 - .collect(Collectors.toList()); - - // 搜索包名,报名不匹配则直接返回 - var protocolClassTitle = StringUtils.format("public class {}", protocolClazz.getSimpleName()); - if (protocolStringList.stream().noneMatch(it -> it.contains(protocolClassTitle))) { - continue; + var description = protocolClazz.getDeclaredAnnotation(Description.class); + if (description != null) { + var docTitleBuilder = new StringBuilder().append("//").append(description.value()); + docTitle = docTitleBuilder.toString(); } - protocolStringList = protocolStringList.stream() - .dropWhile(it -> !it.startsWith("package")) - .collect(Collectors.toList()); - - var docBuilder = new StringBuilder(); - var docTitleBuilder = new StringBuilder(); - for (var line : protocolStringList) { - var startLineStr = line.trim(); - - // 排除java的包头 - if (startLineStr.startsWith("package") || startLineStr.startsWith("import")) { + var registration = (ProtocolRegistration) protocolRegistration; + for (var field : registration.getFields()) { + var fieldDescrption = field.getDeclaredAnnotation(Description.class); + if (fieldDescrption == null) { continue; } - - - if (startLineStr.startsWith("public class ")) { - if (docTitleBuilder != null) { - docTitle = docTitleBuilder.toString(); - docTitle = docTitle.replace("/**", StringUtils.EMPTY); - docTitle = docTitle.replace(" */", StringUtils.EMPTY); - docTitle = docTitle.replace(" *", "//"); - docTitle = docTitle.trim(); - docBuilder = new StringBuilder(); - docTitleBuilder = null; - } - } else { - if (docTitleBuilder != null) { - docTitleBuilder.append(line).append(LS); - } - } - - // 保留注释 - if (startLineStr.startsWith("*/")) { - continue; - } - - if (startLineStr.startsWith("//") || startLineStr.startsWith("*")) { - startLineStr = startLineStr.replaceFirst("//", StringUtils.EMPTY); - startLineStr = startLineStr.replaceFirst("\\*", StringUtils.EMPTY); - docBuilder.append("//").append(startLineStr).append(LS); - continue; - } - - if (startLineStr.startsWith("private static ")) { - continue; - } - - if (startLineStr.contains(" transient ")) { - continue; - } - - if (startLineStr.startsWith("public void set") || startLineStr.startsWith("public bool equals") - || startLineStr.startsWith("public int hashCode") || startLineStr.startsWith("@Override")) { - continue; - } - - if (startLineStr.endsWith("{") || startLineStr.startsWith("return ") || startLineStr.startsWith("}")) { - continue; - } - - if (!startLineStr.endsWith(";")) { - continue; - } - if (!(startLineStr.startsWith("private ") || startLineStr.startsWith("public "))) { - continue; - } - - var fieldName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(startLineStr, StringUtils.SPACE), StringUtils.SEMICOLON).trim(); + var docBuilder = new StringBuilder().append("//").append(fieldDescrption.value()); + var fieldName = field.getName(); docFieldMap.put(fieldName, docBuilder.toString()); - docBuilder = new StringBuilder(); } protocolDocumentMap.put(protocolRegistration.protocolId(), new Pair<>(docTitle, docFieldMap)); diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/anno/Description.java b/protocol/src/main/java/com/zfoo/protocol/serializer/anno/Description.java new file mode 100644 index 00000000..89273042 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/anno/Description.java @@ -0,0 +1,17 @@ +package com.zfoo.protocol.serializer.anno; + +import java.lang.annotation.*; + +/** + * @author meiw + * @version 3.0 + * + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE}) +public @interface Description { + + String value() default ""; + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/util/FileUtils.java b/protocol/src/main/java/com/zfoo/protocol/util/FileUtils.java index 92e3d3d5..85bfe1c0 100644 --- a/protocol/src/main/java/com/zfoo/protocol/util/FileUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/util/FileUtils.java @@ -445,6 +445,38 @@ public abstract class FileUtils { return list; } + /** + * 写入一个content + * + * @param file 文件的绝对路径 + * @param content 写入的内容 + * @param append 是否追加 + */ + public static void writeStringToFile(File file, String content, boolean append) { + // 字节流 + FileOutputStream fileOutputStream = null; + // 转换流,设置编码集和解码集 .处理乱码问题,是字节到字符的桥梁 + OutputStreamWriter outputStreamWriter = null; + //处理流中的缓冲流,提高效率 + BufferedWriter bufferedWriter = null; + // 如果不用缓冲流的话,程序是读一个数据,写一个数据,这样在数据量大的程序中非常影响效率。 + // 缓冲流作用是把数据先写入缓冲区,等缓冲区满了,再把数据写到文件里。这样效率就大大提高了 + try { + // 以追加的方式打开文件 + fileOutputStream = openOutputStream(file, append); + outputStreamWriter = new OutputStreamWriter(fileOutputStream, StringUtils.DEFAULT_CHARSET_NAME); + bufferedWriter = new BufferedWriter(outputStreamWriter); + bufferedWriter.write(content);// 写数据 + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + // Java的垃圾回收机制不会回收任何的物理资源,只会回收堆内存中对象所占用的内存 + // finally总会被执行,即使try块中和catch块中有return,也会被执行。 + // 用来显示回收数据库连接,网络连接,磁盘文件 + IOUtils.closeIO(bufferedWriter, outputStreamWriter, fileOutputStream); + } + } + /** * 以追加的方式写入一个content