修复同时生成多个文件会导致索引不可用问题

This commit is contained in:
makejava 2020-04-21 11:37:40 +08:00
parent e82a8a0a5b
commit 8da33606c9
6 changed files with 146 additions and 103 deletions

View File

@ -0,0 +1,71 @@
package com.sjhy.plugin.entity;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.sjhy.plugin.tool.FileUtils;
import lombok.Data;
/**
* 需要保存的文件
*
* @author makejava
* @version 1.0.0
* @since 2020/04/20 22:54
*/
@Data
public class SaveFile {
private static final Logger LOG = Logger.getInstance(SaveFile.class);
/**
* 所属项目
*/
private Project project;
/**
* 文件保存目录
*/
private String path;
/**
* 需要保存的文件
*/
private PsiFile file;
/**
* 是否需要重新格式化代码
*/
private boolean reformat;
/**
* 文件
*/
private PsiFile psiFile;
/**
* 是否显示操作提示
*/
private boolean operateTitle;
/**
* 构建对象
*
* @param path 路径
* @param fileName 文件没
* @param reformat 是否重新格式化代码
*/
public SaveFile(Project project, String path, String fileName, String content, boolean reformat, boolean operateTitle) {
this.path = path;
this.project = project;
// 构建文件对象
PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project);
LOG.assertTrue(content != null);
// 换行符统一使用\n
this.file = psiFileFactory.createFileFromText(fileName, FileTypes.UNKNOWN, content.replace("\r", ""));
this.reformat = reformat;
this.operateTitle = operateTitle;
}
/**
* 写入文件
*/
public void write() {
FileUtils.getInstance().write(this);
}
}

View File

