From 2ec1a867f53c16f37d1e47ca8d7df2f12e6cd6da Mon Sep 17 00:00:00 2001 From: "Levy.Xie" Date: Tue, 23 May 2023 20:37:59 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-96012=20=E7=A7=BB=E5=8A=A8=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9=E5=88=B0=E8=87=AA=E5=B7=B1=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E4=B8=8B=EF=BC=8C=E6=96=87=E4=BB=B6=E5=A4=B9=E4=B8=A2?= =?UTF-8?q?=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultTemplateTreeDefineProcessor.java | 24 +++++++--- .../fr/design/file/FileOperationHelper.java | 47 +++++++++++++++++-- .../design/file/FileOperationHelperTest.java | 44 +++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java diff --git a/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java b/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java index 1bcfe3c62..e010986ac 100644 --- a/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java +++ b/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java @@ -28,7 +28,6 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.collections.CollectionUtils; import com.fr.stable.project.ProjectConstants; -import com.fr.workspace.WorkContext; import javax.swing.BorderFactory; import javax.swing.JDialog; @@ -221,6 +220,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi /** * 检测是否能够黏贴 + * * @param treeNodeList * @return */ @@ -271,7 +271,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi } } } catch (Exception e) { - FineLoggerFactory.getLogger().error(e,"Template paste failed.", e.getMessage()); + FineLoggerFactory.getLogger().error(e, "Template paste failed.", e.getMessage()); FineJOptionPane.showConfirmDialog(null, Toolkit.i18nText("Fine-Design_Basic_Paste_Failure"), Toolkit.i18nText("Fine-Design_Basic_Error"), @@ -286,7 +286,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi /** * 确认粘贴的目标目录是否是复制文件的子目录,并确认是否继续执行粘贴任务 * - * @param targetDir 目标文件夹 + * @param targetDir 目标文件夹 * @param pasteNodes 待粘贴的文件 * @return 是否继续 */ @@ -433,6 +433,14 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi WARNING_MESSAGE); return false; } + // 检查移动源文件夹是否为目标文件夹的子文件夹 + if (FileOperationHelper.getInstance().isSubDirectory(getFileTree().getSelectedTreeNodes(), getTargetFileNode())) { + FineJOptionPane.showMessageDialog(this, + Toolkit.i18nText("Fine-Design_Basic_Move_To_SubDirectory"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + WARNING_MESSAGE); + return false; + } if (TemplateUtils.checkSelectedTemplateIsEditing()) { return FineJOptionPane.showConfirmDialog(this, Toolkit.i18nText("Fine-Design_Basic_Template_Is_Editing"), @@ -443,9 +451,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi } private boolean doMove() { - FileNode fileNode = getDirTree().getSelectedFileNode(); - ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) getDirTree().getModel().getRoot(); - fileNode = fileNode == null ? (FileNode) rootTreeNode.getUserObject() : fileNode; + FileNode fileNode = getTargetFileNode(); boolean moveSuccess = true; try { //待移动的文件可以有多个 @@ -465,6 +471,12 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi return moveSuccess; } + private FileNode getTargetFileNode() { + FileNode fileNode = getDirTree().getSelectedFileNode(); + ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) getDirTree().getModel().getRoot(); + return fileNode == null ? (FileNode) rootTreeNode.getUserObject() : fileNode; + } + @Override public void dispose() { TemplateDirTreeSearchManager.getInstance().outOfSearchMode(); diff --git a/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java b/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java index a3abaf460..bdbab6413 100644 --- a/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java +++ b/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java @@ -16,6 +16,7 @@ import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; import com.fr.workspace.resource.ResourceIOException; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -26,12 +27,47 @@ import static javax.swing.JOptionPane.WARNING_MESSAGE; */ public class FileOperationHelper { + private static final char DIR_SEPARATOR = '/'; + private static final FileOperationHelper INSTANCE = new FileOperationHelper(); public static FileOperationHelper getInstance() { return INSTANCE; } + /** + * 检查多个目标文件夹是否含有源文件夹的子文件夹 + * + * @param fileNodes + * @param targetNode + * @return + */ + public boolean isSubDirectory(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { + for (ExpandMutableTreeNode treeNode : fileNodes) { + FileNode sourceFileNode = (FileNode) treeNode.getUserObject(); + if (isSubDirectory(sourceFileNode, targetNode)) { + return true; + } + } + return false; + } + + /** + * 检查目标文件夹是否为源文件夹的子文件夹 + * + * @param sourceFileNode + * @param targetNode + */ + public boolean isSubDirectory(@NotNull FileNode sourceFileNode, @NotNull FileNode targetNode) { + if (!sourceFileNode.isDirectory() || !targetNode.isDirectory()) { + return false; + } + String sourceDir = sourceFileNode.getEnvPath(); + String targetDir = targetNode.getEnvPath(); + return StringUtils.equals(targetDir, sourceDir) || + (targetDir.startsWith(sourceDir) && targetDir.charAt(sourceDir.length()) == DIR_SEPARATOR); + } + public String moveFile(FileNode sourceFileNode, String targetDir) { String targetPath = copyFileAndVcs(sourceFileNode, targetDir); FileNodeFILE nodeFILE = new FileNodeFILE(sourceFileNode); @@ -51,8 +87,9 @@ public class FileOperationHelper { /** * 拷贝文件的同时拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFileAndVcs(FileNode sourceFile, String targetDir) { @@ -61,8 +98,9 @@ public class FileOperationHelper { /** * 只拷贝文件, 不拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFile(FileNode sourceFile, String targetDir) { @@ -71,7 +109,8 @@ public class FileOperationHelper { /** * 检测节点是否被锁住了 - * @param node 待检测节点 + * + * @param node 待检测节点 * @param dNodes 没有锁住的节点集合 * @param lNodes 锁住的节点集合 * @return 是否存在被锁住的文件 @@ -165,7 +204,7 @@ public class FileOperationHelper { } else { if (!TemplateResourceManager.getResource().copy(sourcePath, targetPath)) { throw new ResourceIOException(String.format("copy file failed, from %s to %s", sourcePath, targetPath)); - } else if (withCopyVcs){ + } else if (withCopyVcs) { sourcePath = sourcePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY); targetPath = targetPath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY); VcsHelper.getInstance().moveVcs(sourcePath, targetPath); diff --git a/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java b/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java new file mode 100644 index 000000000..612a65d70 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java @@ -0,0 +1,44 @@ +package com.fr.design.file; + +import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.file.filetree.FileNode; +import org.junit.Assert; +import org.junit.Test; + + +/** + * + * @author Levy.Xie + * @version 11.0 + * Created by Levy.Xie on 2023/05/23 + */ +public class FileOperationHelperTest { + + @Test + public void testIsSubDirectory() { + FileNode sourceNode1 = new FileNode("/usr/local/webroot/reportlets", true); + FileNode sourceNode2 = new FileNode("/usr/local/webroot/reportlets/demo", true); + FileNode sourceNode3 = new FileNode("/usr/local/webroot/reportlets/doc", true); + FileNode sourceNode4 = new FileNode("/usr/local/webroot/reportlets/doc/1.cpt", false); + FileNode sourceNode5 = new FileNode("/usr/local/webroot/reportlets/demo/test", true); + FileNode sourceNode6 = new FileNode("/usr/local/webroot/reportlets/demo/test", false); + FileNode sourceNode7 = new FileNode("/usr/local/webroot/reportlets/demo/test123", true); + + FileNode targetNode = new FileNode("/usr/local/webroot/reportlets/demo/test", true); + + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectory(sourceNode1, targetNode)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectory(sourceNode2, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectory(sourceNode3, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectory(sourceNode4, targetNode)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectory(sourceNode5, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectory(sourceNode6, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectory(sourceNode7, targetNode)); + + ExpandMutableTreeNode treeNode1 = new ExpandMutableTreeNode(sourceNode1); + ExpandMutableTreeNode treeNode2 = new ExpandMutableTreeNode(sourceNode2); + ExpandMutableTreeNode treeNode3 = new ExpandMutableTreeNode(sourceNode3); + ExpandMutableTreeNode treeNode4 = new ExpandMutableTreeNode(sourceNode4); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectory(new ExpandMutableTreeNode[]{treeNode1, treeNode2, treeNode3}, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectory(new ExpandMutableTreeNode[]{treeNode3, treeNode4}, targetNode)); + } +} \ No newline at end of file