From 2ec1a867f53c16f37d1e47ca8d7df2f12e6cd6da Mon Sep 17 00:00:00 2001 From: "Levy.Xie" Date: Tue, 23 May 2023 20:37:59 +0800 Subject: [PATCH 1/3] =?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 From 3e2dfd6f53ac8f26ac1fce8b74bb948f080968ed Mon Sep 17 00:00:00 2001 From: "Levy.Xie" Date: Wed, 24 May 2023 10:03:46 +0800 Subject: [PATCH 2/3] =?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=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/file/FileOperationHelper.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) 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 bdbab6413..bc947df41 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 @@ -18,6 +18,8 @@ import com.fr.workspace.WorkContext; import com.fr.workspace.resource.ResourceIOException; import org.jetbrains.annotations.NotNull; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import static javax.swing.JOptionPane.WARNING_MESSAGE; @@ -27,8 +29,6 @@ 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() { @@ -36,10 +36,10 @@ public class FileOperationHelper { } /** - * 检查多个目标文件夹是否含有源文件夹的子文件夹 + * 检查目标文件夹是否为多个源文件夹中,任一文件夹的子文件夹 * - * @param fileNodes - * @param targetNode + * @param fileNodes 需移动的源文件 + * @param targetNode 移动后的目标文件夹 * @return */ public boolean isSubDirectory(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { @@ -55,17 +55,16 @@ public class FileOperationHelper { /** * 检查目标文件夹是否为源文件夹的子文件夹 * - * @param sourceFileNode - * @param targetNode + * @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); + Path sourceDir = Paths.get(sourceFileNode.getEnvPath()); + Path targetDir = Paths.get(targetNode.getEnvPath()); + return targetDir.startsWith(sourceDir); } public String moveFile(FileNode sourceFileNode, String targetDir) { From d0d89d77f071e923a4f71f6267c42686b4634456 Mon Sep 17 00:00:00 2001 From: "Levy.Xie" Date: Mon, 29 May 2023 11:48:09 +0800 Subject: [PATCH 3/3] =?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 | 4 ++-- .../fr/design/file/FileOperationHelper.java | 14 +++++------ .../design/file/FileOperationHelperTest.java | 23 +++++++++++-------- 3 files changed, 23 insertions(+), 18 deletions(-) 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 e010986ac..1d2048fa2 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 @@ -433,8 +433,8 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi WARNING_MESSAGE); return false; } - // 检查移动源文件夹是否为目标文件夹的子文件夹 - if (FileOperationHelper.getInstance().isSubDirectory(getFileTree().getSelectedTreeNodes(), getTargetFileNode())) { + // 检查移动的源文件夹是否为目标文件夹相同文件夹或子文件夹 + if (FileOperationHelper.getInstance().isSubDirectoryOrSame(getFileTree().getSelectedTreeNodes(), getTargetFileNode())) { FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_Move_To_SubDirectory"), Toolkit.i18nText("Fine-Design_Basic_Alert"), 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 bc947df41..8bf57ae4e 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 @@ -36,16 +36,16 @@ public class FileOperationHelper { } /** - * 检查目标文件夹是否为多个源文件夹中,任一文件夹的子文件夹 + * 检查目标文件夹是否为多个源文件夹中的任一文件夹,或者任一文件夹的子文件夹 * * @param fileNodes 需移动的源文件 * @param targetNode 移动后的目标文件夹 * @return */ - public boolean isSubDirectory(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { + public boolean isSubDirectoryOrSame(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { for (ExpandMutableTreeNode treeNode : fileNodes) { FileNode sourceFileNode = (FileNode) treeNode.getUserObject(); - if (isSubDirectory(sourceFileNode, targetNode)) { + if (isSubDirectoryOrSame(sourceFileNode, targetNode)) { return true; } } @@ -53,17 +53,17 @@ public class FileOperationHelper { } /** - * 检查目标文件夹是否为源文件夹的子文件夹 + * 检查目标文件夹是否为源文件夹,或源文件夹的子文件夹 * * @param sourceFileNode 需移动的源文件 * @param targetNode 移动后的目标文件夹 */ - public boolean isSubDirectory(@NotNull FileNode sourceFileNode, @NotNull FileNode targetNode) { + public boolean isSubDirectoryOrSame(@NotNull FileNode sourceFileNode, @NotNull FileNode targetNode) { if (!sourceFileNode.isDirectory() || !targetNode.isDirectory()) { return false; } - Path sourceDir = Paths.get(sourceFileNode.getEnvPath()); - Path targetDir = Paths.get(targetNode.getEnvPath()); + Path sourceDir = Paths.get(sourceFileNode.getEnvPath()).normalize(); + Path targetDir = Paths.get(targetNode.getEnvPath()).normalize(); return targetDir.startsWith(sourceDir); } 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 index 612a65d70..2fa25fd17 100644 --- a/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java +++ b/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java @@ -23,22 +23,27 @@ public class FileOperationHelperTest { 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 sourceNode8 = new FileNode("/usr/local/webroot/reportlets/../reportlets/demo/test", true); + FileNode sourceNode9 = new FileNode("/usr/local/webroot/reportlets/../reportlets/demo/test/c", 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)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode1, targetNode)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode2, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode3, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode4, targetNode)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode5, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode6, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode7, targetNode)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode8, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode9, 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)); + Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode1, treeNode2, treeNode3}, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode3, treeNode4}, targetNode)); } } \ No newline at end of file