From 7004c83a00d0bc1b644bd308b4526bd10f288d85 Mon Sep 17 00:00:00 2001 From: luochuan Date: Thu, 23 Nov 2023 18:57:36 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=AE=8C=E6=88=90=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/{JsonNode.java => AliasNode.java} | 4 +- .../generator/factory/AbstractGenerator.java | 143 ++++++++++++++++++ .../alis/generator/factory/JsonGenerator.java | 137 ++--------------- .../alis/generator/factory/XmlGenerator.java | 17 +++ 4 files changed, 173 insertions(+), 128 deletions(-) rename alis-generator-core/src/main/java/org/alis/generator/domain/model/{JsonNode.java => AliasNode.java} (83%) create mode 100644 alis-generator-core/src/main/java/org/alis/generator/factory/AbstractGenerator.java create mode 100644 alis-generator-core/src/main/java/org/alis/generator/factory/XmlGenerator.java diff --git a/alis-generator-core/src/main/java/org/alis/generator/domain/model/JsonNode.java b/alis-generator-core/src/main/java/org/alis/generator/domain/model/AliasNode.java similarity index 83% rename from alis-generator-core/src/main/java/org/alis/generator/domain/model/JsonNode.java rename to alis-generator-core/src/main/java/org/alis/generator/domain/model/AliasNode.java index bb63e3c..9d98edb 100644 --- a/alis-generator-core/src/main/java/org/alis/generator/domain/model/JsonNode.java +++ b/alis-generator-core/src/main/java/org/alis/generator/domain/model/AliasNode.java @@ -10,11 +10,11 @@ import java.util.List; * @date 2023/11/22 18:39 */ @Data -public class JsonNode { +public class AliasNode { private String name; private String alias; private String type; private String absolutePath; - private List nodes; + private List nodes; private Boolean arrayFlag=Boolean.FALSE; } diff --git a/alis-generator-core/src/main/java/org/alis/generator/factory/AbstractGenerator.java b/alis-generator-core/src/main/java/org/alis/generator/factory/AbstractGenerator.java new file mode 100644 index 0000000..5556bf7 --- /dev/null +++ b/alis-generator-core/src/main/java/org/alis/generator/factory/AbstractGenerator.java @@ -0,0 +1,143 @@ +package org.alis.generator.factory; + +import org.alis.generator.domain.model.AliasNode; +import org.alis.generator.domain.model.Content; +import org.alis.generator.domain.model.ContextConfig; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.text.MessageFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author lc + * @date 2023/11/23 18:49 + **/ +public abstract class AbstractGenerator implements Generator { + + + @Override + public Content generator(ContextConfig prop) { + String source = prop.getSource().trim(); + if (!StringUtils.hasLength(source)) { + return null; + } + + // 使用组合模式 + List aliasNodes = new ArrayList<>(); + // 匿名内部类 + List classNodes = new ArrayList<>(); + + dealHandler(prop.getSource(), aliasNodes, classNodes); + + // merge删除对应的类 + Map merge = merge(classNodes); + + // 生成class 文件 + StringBuilder builder = new StringBuilder(); + + // 包路径 + builder.append("package ").append(prop.getPackagePath()).append(";").append("\n\n"); + // 注解的包 + builder.append("import lombok.Data;").append("\n"); + // 导入所有的包 + List importList = new ArrayList<>(); + fillAllType(aliasNodes, importList); + importList.stream().filter(Objects::nonNull).distinct().forEach(path -> builder.append("import ").append(path).append(";").append("\n\n")); + + // 注解信息 + LocalDateTime now = LocalDateTime.now(); + String localDate = now.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + String localTime = now.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm")); + String author = "/**\n * @author {0}\n * @date {1} {2}\n **/"; + String format = MessageFormat.format(author, prop.getAuthor(), localDate, localTime); + builder.append(format).append("\n"); + // 类名 + builder.append("@Data").append("\n"); + builder.append("public class ").append(prop.getClassName()).append("{\n"); + + // 构造函数 + builder.append(" ").append("public ").append(prop.getClassName()).append("(){}\n"); + + // 生成属性 + aliasNodes.forEach(node -> builder.append(" ").append("private ").append(merge.getOrDefault(node.getType(), node.getType())).append(" ").append(node.getName()).append(";\n")); + + // 生成静态属性类 + classNodes.forEach(clazzNode -> { + builder.append(" ").append("@Data").append("\n"); + builder.append(" ").append("public static class ").append(clazzNode.getAlias()).append("{\n"); + List files = clazzNode.getNodes(); + files.forEach(node -> builder.append(" ").append(" ").append("private ").append(node.getType()).append(" ").append(node.getName()).append(";\n")); + builder.append(" ").append("}\n"); + }); + builder.append("}\n"); + + + Content content = new Content(); + content.setPath(prop.getPackagePath()); + content.setSource(prop.getSource()); + content.setContent(builder.toString()); + + return content; + } + + protected abstract void dealHandler(String source, List fieldNodes, List classNodes); + + private void fillAllType(List jsonNodes, List typeList) { + if (CollectionUtils.isEmpty(jsonNodes)) { + return; + } + for (AliasNode jsonNode : jsonNodes) { + typeList.add(jsonNode.getAbsolutePath()); + fillAllType(jsonNode.getNodes(), typeList); + } + + } + + + protected String upFirstChar(String name) { + String first = name.substring(0, 1); + return name.replaceFirst(first, first.toUpperCase()); + } + + + private Map merge(List classNodes) { + Map mapping = new HashMap<>(); + Map hashTable = new HashMap<>(); + Iterator iterator = classNodes.iterator(); + while (iterator.hasNext()) { + AliasNode next = iterator.next(); + int hash = next.getNodes().stream().map(AliasNode::getName).sorted(String::compareTo) + .collect(Collectors.joining()).hashCode(); + // 如果存在 + if (hashTable.containsKey(hash)) { + mapping.put(next.getType(), hashTable.get(hash)); + if (Boolean.TRUE.equals(next.getArrayFlag())) { + mapping.put(next.getType(), "List<" + hashTable.get(hash) + ">"); + } + iterator.remove(); + } else { + hashTable.put(hash, next.getType()); + } + } + // 如果遇到名称相同的 直接组合成大对象 + Iterator duplicate = classNodes.iterator(); + Map duplicateMap = new HashMap<>(); + while (duplicate.hasNext()) { + AliasNode next = duplicate.next(); + if (duplicateMap.containsKey(next.getType())) { + duplicate.remove(); + List nodes = duplicateMap.get(next.getType()).getNodes(); + Set collect = nodes.stream().map(AliasNode::getName).collect(Collectors.toSet()); + next.getNodes().stream().filter(no -> !collect.contains(no.getName())).forEach(nodes::add); + } else { + duplicateMap.put(next.getType(), next); + } + } + + return mapping; + } +} diff --git a/alis-generator-core/src/main/java/org/alis/generator/factory/JsonGenerator.java b/alis-generator-core/src/main/java/org/alis/generator/factory/JsonGenerator.java index 1f156f6..251cb7e 100644 --- a/alis-generator-core/src/main/java/org/alis/generator/factory/JsonGenerator.java +++ b/alis-generator-core/src/main/java/org/alis/generator/factory/JsonGenerator.java @@ -3,30 +3,23 @@ package org.alis.generator.factory; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; -import org.alis.generator.domain.model.Content; -import org.alis.generator.domain.model.ContextConfig; -import org.alis.generator.domain.model.JsonNode; +import org.alis.generator.domain.model.AliasNode; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.text.MessageFormat; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.stream.Collectors; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * @author lc * @date 2023/11/22 17:01 */ -public class JsonGenerator implements Generator { - @Override - public Content generator(ContextConfig prop) { - String source = prop.getSource().trim(); - if (!StringUtils.hasLength(source)) { - return null; - } +public class JsonGenerator extends AbstractGenerator { + + + public void dealHandler(String source, List fieldNodes, List classNodes) { JSONObject jsonObject; // 翻译source if (StringUtils.startsWithIgnoreCase(source, "[")) { @@ -36,75 +29,21 @@ public class JsonGenerator implements Generator { } else { jsonObject = JSONUtil.parseObj(source); } - // 使用组合模式 - List fieldNodes = new ArrayList<>(); - // 匿名内部类 - List classNodes = new ArrayList<>(); dealMap(jsonObject, fieldNodes, classNodes); - - // merge删除对应的类 - Map merge = merge(classNodes); - - // 生成class 文件 - StringBuilder builder = new StringBuilder(); - - // 包路径 - builder.append("package ").append(prop.getPackagePath()).append(";").append("\n\n"); - // 注解的包 - builder.append("import lombok.Data;").append("\n"); - // 导入所有的包 - List importList = new ArrayList<>(); - fillAllType(fieldNodes, importList); - importList.stream().filter(Objects::nonNull).distinct().forEach(path -> builder.append("import ").append(path).append(";").append("\n\n")); - - // 注解信息 - LocalDateTime now = LocalDateTime.now(); - String localDate = now.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); - String localTime = now.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm")); - String author = "/**\n * @author {0}\n * @date {1} {2}\n **/"; - String format = MessageFormat.format(author, prop.getAuthor(), localDate, localTime); - builder.append(format).append("\n"); - // 类名 - builder.append("@Data").append("\n"); - builder.append("public class ").append(prop.getClassName()).append("{\n"); - - // 构造函数 - builder.append(" ").append("public ").append(prop.getClassName()).append("(){}\n"); - - // 生成属性 - fieldNodes.forEach(node -> builder.append(" ").append("private ").append(merge.getOrDefault(node.getType(), node.getType())).append(" ").append(node.getName()).append(";\n")); - - // 生成静态属性类 - classNodes.forEach(clazzNode -> { - builder.append(" ").append("@Data").append("\n"); - builder.append(" ").append("public static class ").append(clazzNode.getAlias()).append("{\n"); - List files = clazzNode.getNodes(); - files.forEach(node -> builder.append(" ").append(" ").append("private ").append(node.getType()).append(" ").append(node.getName()).append(";\n")); - builder.append(" ").append("}\n"); - }); - builder.append("}\n"); - - - Content content = new Content(); - content.setPath(prop.getPackagePath()); - content.setSource(prop.getSource()); - content.setContent(builder.toString()); - - return content; } - private void dealMap(JSONObject jsonObject, List fields, List classNodes) { + private void dealMap(JSONObject jsonObject, List fields, List classNodes) { for (Map.Entry entry : jsonObject.entrySet()) { Object value = entry.getValue(); String name = entry.getKey(); - JsonNode node = new JsonNode(); + AliasNode node = new AliasNode(); node.setAlias(name); node.setName(name); node.setType(value.getClass().getSimpleName()); node.setAbsolutePath(value.getClass().getName()); - List nodes = new ArrayList<>(); + List nodes = new ArrayList<>(); if (value instanceof JSONObject) { String className = upFirstChar(name) + "DTO"; @@ -145,58 +84,4 @@ public class JsonGenerator implements Generator { } - private void fillAllType(List jsonNodes, List typeList) { - if (CollectionUtils.isEmpty(jsonNodes)) { - return; - } - for (JsonNode jsonNode : jsonNodes) { - typeList.add(jsonNode.getAbsolutePath()); - fillAllType(jsonNode.getNodes(), typeList); - } - - } - - - private String upFirstChar(String name) { - String first = name.substring(0, 1); - return name.replaceFirst(first, first.toUpperCase()); - } - - - private Map merge(List classNodes) { - Map mapping = new HashMap<>(); - Map hashTable = new HashMap<>(); - Iterator iterator = classNodes.iterator(); - while (iterator.hasNext()) { - JsonNode next = iterator.next(); - int hash = next.getNodes().stream().map(JsonNode::getName).sorted(String::compareTo) - .collect(Collectors.joining()).hashCode(); - // 如果存在 - if (hashTable.containsKey(hash)) { - mapping.put(next.getType(), hashTable.get(hash)); - if (Boolean.TRUE.equals(next.getArrayFlag())) { - mapping.put(next.getType(), "List<" + hashTable.get(hash) + ">"); - } - iterator.remove(); - } else { - hashTable.put(hash, next.getType()); - } - } - // 如果遇到名称相同的 直接组合成大对象 - Iterator duplicate = classNodes.iterator(); - Map duplicateMap = new HashMap<>(); - while (duplicate.hasNext()) { - JsonNode next = duplicate.next(); - if (duplicateMap.containsKey(next.getType())) { - duplicate.remove(); - List nodes = duplicateMap.get(next.getType()).getNodes(); - Set collect = nodes.stream().map(JsonNode::getName).collect(Collectors.toSet()); - next.getNodes().stream().filter(no -> !collect.contains(no.getName())).forEach(nodes::add); - } else { - duplicateMap.put(next.getType(), next); - } - } - - return mapping; - } } diff --git a/alis-generator-core/src/main/java/org/alis/generator/factory/XmlGenerator.java b/alis-generator-core/src/main/java/org/alis/generator/factory/XmlGenerator.java new file mode 100644 index 0000000..a0d2f14 --- /dev/null +++ b/alis-generator-core/src/main/java/org/alis/generator/factory/XmlGenerator.java @@ -0,0 +1,17 @@ +package org.alis.generator.factory; + +import org.alis.generator.domain.model.AliasNode; + +import java.util.List; + +/** + * @author lc + * @date 2023/11/23 18:43 + **/ +public class XmlGenerator extends AbstractGenerator { + + @Override + protected void dealHandler(String source, List fieldNodes, List classNodes) { + + } +}