@ -1,25 +1,21 @@
package com.sjhy.plugin.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.intellij.database.util.DasUtil;
import com.intellij.database.util.DbUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiFile;
import com.sjhy.plugin.config.Settings;
import com.sjhy.plugin.constants.MsgValue;
import com.sjhy.plugin.entity.Callback;
import com.sjhy.plugin.entity.SaveFile;
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.tool.*;
import java.io.File;
import java.nio.charset.Charset;
import java.util.*;
/**
@ -36,10 +32,6 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
* 模型管理
*/
private ModuleManager moduleManager;
/**
* 文件工具
*/
private FileUtils fileUtils;
/**
* 表信息服务
*/
@ -56,7 +48,6 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
public CodeGenerateServiceImpl(Project project) {
this.project = project;
this.moduleManager = ModuleManager.getInstance(project);
this.fileUtils = FileUtils.getInstance();
this.tableInfoService = TableInfoService.getInstance(project);
this.cacheDataUtils = CacheDataUtils.getInstance();
}
@ -139,14 +130,13 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
setModulePathAndImportList(param, tableInfo);
// 设置额外代码生成服务
param.put("generateService", new ExtraCodeGenerateUtils(this, tableInfo, title));
List<PsiFile> psiFileList = new ArrayList<>();
for (Template template : templates) {
Callback callback = new Callback();
// 设置回调对象
param.put("callback", callback);
// 开始生成
String code = VelocityUtils.generate(template.getCode(), param);
// 消除两端空格
// 清除前面空格
code = code.trim();
// 设置一个默认保存路径与默认文件名
if (StringUtils.isEmpty(callback.getFileName())) {
@ -161,36 +151,9 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
if (path.startsWith(".")) {
path = project.getBasePath() + path.substring(1);
}
// 创建目录
File dir = new File(path);
if (!dir.exists()) {
// 提示创建目录
if (title && !MessageDialogBuilder.yesNo(MsgValue.TITLE_INFO, "Directory " + dir.getAbsolutePath() + " Not Found, Confirm Create?").isYes()) {
continue;
}
if (!dir.mkdirs()) {
Messages.showWarningDialog("Directory Create Failure!", MsgValue.TITLE_INFO);
continue;
}
}
File file = new File(dir, callback.getFileName());
// 提示是否覆盖文件
if (title && file.exists()) {
if (!MessageDialogBuilder.yesNo(MsgValue.TITLE_INFO, "File " + file.getName() + " Exists, Confirm Continue?").isYes()) {
continue;
}
}
// 保存文件
PsiFile psiFile = fileUtils.write(project, file, code);
if (psiFile != null && callback.isReformat()) {
psiFileList.add(psiFile);
}
new SaveFile(project, path, callback.getFileName(), code, callback.isReformat(), title).write();
}
// 统一格式化
fileUtils.reformatFile(project, psiFileList);
}
//刷新整个项目
VirtualFileManager.getInstance().syncRefresh();
}
/**
@ -248,6 +211,9 @@ public class CodeGenerateServiceImpl implements CodeGenerateService {
param.put("time", TimeUtils.getInstance());
// 项目路径
param.put("projectPath", project.getBasePath());
// Database数据库工具
param.put("dbUtil", DbUtil.class);
param.put("dasUtil", DasUtil.class);
return param;
}

View File

@ -9,12 +9,11 @@ import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.containers.JBIterable;
import com.sjhy.plugin.constants.MsgValue;
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;
@ -334,14 +333,7 @@ public class TableInfoServiceImpl implements TableInfoService {
}
}
// 获取保存文件
File file = new File(dir, getConfigFileName(oldTableInfo.getObj()));
//写入配置文件
PsiFile psiFile = fileUtils.write(project, file, content);
if (psiFile != null) {
fileUtils.reformatFile(project, Collections.singletonList(psiFile));
}
// 同步刷新
VirtualFileManager.getInstance().syncRefresh();
new SaveFile(project, dir.getAbsolutePath(), getConfigFileName(oldTableInfo.getObj()), content, true, false).write();
}
/**

View File

@ -6,19 +6,25 @@ import com.intellij.codeInsight.actions.ReformatCodeProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.ExceptionUtil;
import com.sjhy.plugin.constants.MsgValue;
import com.sjhy.plugin.entity.SaveFile;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
/**
@ -70,27 +76,61 @@ public class FileUtils {
}
/**
* 写入文件内容覆盖模式
* 写入文件
*
* @param project 项目对象
* @param file 文件
* @param content 文件内容
* @param saveFile 需要保存的文件对象
*/
public PsiFile write(Project project, File file, String content) {
// 替换换行符
content = content.replace("\r\n", "\n");
// 创建文件
PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project);
PsiFile psiFile = psiFileFactory.createFileFromText(file.getName(), FileTypes.UNKNOWN, content);
PsiManager psiManager = PsiManager.getInstance(project);
VirtualFile parentVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file.getParentFile());
if (parentVirtualFile == null) {
// 自动创建目录
Messages.showWarningDialog("目录不存在", MsgValue.TITLE_INFO);
return null;
public void write(SaveFile saveFile) {
// 校验目录是否存在
PsiManager psiManager = PsiManager.getInstance(saveFile.getProject());
PsiDirectory psiDirectory;
VirtualFile directory = LocalFileSystem.getInstance().findFileByPath(saveFile.getPath());
if (directory == null) {
// 尝试创建目录
if (saveFile.isOperateTitle() && !MessageDialogBuilder.yesNo(MsgValue.TITLE_INFO, "Directory " + saveFile.getPath() + " Not Found, Confirm Create?").isYes()) {
return;
}
psiDirectory = WriteCommandAction.runWriteCommandAction(saveFile.getProject(), (Computable<PsiDirectory>) () -> {
try {
VirtualFile dir = VfsUtil.createDirectoryIfMissing(saveFile.getPath());
LOG.assertTrue(dir != null);
return psiManager.findDirectory(dir);
} catch (IOException e) {
LOG.error("path {} error", saveFile.getPath());
ExceptionUtil.rethrow(e);
return null;
}
});
} else {
psiDirectory = psiManager.findDirectory(directory);
}
if (psiDirectory == null) {
return;
}
// 保存或替换文件
PsiFile oldFile = psiDirectory.findFile(saveFile.getFile().getName());
if (oldFile != null) {
if (saveFile.isOperateTitle() && MessageDialogBuilder.yesNo(MsgValue.TITLE_INFO, "File " + saveFile.getFile().getName() + " Exists, Confirm Continue?").isYes()) {
return;
}
}
PsiDirectory finalPsiDirectory = psiDirectory;
PsiFile finalFile = WriteCommandAction.runWriteCommandAction(saveFile.getProject(), (Computable<PsiFile>) () -> {
if (oldFile == null) {
return (PsiFile) finalPsiDirectory.add(saveFile.getFile());
} else {
// 对旧文件进行替换操作
PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(saveFile.getProject());
Document document = psiDocumentManager.getDocument(oldFile);
LOG.assertTrue(document != null);
document.setText(saveFile.getFile().getText());
return oldFile;
}
});
// 判断是否需要进行代码格式化操作
if (saveFile.isReformat()) {
reformatFile(saveFile.getProject(), Collections.singletonList(finalFile));
}
PsiDirectory psiDirectory = psiManager.findDirectory(parentVirtualFile);
return saveFileAndFormatCode(project, psiDirectory, psiFile);
}
/**
@ -100,7 +140,7 @@ public class FileUtils {
* @param psiFileList 文件列表
*/
@SuppressWarnings("unchecked")
public void reformatFile(Project project, List<PsiFile> psiFileList) {
private void reformatFile(Project project, List<PsiFile> psiFileList) {
if (CollectionUtil.isEmpty(psiFileList)) {
return;
}
@ -127,28 +167,4 @@ public class FileUtils {
// 执行处理
processor.run();
}
/**
* 保存并格式化文件
*
* @param project 项目
* @param psiDirectory 目录
* @param psiFile 文件
*/
private PsiFile saveFileAndFormatCode(Project project, PsiDirectory psiDirectory, PsiFile psiFile) {
return WriteCommandAction.runWriteCommandAction(project, (Computable<PsiFile>) () -> {
PsiFile oldFile = psiDirectory.findFile(psiFile.getName());
PsiFile temFile;
if (oldFile != null) {
Document document = PsiDocumentManager.getInstance(project).getDocument(oldFile);
LOG.assertTrue(document != null);
// 替换文件
document.setText(psiFile.getText());
temFile = oldFile;
} else {
temFile = (PsiFile) psiDirectory.add(psiFile);
}
return temFile;
});
}
}

View File

@ -1,6 +1,5 @@
package com.sjhy.plugin.tool;
import com.sjhy.plugin.config.Settings;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
@ -50,7 +49,6 @@ public class VelocityUtils {
VelocityEngine velocityEngine = new VelocityEngine(INIT_PROP);
// 创建上下文对象
VelocityContext velocityContext = new VelocityContext();
Settings settings = Settings.getInstance();
if (map != null) {
map.forEach(velocityContext::put);
}

View File

@ -7,6 +7,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
//import com.intellij.psi.PsiPackage;
import com.intellij.util.ExceptionUtil;
@ -28,8 +29,7 @@ import java.awt.event.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.*;
import java.util.List;
/**
@ -307,7 +307,7 @@ public class SelectSavePath extends JDialog {
//选择路径
pathChooseButton.addActionListener(e -> {
//将当前选中的model设置为基础路径
VirtualFile path = project.getBaseDir();
VirtualFile path = LocalFileSystem.getInstance().findFileByPath(project.getBasePath());
Module module = getSelectModule();
if (module != null) {
path = ModuleUtils.getSourcePath(module);