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..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 @@ -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().isSubDirectoryOrSame(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..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 @@ -16,7 +16,10 @@ 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.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import static javax.swing.JOptionPane.WARNING_MESSAGE; @@ -32,6 +35,38 @@ public class FileOperationHelper { return INSTANCE; } + /** + * 检查目标文件夹是否为多个源文件夹中的任一文件夹,或者任一文件夹的子文件夹 + * + * @param fileNodes 需移动的源文件 + * @param targetNode 移动后的目标文件夹 + * @return + */ + public boolean isSubDirectoryOrSame(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { + for (ExpandMutableTreeNode treeNode : fileNodes) { + FileNode sourceFileNode = (FileNode) treeNode.getUserObject(); + if (isSubDirectoryOrSame(sourceFileNode, targetNode)) { + return true; + } + } + return false; + } + + /** + * 检查目标文件夹是否为源文件夹,或源文件夹的子文件夹 + * + * @param sourceFileNode 需移动的源文件 + * @param targetNode 移动后的目标文件夹 + */ + public boolean isSubDirectoryOrSame(@NotNull FileNode sourceFileNode, @NotNull FileNode targetNode) { + if (!sourceFileNode.isDirectory() || !targetNode.isDirectory()) { + return false; + } + Path sourceDir = Paths.get(sourceFileNode.getEnvPath()).normalize(); + Path targetDir = Paths.get(targetNode.getEnvPath()).normalize(); + return targetDir.startsWith(sourceDir); + } + public String moveFile(FileNode sourceFileNode, String targetDir) { String targetPath = copyFileAndVcs(sourceFileNode, targetDir); FileNodeFILE nodeFILE = new FileNodeFILE(sourceFileNode); @@ -51,8 +86,9 @@ public class FileOperationHelper { /** * 拷贝文件的同时拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFileAndVcs(FileNode sourceFile, String targetDir) { @@ -61,8 +97,9 @@ public class FileOperationHelper { /** * 只拷贝文件, 不拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFile(FileNode sourceFile, String targetDir) { @@ -71,7 +108,8 @@ public class FileOperationHelper { /** * 检测节点是否被锁住了 - * @param node 待检测节点 + * + * @param node 待检测节点 * @param dNodes 没有锁住的节点集合 * @param lNodes 锁住的节点集合 * @return 是否存在被锁住的文件 @@ -165,7 +203,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..2fa25fd17 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java @@ -0,0 +1,49 @@ +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 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().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().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode1, treeNode2, treeNode3}, targetNode)); + Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode3, treeNode4}, targetNode)); + } +} \ No newline at end of file