完成抽象

main
luochuan 12 months ago
parent 9ae0250410
commit 7004c83a00

@ -10,11 +10,11 @@ import java.util.List;
* @date 2023/11/22 18:39 * @date 2023/11/22 18:39
*/ */
@Data @Data
public class JsonNode { public class AliasNode {
private String name; private String name;
private String alias; private String alias;
private String type; private String type;
private String absolutePath; private String absolutePath;
private List<JsonNode> nodes; private List<AliasNode> nodes;
private Boolean arrayFlag=Boolean.FALSE; private Boolean arrayFlag=Boolean.FALSE;
} }

@ -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<AliasNode> aliasNodes = new ArrayList<>();
// 匿名内部类
List<AliasNode> classNodes = new ArrayList<>();
dealHandler(prop.getSource(), aliasNodes, classNodes);
// merge删除对应的类
Map<String, String> 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<String> 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<AliasNode> 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<AliasNode> fieldNodes, List<AliasNode> classNodes);
private void fillAllType(List<AliasNode> jsonNodes, List<String> 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<String, String> merge(List<AliasNode> classNodes) {
Map<String, String> mapping = new HashMap<>();
Map<Integer, String> hashTable = new HashMap<>();
Iterator<AliasNode> 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<AliasNode> duplicate = classNodes.iterator();
Map<String, AliasNode> duplicateMap = new HashMap<>();
while (duplicate.hasNext()) {
AliasNode next = duplicate.next();
if (duplicateMap.containsKey(next.getType())) {
duplicate.remove();
List<AliasNode> nodes = duplicateMap.get(next.getType()).getNodes();
Set<String> 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;
}
}

@ -3,30 +3,23 @@ package org.alis.generator.factory;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import org.alis.generator.domain.model.Content; import org.alis.generator.domain.model.AliasNode;
import org.alis.generator.domain.model.ContextConfig;
import org.alis.generator.domain.model.JsonNode;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.text.MessageFormat; import java.util.ArrayList;
import java.time.LocalDateTime; import java.util.List;
import java.time.format.DateTimeFormatter; import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/** /**
* @author lc * @author lc
* @date 2023/11/22 17:01 * @date 2023/11/22 17:01
*/ */
public class JsonGenerator implements Generator { public class JsonGenerator extends AbstractGenerator {
@Override
public Content generator(ContextConfig prop) {
String source = prop.getSource().trim(); public void dealHandler(String source, List<AliasNode> fieldNodes, List<AliasNode> classNodes) {
if (!StringUtils.hasLength(source)) {
return null;
}
JSONObject jsonObject; JSONObject jsonObject;
// 翻译source // 翻译source
if (StringUtils.startsWithIgnoreCase(source, "[")) { if (StringUtils.startsWithIgnoreCase(source, "[")) {
@ -36,75 +29,21 @@ public class JsonGenerator implements Generator {
} else { } else {
jsonObject = JSONUtil.parseObj(source); jsonObject = JSONUtil.parseObj(source);
} }
// 使用组合模式
List<JsonNode> fieldNodes = new ArrayList<>();
// 匿名内部类
List<JsonNode> classNodes = new ArrayList<>();
dealMap(jsonObject, fieldNodes, classNodes); dealMap(jsonObject, fieldNodes, classNodes);
// merge删除对应的类
Map<String, String> 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<String> 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<JsonNode> 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<JsonNode> fields, List<JsonNode> classNodes) { private void dealMap(JSONObject jsonObject, List<AliasNode> fields, List<AliasNode> classNodes) {
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) { for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
Object value = entry.getValue(); Object value = entry.getValue();
String name = entry.getKey(); String name = entry.getKey();
JsonNode node = new JsonNode(); AliasNode node = new AliasNode();
node.setAlias(name); node.setAlias(name);
node.setName(name); node.setName(name);
node.setType(value.getClass().getSimpleName()); node.setType(value.getClass().getSimpleName());
node.setAbsolutePath(value.getClass().getName()); node.setAbsolutePath(value.getClass().getName());
List<JsonNode> nodes = new ArrayList<>(); List<AliasNode> nodes = new ArrayList<>();
if (value instanceof JSONObject) { if (value instanceof JSONObject) {
String className = upFirstChar(name) + "DTO"; String className = upFirstChar(name) + "DTO";
@ -145,58 +84,4 @@ public class JsonGenerator implements Generator {
} }
private void fillAllType(List<JsonNode> jsonNodes, List<String> 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<String, String> merge(List<JsonNode> classNodes) {
Map<String, String> mapping = new HashMap<>();
Map<Integer, String> hashTable = new HashMap<>();
Iterator<JsonNode> 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<JsonNode> duplicate = classNodes.iterator();
Map<String, JsonNode> duplicateMap = new HashMap<>();
while (duplicate.hasNext()) {
JsonNode next = duplicate.next();
if (duplicateMap.containsKey(next.getType())) {
duplicate.remove();
List<JsonNode> nodes = duplicateMap.get(next.getType()).getNodes();
Set<String> 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;
}
} }

@ -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<AliasNode> fieldNodes, List<AliasNode> classNodes) {
}
}
Loading…
Cancel
Save