From aa3a81a5534e471aa6caf8b5817cfbfd813d175e Mon Sep 17 00:00:00 2001 From: PerryZhao Date: Tue, 3 Sep 2024 20:15:52 +0800 Subject: [PATCH] Optimizes the file creation logic of the NewFileUtils class (#86) * Optimizes the file creation logic of the NewFileUtils class 1. Refactor the file creation method to improve code reusability and readability 2. Add Java file specific processing logic to support package name and class name resolution 3. Improve file path and directory processing to enhance adaptability to the project structure * Fixed the import statement order. * Optimize file creation logic and path handling 1. Improved the determination logic of the target directory and handled a variety of project structures 2. Move the file creation operation to DumbService.runWhenSmart to improve IDE responsiveness --------- Co-authored-by: zhaopengjun --- .../zhongan/devpilot/util/NewFileUtils.java | 135 ++++++++++++++---- 1 file changed, 108 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/zhongan/devpilot/util/NewFileUtils.java b/src/main/java/com/zhongan/devpilot/util/NewFileUtils.java index 47a16d1..55703d8 100644 --- a/src/main/java/com/zhongan/devpilot/util/NewFileUtils.java +++ b/src/main/java/com/zhongan/devpilot/util/NewFileUtils.java @@ -8,6 +8,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -19,6 +20,7 @@ import com.zhongan.devpilot.enums.EditorActionEnum; import com.zhongan.devpilot.webview.model.CodeReferenceModel; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @@ -31,19 +33,20 @@ public class NewFileUtils { public static void createNewFile(Project project, String generatedText, CodeReferenceModel codeReferenceModel, String lang) { - // if lang is null, set default language to java - if (StringUtils.isEmpty(lang)) { - handleDefaultAction(project, generatedText, ".java"); - } - - String fileExtension = MarkdownUtil.getFileExtensionFromLanguage(lang); - - if (codeReferenceModel != null && ".java".equals(fileExtension) - && codeReferenceModel.getType() == EditorActionEnum.GENERATE_TESTS) { - var fileUrl = codeReferenceModel.getFileUrl(); - var fileName = codeReferenceModel.getFileName(); - // java test will goto special logic - handleGenerateTestsAction(project, generatedText, fileExtension, fileName, fileUrl); + String fileExtension = StringUtils.isEmpty(lang) ? ".java" : MarkdownUtil.getFileExtensionFromLanguage(lang); + + if (StringUtils.equalsIgnoreCase(".java", fileExtension)) { + String fileUrl = StringUtils.EMPTY; + if (codeReferenceModel != null) { + fileUrl = codeReferenceModel.getFileUrl(); + var fileName = codeReferenceModel.getFileName(); + if (codeReferenceModel.getType() == EditorActionEnum.GENERATE_TESTS) { + // java test will goto special logic + handleGenerateTestsAction(project, generatedText, fileExtension, fileName, fileUrl); + return; + } + } + handleDefaultActionForJava(project, generatedText, fileExtension, fileUrl); } else { handleDefaultAction(project, generatedText, fileExtension); } @@ -80,33 +83,98 @@ private static void handleGenerateTestsAction(Project project, String generatedT }); } - private static void handleDefaultAction(Project project, String generatedText, String fileExtension) { + private static String handleGeneratedJavaFileName(String generatedText, String fileExtension) { + String fileName = "temp_" + UUID.randomUUID().toString().substring(0, 8) + fileExtension; + String generatedClassName = extraClassNameFromGeneratedText(generatedText); + if (generatedClassName != null) { + fileName = generatedClassName + fileExtension; + } + return fileName; + } + + private static PsiDirectory handleGeneratedJavaPackageName(Project project, String generatedText, String fileUrl) { + String result = StringUtils.EMPTY; + String target = File.separator + "src" + File.separator + "main" + File.separator + "java"; + if (StringUtils.isNotEmpty(fileUrl) && fileUrl.contains(target)) { + // Find the project root path for the currently selected code + result = fileUrl.substring(0, fileUrl.indexOf(target)); + if (StringUtils.isNotEmpty(result)) { + VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByPath(result); + if (vf == null) { + result = StringUtils.EMPTY; + } + } + } else { + // Find the project root path of the file currently open for editing + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null != editor) { + VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument()); + if (null != virtualFile) { + ProjectFileIndex fileIndex = ProjectFileIndex.getInstance(project); + VirtualFile rootFile = fileIndex.getContentRootForFile(virtualFile); + result = null != rootFile ? rootFile.getPath() : StringUtils.EMPTY; + } + } + } + // When the root path is obtained, append the sourceDirectory + if (StringUtils.isNotEmpty(result)) { + result += target + File.separator; + } + if (StringUtils.isEmpty(result)) { + // Try to determine whether the target exists in the root path. If the target exists, use it directly + result = project.getBasePath(); + VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByPath(result + target); + if (null != vf) { + result += target + File.separator; + } else { + result += File.separator; + } + } + // Append PackageDirectory + String generatedPackageName = extractPackageFromGeneratedText(generatedText); + if (generatedPackageName != null) { + result += StringUtils.replace(generatedPackageName, ".", File.separator); + } + return createPsiDirectory(project, result); + } + + private static void handleDefaultActionForJava(Project project, String generatedText, String fileExtension, String fileUrl) { + String fileName = handleGeneratedJavaFileName(generatedText, fileExtension); + PsiDirectory targetPsiDir = handleGeneratedJavaPackageName(project, generatedText, fileUrl); + openAndWriteFile(project, generatedText, fileExtension, targetPsiDir, fileName); + } + + private static PsiDirectory handleGeneratedPsiDir(Project project) { PsiDirectory selectedFilePsiDir = getCurrentSelectedFilePsiDir(project); if (selectedFilePsiDir == null) { selectedFilePsiDir = createPsiDirectory(project, project.getBasePath()); } + return selectedFilePsiDir; + } + private static void handleDefaultAction(Project project, String generatedText, String fileExtension) { String fileName = "temp_" + UUID.randomUUID().toString().substring(0, 8) + fileExtension; - if (".java".equals(fileExtension)) { - String generatedClassName = extraClassNameFromGeneratedText(generatedText); - if (generatedClassName != null) { - fileName = generatedClassName + fileExtension; - } - } + PsiDirectory targetPsiDir = handleGeneratedPsiDir(project); + openAndWriteFile(project, generatedText, fileExtension, targetPsiDir, fileName); + } - if (selectedFilePsiDir.findFile(fileName) != null) { + private static void openAndWriteFile(Project project, String generatedText, String fileExtension, PsiDirectory targetFilePsiDir, String fileName) { + if (targetFilePsiDir.findFile(fileName) != null) { BalloonAlertUtils.showErrorAlert(DevPilotMessageBundle.get("devpilot.alter.file.exist"), 0, -10, Balloon.Position.above); - FileEditorManager.getInstance(project).openFile(selectedFilePsiDir.findFile(fileName).getVirtualFile(), true); + FileEditorManager.getInstance(project).openFile(targetFilePsiDir.findFile(fileName).getVirtualFile(), true); return; } FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(fileExtension.substring(1)); - PsiDirectory finalSelectedFileDir = selectedFilePsiDir; + PsiDirectory finalSelectedFileDir = targetFilePsiDir; String finalFileName = fileName; - WriteCommandAction.runWriteCommandAction(project, () -> { - PsiFile fileFromText = PsiFileFactory.getInstance(project).createFileFromText(finalFileName, fileType, generatedText); - PsiFile createdFile = (PsiFile) finalSelectedFileDir.add(fileFromText); - FileEditorManager.getInstance(project).openFile(createdFile.getVirtualFile(), true); + + DumbService.getInstance(project).runWhenSmart(() -> { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFile fileFromText = PsiFileFactory.getInstance(project).createFileFromText(finalFileName, fileType, generatedText); + PsiFile createdFile = (PsiFile) finalSelectedFileDir.add(fileFromText); + FileEditorManager.getInstance(project).openFile(createdFile.getVirtualFile(), true); + }); }); } @@ -150,4 +218,17 @@ private static PsiDirectory getCurrentSelectedFilePsiDir(@NotNull Project projec } return psiDirectory; } + + private static String extractPackageFromGeneratedText(String generatedText) { + String regex = "package\\s+([\\w.]+);"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(generatedText); + + String packageName = null; + if (matcher.find()) { + packageName = matcher.group(1); + } + return packageName; + } + }