mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
svn: Refactored "ShareProjectAction" - code simplified, @NotNull
This commit is contained in:
@@ -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<Boolean> result = new Ref<>(true);
|
||||
Ref<Boolean> result = new Ref<>(true);
|
||||
DirectoryEntryConsumer handler = new DirectoryEntryConsumer() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<Boolean> 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<SVNRevision, SVNURL> pair = createRemoteFolder(activeVcs, parenUrl, file.getName(), commitText);
|
||||
revision = pair.getFirst();
|
||||
checkoutUrl = pair.getSecond();
|
||||
catch (VcsException e) {
|
||||
error[0] = e;
|
||||
}
|
||||
else {
|
||||
Pair<SVNRevision, SVNURL> pair = createRemoteFolder(activeVcs, parenUrl, file.getName(), commitText);
|
||||
Pair<SVNRevision, SVNURL> 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<SVNRevision, SVNURL> 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
|
||||
|
||||
@@ -162,6 +162,7 @@ public class ShareDialog extends RepositoryBrowserDialog {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ShareTarget getShareTarget() {
|
||||
if (myExisting.isSelected()) {
|
||||
return ShareTarget.useSelected;
|
||||
|
||||
Reference in New Issue
Block a user