From 9b2cee87ca37465b430a25b18b4a2267dbdb2c9f Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Thu, 26 Jan 2017 15:55:48 +0300 Subject: [PATCH] svn: Refactored "ShareProjectAction" - code simplified, @NotNull --- .../src/org/jetbrains/idea/svn/SvnUtil.java | 4 +- .../idea/svn/actions/ShareProjectAction.java | 227 +++++++----------- .../idea/svn/dialogs/ShareDialog.java | 1 + 3 files changed, 95 insertions(+), 137 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index c82dd714a794..f767416251d1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -594,9 +594,9 @@ public class SvnUtil { return info == null ? null : info.getURL(); } - public static boolean remoteFolderIsEmpty(final SvnVcs vcs, final String url) throws VcsException { + public static boolean remoteFolderIsEmpty(@NotNull SvnVcs vcs, @NotNull String url) throws VcsException { SvnTarget target = SvnTarget.fromURL(createUrl(url)); - final Ref result = new Ref<>(true); + Ref result = new Ref<>(true); DirectoryEntryConsumer handler = new DirectoryEntryConsumer() { @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java index 909000d78205..1684b0518215 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/ShareProjectAction.java @@ -18,13 +18,9 @@ package org.jetbrains.idea.svn.actions; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsException; @@ -36,51 +32,38 @@ import org.jetbrains.idea.svn.api.ClientFactory; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider; import org.jetbrains.idea.svn.dialogs.ShareDialog; -import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; -import java.io.File; - +import static com.intellij.openapi.progress.ProgressManager.progress; +import static com.intellij.openapi.ui.Messages.*; import static com.intellij.openapi.vfs.VfsUtilCore.virtualToIoFile; +import static com.intellij.util.ArrayUtil.isEmpty; +import static org.jetbrains.idea.svn.SvnBundle.message; +import static org.jetbrains.idea.svn.SvnUtil.append; +import static org.jetbrains.idea.svn.SvnUtil.createUrl; public class ShareProjectAction extends BasicAction { @NotNull @Override protected String getActionName() { - return SvnBundle.message("share.directory.action"); + return message("share.directory.action"); } @Override public void update(@NotNull AnActionEvent e) { - Presentation presentation = e.getPresentation(); - DataContext dataContext = e.getDataContext(); + VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); + Project project = e.getProject(); + boolean visible = project != null && + !ProjectLevelVcsManager.getInstance(project).isBackgroundVcsOperationRunning() && + !isEmpty(files) && + files.length == 1 && + files[0].isDirectory(); - Project project = CommonDataKeys.PROJECT.getData(dataContext); - if ((project == null) || (ProjectLevelVcsManager.getInstance(project).isBackgroundVcsOperationRunning())) { - presentation.setEnabled(false); - presentation.setVisible(false); - return; - } - - VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); - if (files == null || files.length == 0) { - presentation.setEnabled(false); - presentation.setVisible(false); - return; - } - boolean enabled = false; - boolean visible = false; - if (files.length == 1 && files [0].isDirectory()) { - visible = true; - if (! SvnStatusUtil.isUnderControl(project, files[0])) { - enabled = true; - } - } - presentation.setEnabled(enabled); - presentation.setVisible(visible); + e.getPresentation().setVisible(visible); + e.getPresentation().setEnabled(visible && !SvnStatusUtil.isUnderControl(project, files[0])); } @Override @@ -88,17 +71,17 @@ public class ShareProjectAction extends BasicAction { return false; } - public static boolean share(@NotNull Project project, VirtualFile file) throws VcsException { - return performImpl(project, SvnVcs.getInstance(project), file); + public static boolean share(@NotNull Project project, @NotNull VirtualFile file) throws VcsException { + return performImpl(SvnVcs.getInstance(project), file); } @Override protected void perform(@NotNull SvnVcs vcs, @NotNull VirtualFile file, @NotNull DataContext context) throws VcsException { - performImpl(vcs.getProject(), vcs, file); + performImpl(vcs, file); } - private static boolean performImpl(Project project, SvnVcs activeVcs, VirtualFile file) throws VcsException { - ShareDialog shareDialog = new ShareDialog(project, file.getName()); + private static boolean performImpl(@NotNull SvnVcs vcs, @NotNull VirtualFile file) throws VcsException { + ShareDialog shareDialog = new ShareDialog(vcs.getProject(), file.getName()); shareDialog.show(); String parent = shareDialog.getSelectedURL(); @@ -106,127 +89,103 @@ public class ShareProjectAction extends BasicAction { Ref actionStarted = new Ref<>(Boolean.TRUE); Exception[] error = new Exception[1]; ShareDialog.ShareTarget shareTarget = shareDialog.getShareTarget(); - ProgressManager progressManager = ProgressManager.getInstance(); - if (ShareDialog.ShareTarget.useSelected.equals(shareTarget)) { - boolean folderEmpty = checkRemoteFolder(project, activeVcs, parent, progressManager); - - if (!folderEmpty) { - int promptAnswer = - Messages.showYesNoDialog(project, "Remote folder \"" + parent + "\" is not empty.\nDo you want to continue sharing?", - "Share directory", Messages.getWarningIcon()); - if (Messages.YES != promptAnswer) return false; - } + if (ShareDialog.ShareTarget.useSelected.equals(shareTarget) && + !isFolderEmpty(vcs, parent) && + YES != + showYesNoDialog(vcs.getProject(), "Remote folder \"" + parent + "\" is not empty.\nDo you want to continue sharing?", + "Share Directory", getWarningIcon())) { + return false; } - WorkingCopyFormat format = SvnCheckoutProvider.promptForWCopyFormat(virtualToIoFile(file), project); + WorkingCopyFormat format = SvnCheckoutProvider.promptForWCopyFormat(virtualToIoFile(file), vcs.getProject()); actionStarted.set(format != WorkingCopyFormat.UNKNOWN); // means operation cancelled if (format == WorkingCopyFormat.UNKNOWN) { return true; } - ExclusiveBackgroundVcsAction.run(project, () -> progressManager.runProcessWithProgressSynchronously(() -> { - try { - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - File path = virtualToIoFile(file); + ExclusiveBackgroundVcsAction.run(vcs.getProject(), () -> + ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { + try { + SvnWorkingCopyFormatHolder.setPresetFormat(format); - SvnWorkingCopyFormatHolder.setPresetFormat(format); + SvnTarget checkoutTarget = + createFolderStructure(vcs, file, shareTarget, shareDialog.createStandardStructure(), createUrl(parent), + shareDialog.getCommitText()); - SVNURL parenUrl = SVNURL.parseURIEncoded(parent); - SVNURL checkoutUrl; - SVNRevision revision; - String commitText = shareDialog.getCommitText(); - if (ShareDialog.ShareTarget.useSelected.equals(shareTarget)) { - checkoutUrl = parenUrl; - revision = SVNRevision.HEAD; + progress(message("share.directory.checkout.back.progress.text", checkoutTarget.getPathOrUrlString())); + + ClientFactory factory = SvnCheckoutProvider.getFactory(vcs, format); + + factory.createCheckoutClient() + .checkout(SvnTarget.fromURL(checkoutTarget.getURL()), virtualToIoFile(file), checkoutTarget.getPegRevision(), Depth.INFINITY, + false, false, format, null); + addRecursively(vcs, factory, file); } - else if (ShareDialog.ShareTarget.useProjectName.equals(shareTarget)) { - Pair pair = createRemoteFolder(activeVcs, parenUrl, file.getName(), commitText); - revision = pair.getFirst(); - checkoutUrl = pair.getSecond(); + catch (VcsException e) { + error[0] = e; } - else { - Pair pair = createRemoteFolder(activeVcs, parenUrl, file.getName(), commitText); - Pair trunkPair = createRemoteFolder(activeVcs, pair.getSecond(), "trunk", commitText); - checkoutUrl = trunkPair.getSecond(); - revision = trunkPair.getFirst(); - - if (shareDialog.createStandardStructure()) { - createRemoteFolder(activeVcs, pair.getSecond(), "branches", commitText); - createRemoteFolder(activeVcs, pair.getSecond(), "tags", commitText); - } + finally { + vcs.invokeRefreshSvnRoots(); + SvnWorkingCopyFormatHolder.setPresetFormat(null); } - - if (indicator != null) { - indicator.checkCanceled(); - indicator.setText(SvnBundle.message("share.directory.checkout.back.progress.text", checkoutUrl.toString())); - } - - ClientFactory factory = SvnCheckoutProvider.getFactory(activeVcs, format); - - factory.createCheckoutClient() - .checkout(SvnTarget.fromURL(checkoutUrl), path, revision, Depth.INFINITY, false, false, format, null); - addRecursively(activeVcs, factory, file); - } - catch (SVNException | VcsException e) { - error[0] = e; - } - finally { - activeVcs.invokeRefreshSvnRoots(); - SvnWorkingCopyFormatHolder.setPresetFormat(null); - } - }, SvnBundle.message("share.directory.title"), true, project)); + }, message("share.directory.title"), true, vcs.getProject())); if (Boolean.TRUE.equals(actionStarted.get())) { if (error[0] != null) { throw new VcsException(error[0].getMessage()); } - Messages.showInfoMessage(project, SvnBundle.message("share.directory.info.message", file.getName()), - SvnBundle.message("share.directory.title")); + showInfoMessage(vcs.getProject(), message("share.directory.info.message", file.getName()), message("share.directory.title")); } return true; } return false; } - private static boolean checkRemoteFolder(Project project, SvnVcs activeVcs, String parent, ProgressManager progressManager) - throws VcsException { - VcsException[] exc = new VcsException[1]; - boolean[] folderEmpty = new boolean[1]; + @NotNull + private static SvnTarget createFolderStructure(@NotNull SvnVcs vcs, + @NotNull VirtualFile file, + @NotNull ShareDialog.ShareTarget shareTarget, + boolean createStandardStructure, + @NotNull SVNURL parentUrl, + @NotNull String commitText) throws VcsException { + switch (shareTarget) { + case useSelected: + return SvnTarget.fromURL(parentUrl, SVNRevision.HEAD); + case useProjectName: + return createRemoteFolder(vcs, parentUrl, file.getName(), commitText); + default: + SvnTarget projectRoot = createRemoteFolder(vcs, parentUrl, file.getName(), commitText); + SvnTarget trunk = createRemoteFolder(vcs, projectRoot.getURL(), "trunk", commitText); - progressManager.runProcessWithProgressSynchronously(() -> { - try { - folderEmpty[0] = SvnUtil.remoteFolderIsEmpty(activeVcs, parent); - } - catch (VcsException e) { - exc[0] = e; - } - }, "Check remote folder contents", false, project); - if (exc[0] != null) { - throw exc[0]; + if (createStandardStructure) { + createRemoteFolder(vcs, projectRoot.getURL(), "branches", commitText); + createRemoteFolder(vcs, projectRoot.getURL(), "tags", commitText); + } + return trunk; } - return folderEmpty[0]; + } + + private static boolean isFolderEmpty(@NotNull SvnVcs vcs, @NotNull String folderUrl) throws VcsException { + return ProgressManager.getInstance().runProcessWithProgressSynchronously( + () -> SvnUtil.remoteFolderIsEmpty(vcs, folderUrl), "Check Remote Folder Contents", false, vcs.getProject()); } @NotNull - private static Pair createRemoteFolder(@NotNull SvnVcs vcs, - @NotNull SVNURL parent, - String folderName, - String commitText) throws VcsException, SVNException { - SVNURL url = parent.appendPath(folderName, false); - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - if (indicator != null) { - indicator.checkCanceled(); - indicator.setText(SvnBundle.message("share.directory.create.dir.progress.text", url.toString())); - } - + private static SvnTarget createRemoteFolder(@NotNull SvnVcs vcs, + @NotNull SVNURL parent, + @NotNull String folderName, + @NotNull String commitText) throws VcsException { + SVNURL url = append(parent, folderName); String message = - SvnBundle.message("share.directory.commit.message", folderName, ApplicationNamesInfo.getInstance().getFullProductName(), commitText); + message("share.directory.commit.message", folderName, ApplicationNamesInfo.getInstance().getFullProductName(), commitText); SvnTarget target = SvnTarget.fromURL(url); - long revision = vcs.getFactoryFromSettings().createBrowseClient().createDirectory(target, message, false); - return Pair.create(SVNRevision.create(revision), url); + progress(message("share.directory.create.dir.progress.text", url.toString())); + + long revision = vcs.getFactoryFromSettings().createBrowseClient().createDirectory(target, message, false); + return SvnTarget.fromURL(url, SVNRevision.create(revision)); } @Override @@ -234,17 +193,15 @@ public class ShareProjectAction extends BasicAction { VcsDirtyScopeManager.getInstance(vcs.getProject()).dirDirtyRecursively(file); } - private static void addRecursively(@NotNull SvnVcs vcs, @NotNull ClientFactory factory, @NotNull VirtualFile file) throws VcsException { - SvnExcludingIgnoredOperation operation = new SvnExcludingIgnoredOperation(vcs.getProject(), virtualFile -> { - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - if (indicator != null) { - indicator.checkCanceled(); - indicator.setText(SvnBundle.message("share.or.import.add.progress.text", virtualFile.getPath())); - } - factory.createAddClient().add(virtualToIoFile(virtualFile), Depth.EMPTY, false, false, true, null); + private static void addRecursively(@NotNull SvnVcs vcs, @NotNull ClientFactory factory, @NotNull VirtualFile rootFile) + throws VcsException { + SvnExcludingIgnoredOperation operation = new SvnExcludingIgnoredOperation(vcs.getProject(), file -> { + progress(message("share.or.import.add.progress.text", file.getPath())); + + factory.createAddClient().add(virtualToIoFile(file), Depth.EMPTY, false, false, true, null); }, Depth.INFINITY); - operation.execute(file); + operation.execute(rootFile); } @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ShareDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ShareDialog.java index d441052bb243..865e1eed87bc 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ShareDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/ShareDialog.java @@ -162,6 +162,7 @@ public class ShareDialog extends RepositoryBrowserDialog { return wrapper; } + @NotNull public ShareTarget getShareTarget() { if (myExisting.isSelected()) { return ShareTarget.useSelected;