Skip to content

Commit

Permalink
Optimizes the file creation logic of the NewFileUtils class (#86)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
PerryZhao and zhaopengjun authored Sep 3, 2024
1 parent a63721e commit aa3a81a
Showing 1 changed file with 108 additions and 27 deletions.
135 changes: 108 additions & 27 deletions src/main/java/com/zhongan/devpilot/util/NewFileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
});
});
}

Expand Down Expand Up @@ -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;
}

}

0 comments on commit aa3a81a

Please sign in to comment.