mirror of https://gitee.com/makejava/EasyCode.git
彻底废除旧版表配置服务,优化未知类型的添加方式
This commit is contained in:
parent
8f080783ff
commit
0192ae2f91
|
@ -1,14 +1,34 @@
|
|||
package com.sjhy.plugin.actions;
|
||||
|
||||
import com.intellij.database.model.DasColumn;
|
||||
import com.intellij.database.psi.DbTable;
|
||||
import com.intellij.database.util.DasUtil;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sjhy.plugin.service.TableInfoService;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.sjhy.plugin.dict.GlobalDict;
|
||||
import com.sjhy.plugin.entity.TypeMapper;
|
||||
import com.sjhy.plugin.enums.MatchType;
|
||||
import com.sjhy.plugin.tool.CacheDataUtils;
|
||||
import com.sjhy.plugin.tool.CurrGroupUtils;
|
||||
import com.sjhy.plugin.tool.StringUtils;
|
||||
import com.sjhy.plugin.ui.SelectSavePath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* 代码生成菜单
|
||||
*
|
||||
|
@ -39,11 +59,103 @@ public class MainAction extends AnAction {
|
|||
}
|
||||
|
||||
// 校验类型映射
|
||||
if (!TableInfoService.getInstance(project).typeValidator(CacheDataUtils.getInstance().getSelectDbTable())) {
|
||||
if (!typeValidator(project, CacheDataUtils.getInstance().getSelectDbTable())) {
|
||||
// 没通过不打开窗口
|
||||
return;
|
||||
}
|
||||
//开始处理
|
||||
new SelectSavePath(event.getProject()).show();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 类型校验,如果存在未知类型则引导用于去条件类型
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
private boolean typeValidator(Project project, DbTable dbTable) {
|
||||
// 处理所有列
|
||||
JBIterable<? extends DasColumn> columns = DasUtil.getColumns(dbTable);
|
||||
List<TypeMapper> typeMapperList = CurrGroupUtils.getCurrTypeMapperGroup().getElementList();
|
||||
|
||||
// 简单的记录报错弹窗次数,避免重复报错
|
||||
Set<String> errorCount = new HashSet<>();
|
||||
|
||||
FLAG:
|
||||
for (DasColumn column : columns) {
|
||||
String typeName = column.getDataType().getSpecification();
|
||||
for (TypeMapper typeMapper : typeMapperList) {
|
||||
try {
|
||||
if (typeMapper.getMatchType() == MatchType.ORDINARY) {
|
||||
if (typeName.equalsIgnoreCase(typeMapper.getColumnType())) {
|
||||
continue FLAG;
|
||||
}
|
||||
} else {
|
||||
// 不区分大小写的正则匹配模式
|
||||
if (Pattern.compile(typeMapper.getColumnType(), Pattern.CASE_INSENSITIVE).matcher(typeName).matches()) {
|
||||
continue FLAG;
|
||||
}
|
||||
}
|
||||
} catch (PatternSyntaxException e) {
|
||||
if (!errorCount.contains(typeMapper.getColumnType())) {
|
||||
Messages.showWarningDialog(
|
||||
"类型映射《" + typeMapper.getColumnType() + "》存在语法错误,请及时修正。报错信息:" + e.getMessage(),
|
||||
GlobalDict.TITLE_INFO);
|
||||
errorCount.add(typeMapper.getColumnType());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 没找到类型,提示用户选择输入类型
|
||||
new Dialog(project, typeName).showAndGet();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class Dialog extends DialogWrapper {
|
||||
|
||||
private String typeName;
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private ComboBox<String> comboBox;
|
||||
|
||||
protected Dialog(@Nullable Project project, String typeName) {
|
||||
super(project);
|
||||
this.typeName = typeName;
|
||||
this.initPanel();
|
||||
}
|
||||
|
||||
private void initPanel() {
|
||||
setTitle(GlobalDict.TITLE_INFO);
|
||||
String msg = String.format("数据库类型%s,没有找到映射关系,请输入想转换的类型?", typeName);
|
||||
JLabel label = new JLabel(msg);
|
||||
this.mainPanel = new JPanel(new BorderLayout());
|
||||
this.mainPanel.setBorder(JBUI.Borders.empty(5, 10, 7, 10));
|
||||
mainPanel.add(label, BorderLayout.NORTH);
|
||||
this.comboBox = new ComboBox<>(GlobalDict.DEFAULT_JAVA_TYPE_LIST);
|
||||
this.comboBox.setEditable(true);
|
||||
this.mainPanel.add(this.comboBox, BorderLayout.CENTER);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable JComponent createCenterPanel() {
|
||||
return this.mainPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
super.doOKAction();
|
||||
String selectedItem = (String) this.comboBox.getSelectedItem();
|
||||
if (StringUtils.isEmpty(selectedItem)) {
|
||||
return;
|
||||
}
|
||||
TypeMapper typeMapper = new TypeMapper();
|
||||
typeMapper.setMatchType(MatchType.ORDINARY);
|
||||
typeMapper.setJavaType(selectedItem);
|
||||
typeMapper.setColumnType(typeName);
|
||||
CurrGroupUtils.getCurrTypeMapperGroup().getElementList().add(typeMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.sjhy.plugin.dto;
|
|||
import com.intellij.database.model.DasColumn;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.sjhy.plugin.entity.TypeMapper;
|
||||
import com.sjhy.plugin.enums.MatchType;
|
||||
import com.sjhy.plugin.tool.CurrGroupUtils;
|
||||
import com.sjhy.plugin.tool.DocCommentUtils;
|
||||
import com.sjhy.plugin.tool.NameUtils;
|
||||
|
@ -42,18 +43,15 @@ public class ColumnInfoDTO {
|
|||
|
||||
private String getJavaType(String dbType) {
|
||||
for (TypeMapper typeMapper : CurrGroupUtils.getCurrTypeMapperGroup().getElementList()) {
|
||||
switch (typeMapper.getMatchType()) {
|
||||
case REGEX:
|
||||
if (Pattern.compile(typeMapper.getColumnType()).matcher(dbType).matches()) {
|
||||
return typeMapper.getJavaType();
|
||||
}
|
||||
break;
|
||||
case ORDINARY:
|
||||
default:
|
||||
if (typeMapper.getMatchType() == MatchType.ORDINARY) {
|
||||
if (dbType.equalsIgnoreCase(typeMapper.getColumnType())) {
|
||||
return typeMapper.getJavaType();
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
// 不区分大小写的正则匹配模式
|
||||
if (Pattern.compile(typeMapper.getColumnType(), Pattern.CASE_INSENSITIVE).matcher(dbType).matches()) {
|
||||
return typeMapper.getJavaType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "java.lang.Object";
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.sjhy.plugin.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 生成选项
|
||||
*
|
||||
* @author makejava
|
||||
* @version 1.0.0
|
||||
* @date 2021/08/17 09:08
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class GenerateOptions {
|
||||
/**
|
||||
* 实体类模式
|
||||
*/
|
||||
private Boolean entityModel;
|
||||
/**
|
||||
* 统一配置
|
||||
*/
|
||||
private Boolean unifiedConfig;
|
||||
/**
|
||||
* 重新格式化代码
|
||||
*/
|
||||
private Boolean reFormat;
|
||||
/**
|
||||
* 提示选是
|
||||
*/
|
||||
private Boolean titleSure;
|
||||
/**
|
||||
* 提示选否
|
||||
*/
|
||||
private Boolean titleRefuse;
|
||||
}
|
|
@ -22,5 +22,9 @@ public class Callback {
|
|||
/**
|
||||
* 是否重新格式化代码
|
||||
*/
|
||||
private boolean reformat = true;
|
||||
private Boolean reformat;
|
||||
/**
|
||||
* 是否写入文件,部分模块不需要写入文件。例如debug.json模板
|
||||
*/
|
||||
private Boolean writeFile;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VfsUtil;
|
|||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.sjhy.plugin.dto.GenerateOptions;
|
||||
import com.sjhy.plugin.tool.CompareFileUtils;
|
||||
import com.sjhy.plugin.tool.FileUtils;
|
||||
import com.sjhy.plugin.tool.MessageDialogUtils;
|
||||
|
@ -36,49 +37,36 @@ public class SaveFile {
|
|||
* 所属项目
|
||||
*/
|
||||
private Project project;
|
||||
/**
|
||||
* 文件保存目录
|
||||
*/
|
||||
private String path;
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String fileName;
|
||||
/**
|
||||
* 文件内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 是否需要重新格式化代码
|
||||
*/
|
||||
private boolean reformat;
|
||||
/**
|
||||
* 是否显示操作提示
|
||||
*/
|
||||
private boolean operateTitle;
|
||||
/**
|
||||
* 文件工具类
|
||||
*/
|
||||
private FileUtils fileUtils = FileUtils.getInstance();
|
||||
/**
|
||||
* 回调对象
|
||||
*/
|
||||
private Callback callback;
|
||||
/**
|
||||
* 生成配置
|
||||
*/
|
||||
private GenerateOptions generateOptions;
|
||||
|
||||
/**
|
||||
* 构建对象
|
||||
* 保存文件
|
||||
*
|
||||
* @param project 项目对象
|
||||
* @param path 绝对路径
|
||||
* @param fileName 文件名
|
||||
* @param content 文件内容
|
||||
* @param reformat 是否重新格式化代码
|
||||
* @param operateTitle 操作提示
|
||||
* @param project 项目
|
||||
* @param content 内容
|
||||
* @param callback 回调
|
||||
* @param generateOptions 生成选项
|
||||
*/
|
||||
public SaveFile(@NonNull Project project, @NonNull String path, @NonNull String fileName, String content, boolean reformat, boolean operateTitle) {
|
||||
this.path = path;
|
||||
public SaveFile(@NonNull Project project, @NonNull String content, @NonNull Callback callback, @NonNull GenerateOptions generateOptions) {
|
||||
this.project = project;
|
||||
this.fileName = fileName;
|
||||
LOG.assertTrue(content != null);
|
||||
this.callback = callback;
|
||||
this.content = content.replace("\r", "");
|
||||
this.reformat = reformat;
|
||||
this.operateTitle = operateTitle;
|
||||
this.generateOptions = generateOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +82,7 @@ public class SaveFile {
|
|||
}
|
||||
// 路径对比,判断项目路径是否为文件保存路径的子路径
|
||||
String projectPath = handlerPath(baseDir.getPath());
|
||||
String tmpFilePath = handlerPath(this.path);
|
||||
String tmpFilePath = handlerPath(callback.getSavePath());
|
||||
if (tmpFilePath.length() > projectPath.length()) {
|
||||
if (!"/".equals(tmpFilePath.substring(projectPath.length(), projectPath.length() + 1))) {
|
||||
return false;
|
||||
|
@ -133,13 +121,16 @@ public class SaveFile {
|
|||
* 通过IDEA自带的Psi文件方式写入
|
||||
*/
|
||||
public void write() {
|
||||
if (!Boolean.TRUE.equals(callback.getWriteFile())) {
|
||||
return;
|
||||
}
|
||||
// 判断目录是否存在
|
||||
VirtualFile baseDir = ProjectUtils.getBaseDir(project);
|
||||
if (baseDir == null) {
|
||||
throw new IllegalStateException("项目基本路径不存在");
|
||||
}
|
||||
// 处理保存路径
|
||||
String savePath = handlerPath(this.path, false);
|
||||
String savePath = handlerPath(callback.getSavePath(), false);
|
||||
if (isProjectFile()) {
|
||||
// 删除保存路径的前面部分
|
||||
savePath = savePath.substring(handlerPath(baseDir.getPath()).length());
|
||||
|
@ -165,7 +156,7 @@ public class SaveFile {
|
|||
if (directory == null) {
|
||||
return;
|
||||
}
|
||||
VirtualFile psiFile = directory.findChild(this.fileName);
|
||||
VirtualFile psiFile = directory.findChild(callback.getFileName());
|
||||
// 保存或覆盖
|
||||
saveOrReplaceFile(psiFile, directory);
|
||||
}
|
||||
|
@ -181,12 +172,19 @@ public class SaveFile {
|
|||
return saveDir;
|
||||
}
|
||||
// 尝试创建目录
|
||||
String msg = String.format("Directory %s Not Found, Confirm Create?", this.path);
|
||||
if (this.operateTitle && !MessageDialogUtils.yesNo(project, msg)) {
|
||||
return null;
|
||||
}
|
||||
String msg = String.format("Directory %s Not Found, Confirm Create?", callback.getSavePath());
|
||||
if (generateOptions.getTitleSure()) {
|
||||
saveDir = fileUtils.createChildDirectory(project, baseDir, savePath);
|
||||
return saveDir;
|
||||
} else if (generateOptions.getTitleRefuse()) {
|
||||
return null;
|
||||
} else {
|
||||
if (MessageDialogUtils.yesNo(project, msg)) {
|
||||
saveDir = fileUtils.createChildDirectory(project, baseDir, savePath);
|
||||
return saveDir;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,16 +198,22 @@ public class SaveFile {
|
|||
Document document;
|
||||
// 文件不存在直接创建
|
||||
if (file == null) {
|
||||
file = fileUtils.createChildFile(project, directory, this.fileName);
|
||||
file = fileUtils.createChildFile(project, directory, callback.getFileName());
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
document = coverFile(file);
|
||||
} else {
|
||||
// 提示覆盖文件
|
||||
if (operateTitle) {
|
||||
if (generateOptions.getTitleSure()) {
|
||||
// 默认选是
|
||||
document = coverFile(file);
|
||||
} else if (generateOptions.getTitleRefuse()) {
|
||||
// 默认选否
|
||||
return;
|
||||
} else {
|
||||
String msg = String.format("File %s Exists, Select Operate Mode?", file.getPath());
|
||||
int result = MessageDialogUtils.yesNoCancel(project, msg, "Conver", "Compare", "Cancel");
|
||||
int result = MessageDialogUtils.yesNoCancel(project, msg, "Convert", "Compare", "Cancel");
|
||||
switch (result) {
|
||||
case Messages.YES:
|
||||
// 覆盖文件
|
||||
|
@ -218,7 +222,7 @@ public class SaveFile {
|
|||
case Messages.NO:
|
||||
// 对比代码时也格式化代码
|
||||
String newText = content;
|
||||
if (reformat) {
|
||||
if (Boolean.TRUE.equals(callback.getReformat())) {
|
||||
// 保留旧文件内容,用新文件覆盖旧文件执行格式化,然后再还原旧文件内容
|
||||
String oldText = getFileText(file);
|
||||
Document tmpDoc = coverFile(file);
|
||||
|
@ -231,20 +235,17 @@ public class SaveFile {
|
|||
// 还原旧文件
|
||||
coverFile(file, oldText);
|
||||
}
|
||||
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
|
||||
CompareFileUtils.showCompareWindow(project, file, new LightVirtualFile(fileName, fileType, newText));
|
||||
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(callback.getFileName());
|
||||
CompareFileUtils.showCompareWindow(project, file, new LightVirtualFile(callback.getFileName(), fileType, newText));
|
||||
return;
|
||||
case Messages.CANCEL:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 没有操作提示的情况下直接覆盖
|
||||
document = coverFile(file);
|
||||
}
|
||||
}
|
||||
// 执行代码格式化操作
|
||||
if (reformat) {
|
||||
if (Boolean.TRUE.equals(callback.getReformat())) {
|
||||
FileUtils.getInstance().reformatFile(project, file);
|
||||
}
|
||||
// 提交文档改动,并非VCS中的提交文件
|
||||
|
@ -278,6 +279,6 @@ public class SaveFile {
|
|||
* @return 覆盖后的文档对象
|
||||
*/
|
||||
private Document coverFile(VirtualFile file, String text) {
|
||||
return FileUtils.getInstance().writeFileContent(project, file, fileName, text);
|
||||
return FileUtils.getInstance().writeFileContent(project, file, callback.getFileName(), text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.sjhy.plugin.service;
|
|||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sjhy.plugin.dto.GenerateOptions;
|
||||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.entity.Template;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -27,14 +28,12 @@ public interface CodeGenerateService {
|
|||
}
|
||||
|
||||
/**
|
||||
* 生成代码,并自动保存到对应位置,使用统一配置
|
||||
* 生成
|
||||
*
|
||||
* @param templates 模板
|
||||
* @param unifiedConfig 是否使用统一配置
|
||||
* @param title 是否显示提示
|
||||
* @param entityMode
|
||||
* @param generateOptions 生成选项
|
||||
*/
|
||||
void generateByUnifiedConfig(Collection<Template> templates, boolean unifiedConfig, boolean title,
|
||||
boolean entityMode);
|
||||
void generate(Collection<Template> templates, GenerateOptions generateOptions);
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
package com.sjhy.plugin.service;
|
||||
|
||||
import com.intellij.database.psi.DbTable;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.tool.CollectionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表信息服务,Project级Service
|
||||
* 1.提供原始对象转包装对象服务
|
||||
* 2.提供表额外配置信息持久化服务
|
||||
*
|
||||
* @author makejava
|
||||
* @version 1.0.0
|
||||
* @since 2018/09/02 11:27
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface TableInfoService {
|
||||
/**
|
||||
* 获取实例对象
|
||||
* @param project 项目对象
|
||||
* @return 实例对象
|
||||
*/
|
||||
static TableInfoService getInstance(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, TableInfoService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过DbTable获取TableInfo
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
TableInfo getTableInfoByDbTable(DbTable dbTable);
|
||||
|
||||
/**
|
||||
* 通过DbTable获取TableInfo
|
||||
*
|
||||
* @param dbTables 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
default List<TableInfo> getTableInfoByDbTable(Collection<DbTable> dbTables) {
|
||||
if (CollectionUtil.isEmpty(dbTables)) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
List<TableInfo> tableInfoList = new ArrayList<>(dbTables.size());
|
||||
dbTables.forEach(dbTable -> tableInfoList.add(this.getTableInfoByDbTable(dbTable)));
|
||||
return tableInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表信息并加载配置信息
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
TableInfo getTableInfoAndConfig(DbTable dbTable);
|
||||
|
||||
/**
|
||||
* 获取表信息并加载配置信息
|
||||
*
|
||||
* @param dbTables 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
default List<TableInfo> getTableInfoAndConfig(Collection<DbTable> dbTables) {
|
||||
if (CollectionUtil.isEmpty(dbTables)) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
List<TableInfo> tableInfoList = new ArrayList<>(dbTables.size());
|
||||
dbTables.forEach(dbTable -> tableInfoList.add(this.getTableInfoAndConfig(dbTable)));
|
||||
return tableInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型校验,如果存在未知类型则引导用于去条件类型
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
boolean typeValidator(DbTable dbTable);
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*
|
||||
* @param tableInfo 表信息对象
|
||||
*/
|
||||
void save(TableInfo tableInfo);
|
||||
|
||||
/**
|
||||
* 获取表信息
|
||||
*/
|
||||
TableInfo getTableInfoByPsiClass(PsiClass psiClass);
|
||||
|
||||
/**
|
||||
* 从实体获取表信息包含配置
|
||||
*/
|
||||
TableInfo getTableInfoAndConfigByPsiClass(PsiClass selectPsiClass);
|
||||
|
||||
/**
|
||||
* 从实体获取表信息包含配置
|
||||
*/
|
||||
List<TableInfo> getTableInfoAndConfigByPsiClass(List<PsiClass> selectPsiClass);
|
||||
}
|
|
@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project;
|
|||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.sjhy.plugin.dict.GlobalDict;
|
||||
import com.sjhy.plugin.dto.GenerateOptions;
|
||||
import com.sjhy.plugin.dto.SettingsStorageDTO;
|
||||
import com.sjhy.plugin.entity.Callback;
|
||||
import com.sjhy.plugin.entity.SaveFile;
|
||||
|
@ -16,10 +17,11 @@ import com.sjhy.plugin.entity.TableInfo;
|
|||
import com.sjhy.plugin.entity.Template;
|
||||
import com.sjhy.plugin.service.CodeGenerateService;
|
||||
import com.sjhy.plugin.service.SettingsStorageService;
|
||||
import com.sjhy.plugin.service.TableInfoService;
|
||||
import com.sjhy.plugin.service.TableInfoSettingsService;
|
||||
import com.sjhy.plugin.tool.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author makejava
|
||||
|
@ -38,7 +40,7 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
/**
|
||||
* 表信息服务
|
||||
*/
|
||||
private TableInfoService tableInfoService;
|
||||
private TableInfoSettingsService tableInfoService;
|
||||
/**
|
||||
* 缓存数据工具
|
||||
*/
|
||||
|
@ -51,30 +53,27 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
public CodeGenerateServiceImpl(Project project) {
|
||||
this.project = project;
|
||||
this.moduleManager = ModuleManager.getInstance(project);
|
||||
this.tableInfoService = TableInfoService.getInstance(project);
|
||||
this.tableInfoService = TableInfoSettingsService.getInstance();
|
||||
this.cacheDataUtils = CacheDataUtils.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码,并自动保存到对应位置,使用统一配置
|
||||
* 生成
|
||||
*
|
||||
* @param templates 模板
|
||||
* @param unifiedConfig 是否使用统一配置
|
||||
* @param title 是否显示提示
|
||||
* @param entityMode 实体类生成模式
|
||||
* @param generateOptions 生成选项
|
||||
*/
|
||||
@Override
|
||||
public void generateByUnifiedConfig(Collection<Template> templates, boolean unifiedConfig, boolean title,
|
||||
boolean entityMode) {
|
||||
public void generate(Collection<Template> templates, GenerateOptions generateOptions) {
|
||||
// 获取选中表信息
|
||||
TableInfo selectedTableInfo;
|
||||
List<TableInfo> tableInfoList;
|
||||
if (!entityMode) {
|
||||
selectedTableInfo = tableInfoService.getTableInfoAndConfig(cacheDataUtils.getSelectDbTable());
|
||||
tableInfoList = tableInfoService.getTableInfoAndConfig(cacheDataUtils.getDbTableList());
|
||||
if (Boolean.TRUE.equals(generateOptions.getEntityModel())) {
|
||||
selectedTableInfo = tableInfoService.getTableInfo(cacheDataUtils.getSelectPsiClass());
|
||||
tableInfoList = cacheDataUtils.getPsiClassList().stream().map(item -> tableInfoService.getTableInfo(item)).collect(Collectors.toList());
|
||||
} else {
|
||||
selectedTableInfo = tableInfoService.getTableInfoAndConfigByPsiClass(cacheDataUtils.getSelectPsiClass());
|
||||
tableInfoList = tableInfoService.getTableInfoAndConfigByPsiClass(cacheDataUtils.getPsiClassList());
|
||||
selectedTableInfo = tableInfoService.getTableInfo(cacheDataUtils.getSelectDbTable());
|
||||
tableInfoList = cacheDataUtils.getDbTableList().stream().map(item -> tableInfoService.getTableInfo(item)).collect(Collectors.toList());
|
||||
}
|
||||
// 校验选中表的保存路径是否正确
|
||||
if (StringUtils.isEmpty(selectedTableInfo.getSavePath())) {
|
||||
|
@ -95,11 +94,11 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
tableInfo.setSavePackageName(finalSelectedTableInfo.getSavePackageName());
|
||||
tableInfo.setSavePath(finalSelectedTableInfo.getSavePath());
|
||||
tableInfo.setPreName(finalSelectedTableInfo.getPreName());
|
||||
tableInfoService.save(tableInfo);
|
||||
tableInfoService.saveTableInfo(tableInfo);
|
||||
}
|
||||
});
|
||||
// 如果使用统一配置,直接全部覆盖
|
||||
if (unifiedConfig) {
|
||||
if (Boolean.TRUE.equals(generateOptions.getUnifiedConfig())) {
|
||||
tableInfoList.forEach(tableInfo -> {
|
||||
tableInfo.setSaveModelName(finalSelectedTableInfo.getSaveModelName());
|
||||
tableInfo.setSavePackageName(finalSelectedTableInfo.getSavePackageName());
|
||||
|
@ -109,7 +108,7 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
}
|
||||
|
||||
// 生成代码
|
||||
generate(templates, tableInfoList, title);
|
||||
generate(templates, tableInfoList, generateOptions, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,21 +116,10 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
*
|
||||
* @param templates 模板
|
||||
* @param tableInfoList 表信息对象
|
||||
* @param title 是否显示提示
|
||||
*/
|
||||
private void generate(Collection<Template> templates, Collection<TableInfo> tableInfoList, boolean title) {
|
||||
generate(templates, tableInfoList, title, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码,并自动保存到对应位置
|
||||
*
|
||||
* @param templates 模板
|
||||
* @param tableInfoList 表信息对象
|
||||
* @param title 是否显示提示
|
||||
* @param generateOptions 生成配置
|
||||
* @param otherParam 其他参数
|
||||
*/
|
||||
public void generate(Collection<Template> templates, Collection<TableInfo> tableInfoList, boolean title, Map<String, Object> otherParam) {
|
||||
public void generate(Collection<Template> templates, Collection<TableInfo> tableInfoList, GenerateOptions generateOptions, Map<String, Object> otherParam) {
|
||||
if (CollectionUtil.isEmpty(templates) || CollectionUtil.isEmpty(tableInfoList)) {
|
||||
return;
|
||||
}
|
||||
|
@ -159,33 +147,28 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
// 设置模型路径与导包列表
|
||||
setModulePathAndImportList(param, tableInfo);
|
||||
// 设置额外代码生成服务
|
||||
param.put("generateService", new ExtraCodeGenerateUtils(this, tableInfo, title));
|
||||
param.put("generateService", new ExtraCodeGenerateUtils(this, tableInfo, generateOptions));
|
||||
for (Template template : templates) {
|
||||
Callback callback = new Callback();
|
||||
callback.setWriteFile(true);
|
||||
callback.setReformat(generateOptions.getReFormat());
|
||||
// 默认名称
|
||||
callback.setFileName(tableInfo.getName() + "Default.java");
|
||||
// 默认路径
|
||||
callback.setSavePath(tableInfo.getSavePath());
|
||||
// 设置回调对象
|
||||
param.put("callback", callback);
|
||||
// 开始生成
|
||||
String code = VelocityUtils.generate(template.getCode(), param);
|
||||
// 清除前面空格
|
||||
StringBuilder sb = new StringBuilder(code);
|
||||
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
|
||||
sb.deleteCharAt(0);
|
||||
}
|
||||
code = sb.toString();
|
||||
// 设置一个默认保存路径与默认文件名
|
||||
if (StringUtils.isEmpty(callback.getFileName())) {
|
||||
callback.setFileName(tableInfo.getName() + "Default.java");
|
||||
}
|
||||
if (StringUtils.isEmpty(callback.getSavePath())) {
|
||||
callback.setSavePath(tableInfo.getSavePath());
|
||||
}
|
||||
String path = callback.getSavePath();
|
||||
path = path.replace("\\", "/");
|
||||
// 针对相对路径进行处理
|
||||
if (path.startsWith(".")) {
|
||||
path = project.getBasePath() + path.substring(1);
|
||||
}
|
||||
new SaveFile(project, path, callback.getFileName(), code, callback.isReformat(), title).write();
|
||||
callback.setSavePath(path);
|
||||
new SaveFile(project, code, callback, generateOptions).write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +190,7 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
|
|||
setModulePathAndImportList(param, tableInfo);
|
||||
// 处理模板,注入全局变量
|
||||
TemplateUtils.addGlobalConfig(template);
|
||||
return VelocityUtils.generate(template.getCode(), param).trim();
|
||||
return VelocityUtils.generate(template.getCode(), param);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,541 +0,0 @@
|
|||
package com.sjhy.plugin.service.impl;
|
||||
|
||||
import com.intellij.database.model.DasColumn;
|
||||
import com.intellij.database.psi.DbTable;
|
||||
import com.intellij.database.util.DasUtil;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.sjhy.plugin.dict.GlobalDict;
|
||||
import com.sjhy.plugin.entity.ColumnInfo;
|
||||
import com.sjhy.plugin.entity.SaveFile;
|
||||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.entity.TypeMapper;
|
||||
import com.sjhy.plugin.service.TableInfoService;
|
||||
import com.sjhy.plugin.tool.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* @author makejava
|
||||
* @version 1.0.0
|
||||
* @since 2018/09/02 12:13
|
||||
*/
|
||||
public class TableInfoServiceImpl implements TableInfoService {
|
||||
|
||||
/**
|
||||
* 项目对象
|
||||
*/
|
||||
private Project project;
|
||||
|
||||
/**
|
||||
* 命名工具类
|
||||
*/
|
||||
private NameUtils nameUtils;
|
||||
/**
|
||||
* 文件工具类
|
||||
*/
|
||||
private FileUtils fileUtils;
|
||||
|
||||
public TableInfoServiceImpl(Project project) {
|
||||
this.project = project;
|
||||
this.nameUtils = NameUtils.getInstance();
|
||||
this.fileUtils = FileUtils.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过DbTable获取TableInfo
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
@Override
|
||||
public TableInfo getTableInfoByDbTable(DbTable dbTable) {
|
||||
if (dbTable == null) {
|
||||
return null;
|
||||
}
|
||||
TableInfo tableInfo = new TableInfo();
|
||||
// 设置原属对象
|
||||
tableInfo.setObj(dbTable);
|
||||
// 设置类名
|
||||
tableInfo.setName(nameUtils.getClassName(dbTable.getName()));
|
||||
// 设置注释
|
||||
tableInfo.setComment(dbTable.getComment());
|
||||
// 设置所有列
|
||||
tableInfo.setFullColumn(new ArrayList<>());
|
||||
// 设置主键列
|
||||
tableInfo.setPkColumn(new ArrayList<>());
|
||||
// 设置其他列
|
||||
tableInfo.setOtherColumn(new ArrayList<>());
|
||||
// 处理所有列
|
||||
JBIterable<? extends DasColumn> columns = DasUtil.getColumns(dbTable);
|
||||
for (DasColumn column : columns) {
|
||||
ColumnInfo columnInfo = new ColumnInfo();
|
||||
// 原始列对象
|
||||
columnInfo.setObj(column);
|
||||
// 列类型
|
||||
columnInfo.setType(getColumnType(column.getDataType().getSpecification()));
|
||||
// 短类型
|
||||
columnInfo.setShortType(nameUtils.getClsNameByFullName(columnInfo.getType()));
|
||||
// 列名
|
||||
columnInfo.setName(nameUtils.getJavaName(column.getName()));
|
||||
// 列注释
|
||||
columnInfo.setComment(column.getComment());
|
||||
// 扩展项
|
||||
columnInfo.setExt(new LinkedHashMap<>());
|
||||
// 添加到全部列
|
||||
tableInfo.getFullColumn().add(columnInfo);
|
||||
// 主键列添加到主键列,否则添加到其他列
|
||||
if (DasUtil.isPrimary(column)) {
|
||||
tableInfo.getPkColumn().add(columnInfo);
|
||||
} else {
|
||||
tableInfo.getOtherColumn().add(columnInfo);
|
||||
}
|
||||
}
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表信息并加载配置信息
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 表信息对象
|
||||
*/
|
||||
@Override
|
||||
public TableInfo getTableInfoAndConfig(DbTable dbTable) {
|
||||
TableInfo tableInfo = this.getTableInfoByDbTable(dbTable);
|
||||
// 加载配置
|
||||
String configFileName = getConfigFileName(tableInfo);
|
||||
this.loadConfig(tableInfo, configFileName);
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载单个表信息配置(用户自定义列与扩张选项)
|
||||
*
|
||||
* @param tableInfo 表信息对象
|
||||
* @param configFileName 配置文件名称
|
||||
*/
|
||||
private void loadConfig(TableInfo tableInfo, String configFileName) {
|
||||
if (tableInfo == null) {
|
||||
return;
|
||||
}
|
||||
// 读取配置文件中的表信息
|
||||
TableInfo tableInfoConfig = read(configFileName);
|
||||
// 返回空直接不处理
|
||||
if (tableInfoConfig == null) {
|
||||
return;
|
||||
}
|
||||
// 开始合并数据
|
||||
// 选择模型名称
|
||||
tableInfo.setSaveModelName(tableInfoConfig.getSaveModelName());
|
||||
// 选择的包名
|
||||
tableInfo.setSavePackageName(tableInfoConfig.getSavePackageName());
|
||||
// 选择的保存路径
|
||||
tableInfo.setSavePath(tableInfoConfig.getSavePath());
|
||||
// 选择的表名前缀
|
||||
tableInfo.setPreName(tableInfoConfig.getPreName());
|
||||
// 选择的模板组
|
||||
tableInfo.setTemplateGroupName(tableInfoConfig.getTemplateGroupName());
|
||||
|
||||
// 没有列时不处理
|
||||
if (CollectionUtil.isEmpty(tableInfoConfig.getFullColumn())) {
|
||||
return;
|
||||
}
|
||||
|
||||
int fullSize = tableInfoConfig.getFullColumn().size();
|
||||
// 所有列
|
||||
List<ColumnInfo> fullColumn = new ArrayList<>(fullSize);
|
||||
int pkSize = tableInfo.getPkColumn().size();
|
||||
// 主键列
|
||||
List<ColumnInfo> pkColumn = new ArrayList<>(pkSize);
|
||||
// 其他列
|
||||
List<ColumnInfo> otherColumn = new ArrayList<>(fullSize - pkSize);
|
||||
|
||||
for (ColumnInfo column : tableInfo.getFullColumn()) {
|
||||
boolean exists = false;
|
||||
for (ColumnInfo configColumn : tableInfoConfig.getFullColumn()) {
|
||||
if (Objects.equals(configColumn.getName(), column.getName())) {
|
||||
exists = true;
|
||||
// 覆盖空值
|
||||
if (configColumn.getType() == null) {
|
||||
configColumn.setType(column.getType());
|
||||
}
|
||||
// 短类型
|
||||
if (!StringUtils.isEmpty(column.getShortType())) {
|
||||
configColumn.setShortType(column.getShortType());
|
||||
} else if (!StringUtils.isEmpty(configColumn.getType())) {
|
||||
configColumn.setShortType(nameUtils.getClsNameByFullName(configColumn.getType()));
|
||||
}
|
||||
// 表注释覆盖
|
||||
if (configColumn.getComment() == null) {
|
||||
configColumn.setComment(column.getComment());
|
||||
}
|
||||
// 列对象覆盖
|
||||
configColumn.setObj(column.getObj());
|
||||
|
||||
// 添加至新列表中
|
||||
fullColumn.add(configColumn);
|
||||
// 是否为主键
|
||||
if (configColumn.getObj() != null) {
|
||||
if (DasUtil.isPrimary(configColumn.getObj())) {
|
||||
pkColumn.add(configColumn);
|
||||
} else {
|
||||
otherColumn.add(configColumn);
|
||||
}
|
||||
} else {
|
||||
boolean isPk = tableInfo.getPkColumn() != null
|
||||
&& tableInfo.getPkColumn().stream()
|
||||
.anyMatch(c -> Objects.equals(c.getName(), column.getName()));
|
||||
if (isPk) {
|
||||
pkColumn.add(configColumn);
|
||||
} else {
|
||||
otherColumn.add(configColumn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 新增的列
|
||||
if (!exists) {
|
||||
fullColumn.add(column);
|
||||
}
|
||||
}
|
||||
// 添加附加列
|
||||
for (ColumnInfo configColumn : tableInfoConfig.getFullColumn()) {
|
||||
if (Boolean.TRUE.equals(configColumn.getCustom())) {
|
||||
fullColumn.add(configColumn);
|
||||
}
|
||||
}
|
||||
|
||||
// 全部覆盖
|
||||
tableInfo.setFullColumn(fullColumn);
|
||||
tableInfo.setPkColumn(pkColumn);
|
||||
tableInfo.setOtherColumn(otherColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过映射获取对应的java类型类型名称
|
||||
*
|
||||
* @param typeName 列类型
|
||||
* @return java类型
|
||||
*/
|
||||
private String getColumnType(String typeName) {
|
||||
for (TypeMapper typeMapper : CurrGroupUtils.getCurrTypeMapperGroup().getElementList()) {
|
||||
// 不区分大小写进行类型转换
|
||||
if (Pattern.compile(typeMapper.getColumnType(), Pattern.CASE_INSENSITIVE).matcher(typeName).matches()) {
|
||||
return typeMapper.getJavaType();
|
||||
}
|
||||
}
|
||||
// 没找到直接返回Object
|
||||
return "java.lang.Object";
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型校验,如果存在未知类型则引导用于去条件类型
|
||||
*
|
||||
* @param dbTable 原始表对象
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
@Override
|
||||
public boolean typeValidator(DbTable dbTable) {
|
||||
// 处理所有列
|
||||
JBIterable<? extends DasColumn> columns = DasUtil.getColumns(dbTable);
|
||||
List<TypeMapper> typeMapperList = CurrGroupUtils.getCurrTypeMapperGroup().getElementList();
|
||||
|
||||
// 简单的记录报错弹窗次数,避免重复报错
|
||||
Set<String> errorCount = new HashSet<>();
|
||||
|
||||
FLAG:
|
||||
for (DasColumn column : columns) {
|
||||
String typeName = column.getDataType().getSpecification();
|
||||
for (TypeMapper typeMapper : typeMapperList) {
|
||||
try {
|
||||
// 不区分大小写查找类型
|
||||
if (Pattern.compile(typeMapper.getColumnType(), Pattern.CASE_INSENSITIVE).matcher(typeName)
|
||||
.matches()) {
|
||||
continue FLAG;
|
||||
}
|
||||
} catch (PatternSyntaxException e) {
|
||||
if (!errorCount.contains(typeMapper.getColumnType())) {
|
||||
Messages.showWarningDialog(
|
||||
"类型映射《" + typeMapper.getColumnType() + "》存在语法错误,请及时修正。报错信息:" + e.getMessage(),
|
||||
GlobalDict.TITLE_INFO);
|
||||
errorCount.add(typeMapper.getColumnType());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 没找到类型,引导用户去添加类型
|
||||
if (MessageDialogUtils.yesNo(project, String.format("数据库类型%s,没有找到映射关系,是否去添加?", typeName))) {
|
||||
ShowSettingsUtil.getInstance().showSettingsDialog(project, "Type Mapper");
|
||||
return false;
|
||||
}
|
||||
// 用户取消添加
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*
|
||||
* @param tableInfo 表信息对象
|
||||
*/
|
||||
@Override
|
||||
public void save(TableInfo tableInfo) {
|
||||
// 获取未修改前的原数据
|
||||
TableInfo oldTableInfo;
|
||||
if (tableInfo.getObj() != null) {
|
||||
oldTableInfo = getTableInfoByDbTable(tableInfo.getObj());
|
||||
} else {
|
||||
oldTableInfo = getTableInfoByPsiClass(tableInfo.getPsiClassObj());
|
||||
}
|
||||
// 克隆对象,防止串改,同时原始对象丢失
|
||||
tableInfo = CloneUtils.cloneByJson(tableInfo, false);
|
||||
//排除部分字段,这些字段不进行保存
|
||||
tableInfo.setOtherColumn(null);
|
||||
tableInfo.setPkColumn(null);
|
||||
// 获取迭代器
|
||||
Iterator<ColumnInfo> columnIterable = tableInfo.getFullColumn().iterator();
|
||||
while (columnIterable.hasNext()) {
|
||||
Iterator<ColumnInfo> oldColumnIterable = oldTableInfo.getFullColumn().iterator();
|
||||
// 新列
|
||||
ColumnInfo columnInfo = columnIterable.next();
|
||||
// 是否存在
|
||||
boolean exists = false;
|
||||
while (oldColumnIterable.hasNext()) {
|
||||
ColumnInfo oldColumnInfo = oldColumnIterable.next();
|
||||
// 不同列直接返回跳过
|
||||
if (!Objects.equals(columnInfo.getName(), oldColumnInfo.getName())) {
|
||||
continue;
|
||||
}
|
||||
// 类型排除
|
||||
if (Objects.equals(columnInfo.getType(), oldColumnInfo.getType())) {
|
||||
columnInfo.setType(null);
|
||||
}
|
||||
// 注释排除
|
||||
if (Objects.equals(columnInfo.getComment(), oldColumnInfo.getComment())) {
|
||||
columnInfo.setComment(null);
|
||||
}
|
||||
// 不保存短类型
|
||||
columnInfo.setShortType(null);
|
||||
// 列存在,进行处理
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
// 扩展项不能为空
|
||||
if (columnInfo.getExt() == null) {
|
||||
columnInfo.setExt(new LinkedHashMap<>());
|
||||
}
|
||||
// 已经不存在的非自定义列直接删除
|
||||
if (!exists && !columnInfo.getCustom()) {
|
||||
columnIterable.remove();
|
||||
}
|
||||
}
|
||||
// 获取优雅格式的JSON字符串
|
||||
String content = null;
|
||||
try {
|
||||
content = JSON.toJsonByFormat(tableInfo);
|
||||
} catch (Exception e) {
|
||||
ExceptionUtil.rethrow(e);
|
||||
}
|
||||
if (content == null) {
|
||||
Messages.showWarningDialog("保存失败,JSON序列化错误。", GlobalDict.TITLE_INFO);
|
||||
return;
|
||||
}
|
||||
// 获取或创建保存目录
|
||||
VirtualFile dir = getEasyCodeConfigDirectory(project);
|
||||
if (dir == null) {
|
||||
return;
|
||||
}
|
||||
// 获取保存文件
|
||||
new SaveFile(project, dir.getPath(), getConfigFileName(oldTableInfo), content, true, false).write();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableInfo getTableInfoByPsiClass(PsiClass psiClass) {
|
||||
TableInfo tableInfo = new TableInfo();
|
||||
tableInfo.setPsiClassObj(psiClass);
|
||||
tableInfo.setName(psiClass.getName());
|
||||
tableInfo.setComment(parsePsiClassComment(psiClass.getDocComment()));
|
||||
tableInfo.setFullColumn(new ArrayList<>());
|
||||
tableInfo.setPkColumn(new ArrayList<>());
|
||||
tableInfo.setOtherColumn(new ArrayList<>());
|
||||
for (PsiField field : psiClass.getAllFields()) {
|
||||
if (PsiClassGenerateUtils.isSkipField(field)) {
|
||||
continue;
|
||||
}
|
||||
ColumnInfo columnInfo = new ColumnInfo();
|
||||
columnInfo.setName(field.getName());
|
||||
columnInfo.setShortType(field.getType().getPresentableText());
|
||||
columnInfo.setType(field.getType().getCanonicalText());
|
||||
columnInfo.setComment(parsePsiClassComment(field.getDocComment()));
|
||||
tableInfo.getFullColumn().add(columnInfo);
|
||||
if (PsiClassGenerateUtils.isPkField(field)) {
|
||||
tableInfo.getPkColumn().add(columnInfo);
|
||||
} else {
|
||||
tableInfo.getOtherColumn().add(columnInfo);
|
||||
}
|
||||
}
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
private String removeClassNameGeneric(String fullName) {
|
||||
int genericIdx = fullName.indexOf('<');
|
||||
if (genericIdx == -1) {
|
||||
return fullName;
|
||||
}
|
||||
return fullName.substring(0, genericIdx);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TableInfo getTableInfoAndConfigByPsiClass(PsiClass selectPsiClass) {
|
||||
TableInfo tableInfo = this.getTableInfoByPsiClass(selectPsiClass);
|
||||
// 加载配置
|
||||
String configFileName = getConfigFileName(tableInfo);
|
||||
this.loadConfig(tableInfo, configFileName);
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableInfo> getTableInfoAndConfigByPsiClass(List<PsiClass> psiClassList) {
|
||||
if (CollectionUtil.isEmpty(psiClassList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<TableInfo> tableInfoList = new ArrayList<>(psiClassList.size());
|
||||
psiClassList.forEach(psiClass -> tableInfoList.add(this.getTableInfoAndConfigByPsiClass(psiClass)));
|
||||
return tableInfoList;
|
||||
}
|
||||
|
||||
private String parsePsiClassComment(@Nullable PsiDocComment docComment) {
|
||||
if (docComment == null) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(docComment.getDescriptionElements())
|
||||
.filter(o -> o instanceof PsiDocToken)
|
||||
.map(PsiElement::getText)
|
||||
.findFirst()
|
||||
.map(String::trim)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置文件
|
||||
*
|
||||
* @param fileName 配置文件名称, 不包含路径
|
||||
* @return 读取到的配置信息
|
||||
*/
|
||||
private TableInfo read(String fileName) {
|
||||
// 获取保存的目录
|
||||
VirtualFile easyCodeConfigDir = getEasyCodeConfigDirectory(project);
|
||||
if (easyCodeConfigDir == null) {
|
||||
return null;
|
||||
}
|
||||
// 获取配置文件
|
||||
VirtualFile configJsonFile = easyCodeConfigDir.findChild(fileName);
|
||||
if (configJsonFile == null) {
|
||||
return null;
|
||||
}
|
||||
Document document = FileDocumentManager.getInstance().getDocument(configJsonFile);
|
||||
if (document == null) {
|
||||
Messages.showInfoMessage(fileName + "转文档对象失败", GlobalDict.TITLE_INFO);
|
||||
return null;
|
||||
}
|
||||
// 读取并解析文件
|
||||
String json = document.getText();
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
Messages.showInfoMessage(fileName + "配置文件文件为空,请尝试手动删除" + configJsonFile.getPath() + "文件!",
|
||||
GlobalDict.TITLE_INFO);
|
||||
return null;
|
||||
}
|
||||
return parser(json, configJsonFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取EasyCodeConfig目录
|
||||
*
|
||||
* @param project 项目
|
||||
* @return EasyCodeConfig目录
|
||||
*/
|
||||
private VirtualFile getEasyCodeConfigDirectory(Project project) {
|
||||
VirtualFile baseDir = ProjectUtils.getBaseDir(project);
|
||||
if (baseDir == null) {
|
||||
Messages.showInfoMessage("无法获取项目路径", GlobalDict.TITLE_INFO);
|
||||
return null;
|
||||
}
|
||||
// 获取.idea路径
|
||||
VirtualFile ideaDir = baseDir.findChild(".idea");
|
||||
// 当获取失败时尝试通过父级目录获取,最多向上找3级目录
|
||||
VirtualFile tmpDir = baseDir;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (ideaDir != null) {
|
||||
break;
|
||||
}
|
||||
tmpDir = tmpDir.getParent();
|
||||
// 当没有父级目录时不再继续
|
||||
if (tmpDir == null) {
|
||||
break;
|
||||
}
|
||||
ideaDir = tmpDir.findChild(".idea");
|
||||
}
|
||||
if (ideaDir == null) {
|
||||
Messages.showInfoMessage(".idea路径获取失败", GlobalDict.TITLE_INFO);
|
||||
String errorMsg = String.format("baseDir:%s, not found .idea child directory", baseDir.getPath());
|
||||
ExceptionUtil.rethrow(new IllegalStateException(errorMsg));
|
||||
return null;
|
||||
}
|
||||
// 查找或创建EasyCodeConfig路径
|
||||
VirtualFile easyCodeDir = ideaDir.findChild("EasyCodeConfig");
|
||||
if (easyCodeDir == null) {
|
||||
easyCodeDir = fileUtils.createChildDirectory(project, ideaDir, "EasyCodeConfig");
|
||||
}
|
||||
return easyCodeDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置文件名称
|
||||
*
|
||||
* @param tableInfo 表信息对象
|
||||
* @return 对应的配置文件名称
|
||||
*/
|
||||
private String getConfigFileName(TableInfo tableInfo) {
|
||||
if (tableInfo.getObj() != null) {
|
||||
DbTable dbTable = tableInfo.getObj();
|
||||
String schemaName = DasUtil.getSchema(dbTable);
|
||||
return schemaName + "-" + dbTable.getName() + ".json";
|
||||
} else {
|
||||
return tableInfo.getPsiClassObj().getQualifiedName() + ".json";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象还原
|
||||
*
|
||||
* @param str 原始JSON字符串
|
||||
* @return 解析结果
|
||||
*/
|
||||
private TableInfo parser(String str, VirtualFile originalFile) {
|
||||
try {
|
||||
return JSON.parse(str, TableInfo.class);
|
||||
} catch (Exception e) {
|
||||
Messages.showWarningDialog("读取配置失败,JSON反序列化异常。请尝试手动删除" + originalFile.getPath() + "文件!",
|
||||
GlobalDict.TITLE_INFO);
|
||||
ExceptionUtil.rethrow(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.sjhy.plugin.tool;
|
||||
|
||||
import com.sjhy.plugin.dto.GenerateOptions;
|
||||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.entity.Template;
|
||||
import com.sjhy.plugin.service.impl.CodeGenerateServiceImpl;
|
||||
|
@ -25,14 +26,14 @@ public class ExtraCodeGenerateUtils {
|
|||
*/
|
||||
private TableInfo tableInfo;
|
||||
/**
|
||||
* 文件覆盖提示
|
||||
* 生成配置
|
||||
*/
|
||||
private Boolean title;
|
||||
private GenerateOptions generateOptions;
|
||||
|
||||
public ExtraCodeGenerateUtils(CodeGenerateServiceImpl codeGenerateService, TableInfo tableInfo, Boolean title) {
|
||||
public ExtraCodeGenerateUtils(CodeGenerateServiceImpl codeGenerateService, TableInfo tableInfo, GenerateOptions generateOptions) {
|
||||
this.codeGenerateService = codeGenerateService;
|
||||
this.tableInfo = tableInfo;
|
||||
this.title = title;
|
||||
this.generateOptions = generateOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,6 +54,6 @@ public class ExtraCodeGenerateUtils {
|
|||
return;
|
||||
}
|
||||
// 生成代码
|
||||
codeGenerateService.generate(Collections.singletonList(currTemplate), Collections.singletonList(this.tableInfo), this.title, param);
|
||||
codeGenerateService.generate(Collections.singletonList(currTemplate), Collections.singletonList(this.tableInfo), this.generateOptions, param);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,13 @@ public class VelocityUtils {
|
|||
builder.append(writer.toString());
|
||||
return builder.toString().replace("\r", "");
|
||||
}
|
||||
String code = stringWriter.toString();
|
||||
// 清除前面空格
|
||||
StringBuilder sb = new StringBuilder(code);
|
||||
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
|
||||
sb.deleteCharAt(0);
|
||||
}
|
||||
// 返回结果
|
||||
return stringWriter.toString();
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="e3588" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="e3588" layout-manager="GridLayoutManager" row-count="10" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
|
@ -74,7 +74,7 @@
|
|||
</component>
|
||||
<grid id="7831c" binding="templatePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="3" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="1" row-span="6" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
|
@ -82,7 +82,7 @@
|
|||
</grid>
|
||||
<component id="91ae2" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="3" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="0" row-span="6" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="string" key="label.template"/>
|
||||
|
@ -90,7 +90,7 @@
|
|||
</component>
|
||||
<vspacer id="98aa7">
|
||||
<constraints>
|
||||
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="9" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="caddc" class="javax.swing.JLabel">
|
||||
|
@ -119,20 +119,40 @@
|
|||
<text resource-bundle="string" key="label.module"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5e5a1" class="javax.swing.JCheckBox" binding="unifiedConfig">
|
||||
<component id="5e5a1" class="javax.swing.JCheckBox" binding="unifiedConfigCheckBox">
|
||||
<constraints>
|
||||
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="string" key="label.unified.config"/>
|
||||
<toolTipText value="在多表生成时,每张表会有自己保存的配置信息。<br>勾选统一配置表示所有表都使用当前的配置信息进行生成。<br>否则使用自身保存的配置信息生成代码。"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="af94e" class="javax.swing.JCheckBox" binding="titleConfig">
|
||||
<component id="af94e" class="javax.swing.JCheckBox" binding="titleSureCheckBox">
|
||||
<constraints>
|
||||
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="禁止提示"/>
|
||||
<text value="弹框选是"/>
|
||||
<toolTipText value="后续弹出的所有代码覆盖弹框全部选是"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="53e7" class="javax.swing.JCheckBox" binding="reFormatCheckBox">
|
||||
<constraints>
|
||||
<grid row="7" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="格式化代码"/>
|
||||
<toolTipText value="对生成完毕的代码进行格式化"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="846f2" class="javax.swing.JCheckBox" binding="titleRefuseCheckBox">
|
||||
<constraints>
|
||||
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="弹框选否"/>
|
||||
<toolTipText value="后续弹出的所有代码覆盖弹框全部选否"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||
import com.intellij.util.ExceptionUtil;
|
||||
import com.sjhy.plugin.constants.StrState;
|
||||
import com.sjhy.plugin.dict.GlobalDict;
|
||||
import com.sjhy.plugin.dto.GenerateOptions;
|
||||
import com.sjhy.plugin.dto.SettingsStorageDTO;
|
||||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.entity.Template;
|
||||
|
@ -77,11 +78,19 @@ public class SelectSavePath extends DialogWrapper {
|
|||
/**
|
||||
* 统一配置复选框
|
||||
*/
|
||||
private JCheckBox unifiedConfig;
|
||||
private JCheckBox unifiedConfigCheckBox;
|
||||
/**
|
||||
* 禁止提示复选框
|
||||
* 弹框选是复选框
|
||||
*/
|
||||
private JCheckBox titleConfig;
|
||||
private JCheckBox titleSureCheckBox;
|
||||
/**
|
||||
* 格式化代码复选框
|
||||
*/
|
||||
private JCheckBox reFormatCheckBox;
|
||||
/**
|
||||
* 弹框全否复选框
|
||||
*/
|
||||
private JCheckBox titleRefuseCheckBox;
|
||||
/**
|
||||
* 数据缓存工具类
|
||||
*/
|
||||
|
@ -305,7 +314,7 @@ public class SelectSavePath extends DialogWrapper {
|
|||
tableInfoService.saveTableInfo(tableInfo);
|
||||
|
||||
// 生成代码
|
||||
codeGenerateService.generateByUnifiedConfig(selectTemplateList, unifiedConfig.isSelected(), !titleConfig.isSelected(), this.entityMode);
|
||||
codeGenerateService.generate(selectTemplateList, getGenerateOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,6 +331,21 @@ public class SelectSavePath extends DialogWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取生成选项
|
||||
*
|
||||
* @return {@link GenerateOptions}
|
||||
*/
|
||||
private GenerateOptions getGenerateOptions() {
|
||||
return GenerateOptions.builder()
|
||||
.entityModel(this.entityMode)
|
||||
.reFormat(reFormatCheckBox.isSelected())
|
||||
.titleSure(titleSureCheckBox.isSelected())
|
||||
.titleRefuse(titleRefuseCheckBox.isSelected())
|
||||
.unifiedConfig(unifiedConfigCheckBox.isSelected())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选中的Module
|
||||
*
|
||||
|
|
|
@ -31,7 +31,7 @@ import com.sjhy.plugin.dict.GlobalDict;
|
|||
import com.sjhy.plugin.entity.TableInfo;
|
||||
import com.sjhy.plugin.entity.Template;
|
||||
import com.sjhy.plugin.service.CodeGenerateService;
|
||||
import com.sjhy.plugin.service.TableInfoService;
|
||||
import com.sjhy.plugin.service.TableInfoSettingsService;
|
||||
import com.sjhy.plugin.tool.CollectionUtil;
|
||||
import com.sjhy.plugin.tool.ProjectUtils;
|
||||
import com.sjhy.plugin.ui.base.EditorSettingsInit;
|
||||
|
@ -122,7 +122,7 @@ public class RealtimeDebugComponent {
|
|||
}
|
||||
}
|
||||
// 获取表信息
|
||||
TableInfo tableInfo = TableInfoService.getInstance(ProjectUtils.getCurrProject()).getTableInfoAndConfig(dbTable);
|
||||
TableInfo tableInfo = TableInfoSettingsService.getInstance().getTableInfo(dbTable);
|
||||
// 为未配置的表设置一个默认包名
|
||||
if (tableInfo.getSavePackageName() == null) {
|
||||
tableInfo.setSavePackageName("com.companyname.modulename");
|
||||
|
|
|
@ -241,7 +241,6 @@
|
|||
<applicationService serviceImplementation="com.sjhy.plugin.service.impl.SettingsStorageServiceImpl"/>
|
||||
<!--项目服务-->
|
||||
<projectService serviceImplementation="com.sjhy.plugin.service.impl.TableInfoSettingsServiceImpl"/>
|
||||
<projectService serviceInterface="com.sjhy.plugin.service.TableInfoService" serviceImplementation="com.sjhy.plugin.service.impl.TableInfoServiceImpl"/>
|
||||
<projectService serviceInterface="com.sjhy.plugin.service.CodeGenerateService" serviceImplementation="com.sjhy.plugin.service.impl.CodeGenerateServiceImpl"/>
|
||||
<!--系统设置面板-->
|
||||
<applicationConfigurable dynamic="true" instance="com.sjhy.plugin.ui.MainSettingForm"/>
|
||||
|
|
Loading…
Reference in New Issue