/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java

https://bitbucket.org/nbargnesi/idea · Java · 179 lines · 140 code · 16 blank · 23 comment · 34 complexity · 827d88459d9003930f71936620e0ca66 MD5 · raw file

  1. /*
  2. * Copyright 2000-2012 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jetbrains.idea.svn.actions;
  17. import com.intellij.openapi.actionSystem.AnActionEvent;
  18. import com.intellij.openapi.actionSystem.DataContext;
  19. import com.intellij.openapi.actionSystem.PlatformDataKeys;
  20. import com.intellij.openapi.progress.ProgressIndicator;
  21. import com.intellij.openapi.progress.ProgressManager;
  22. import com.intellij.openapi.progress.Task;
  23. import com.intellij.openapi.project.DumbAwareAction;
  24. import com.intellij.openapi.project.Project;
  25. import com.intellij.openapi.ui.DialogWrapper;
  26. import com.intellij.openapi.util.Comparing;
  27. import com.intellij.openapi.util.text.StringUtil;
  28. import com.intellij.openapi.vcs.*;
  29. import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
  30. import com.intellij.openapi.vfs.VirtualFile;
  31. import com.intellij.vcsUtil.ActionExecuteHelper;
  32. import com.intellij.vcsUtil.ActionStateConsumer;
  33. import com.intellij.vcsUtil.ActionUpdateHelper;
  34. import org.jetbrains.annotations.NotNull;
  35. import org.jetbrains.idea.svn.SvnBundle;
  36. import org.jetbrains.idea.svn.SvnPropertyKeys;
  37. import org.jetbrains.idea.svn.SvnVcs;
  38. import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog;
  39. import org.tmatesoft.svn.core.*;
  40. import org.tmatesoft.svn.core.internal.wc.SVNExternal;
  41. import org.tmatesoft.svn.core.wc.*;
  42. import java.io.File;
  43. /**
  44. * Created with IntelliJ IDEA.
  45. * User: Irina.Chernushina
  46. * Date: 7/6/12
  47. * Time: 7:21 PM
  48. */
  49. public class CreateExternalAction extends DumbAwareAction {
  50. public CreateExternalAction() {
  51. super(SvnBundle.message("svn.create.external.below.action"), SvnBundle.message("svn.create.external.below.description"), null);
  52. }
  53. @Override
  54. public void actionPerformed(AnActionEvent e) {
  55. final ActionExecuteHelper helper = new ActionExecuteHelper();
  56. checkState(e, helper);
  57. if (! helper.isOk()) return;
  58. final DataContext dc = e.getDataContext();
  59. final Project project = PlatformDataKeys.PROJECT.getData(dc);
  60. final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc);
  61. //1 select target
  62. final SelectCreateExternalTargetDialog dialog = new SelectCreateExternalTargetDialog(project, vf);
  63. dialog.show();
  64. if (DialogWrapper.OK_EXIT_CODE != dialog.getExitCode()) return;
  65. final String url = dialog.getSelectedURL();
  66. final boolean checkout = dialog.isCheckout();
  67. final String target = dialog.getLocalTarget().trim();
  68. ProgressManager.getInstance().run(new Task.Backgroundable(project, "Creating External", true, null) {
  69. @Override
  70. public void run(@NotNull ProgressIndicator indicator) {
  71. doInBackground(project, vf, url, checkout, target);
  72. }
  73. });
  74. }
  75. private void doInBackground(Project project, VirtualFile vf, String url, boolean checkout, String target) {
  76. final SvnVcs vcs = SvnVcs.getInstance(project);
  77. try {
  78. final SVNURL svnurl = SVNURL.parseURIEncoded(url);
  79. final File ioFile = new File(vf.getPath());
  80. final SVNWCClient wcClient = vcs.createWCClient();
  81. final SVNPropertyData propertyData =
  82. wcClient.doGetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
  83. String newValue;
  84. if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) {
  85. final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString());
  86. for (SVNExternal external : externals) {
  87. if (Comparing.equal(external.getPath(), target)) {
  88. AbstractVcsHelper.getInstance(project).showError(new VcsException("Selected destination conflicts with existing: " + external.toString()), "Create External");
  89. return;
  90. }
  91. }
  92. final String string = createExternalDefinitionString(url, target);
  93. newValue = propertyData.getValue().getString() + "\n" + string;
  94. } else {
  95. newValue = createExternalDefinitionString(url, target);
  96. }
  97. wcClient.doSetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), false, SVNDepth.EMPTY, null, null);
  98. final VcsDirtyScopeManager dirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
  99. final FilePathImpl filePath = new FilePathImpl(ioFile, true);
  100. dirtyScopeManager.fileDirty(filePath);
  101. if (checkout) {
  102. // +-
  103. final SVNUpdateClient client = vcs.createUpdateClient();
  104. client.setEventHandler(new ISVNEventHandler() {
  105. @Override
  106. public void handleEvent(SVNEvent event, double progress) throws SVNException {
  107. }
  108. @Override
  109. public void checkCancelled() throws SVNCancelException {
  110. final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();
  111. if (pi != null && pi.isCanceled()) throw new SVNCancelException();
  112. }
  113. });
  114. client.doUpdate(ioFile, SVNRevision.HEAD, SVNDepth.UNKNOWN, false, false);
  115. vf.refresh(true, true, new Runnable() {
  116. @Override
  117. public void run() {
  118. dirtyScopeManager.dirDirtyRecursively(filePath);
  119. }
  120. });
  121. }
  122. }
  123. catch (SVNException e1) {
  124. AbstractVcsHelper.getInstance(project).showError(new VcsException(e1), "Create External");
  125. }
  126. }
  127. private String createExternalDefinitionString(String url, String target) {
  128. return url + " " + target;
  129. }
  130. @Override
  131. public void update(AnActionEvent e) {
  132. final ActionUpdateHelper helper = new ActionUpdateHelper();
  133. checkState(e, helper);
  134. helper.apply(e);
  135. }
  136. private void checkState(AnActionEvent e, final ActionStateConsumer sc) {
  137. final DataContext dc = e.getDataContext();
  138. final Project project = PlatformDataKeys.PROJECT.getData(dc);
  139. final ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
  140. if (project == null || ! manager.checkVcsIsActive(SvnVcs.getKey().getName())) {
  141. sc.hide();
  142. return;
  143. }
  144. final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(dc);
  145. final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dc);
  146. if (vf == null || files == null || files.length != 1 || ! vf.isDirectory()) {
  147. sc.disable();
  148. return;
  149. }
  150. final AbstractVcs vcsFor = manager.getVcsFor(vf);
  151. if (vcsFor == null || ! SvnVcs.getKey().equals(vcsFor.getKeyInstanceMethod())) {
  152. sc.disable();
  153. return;
  154. }
  155. final FileStatus status = FileStatusManager.getInstance(project).getStatus(vf);
  156. if (status == null || FileStatus.DELETED.equals(status) || FileStatus.IGNORED.equals(status) ||
  157. FileStatus.MERGED_WITH_PROPERTY_CONFLICTS.equals(status) || FileStatus.OBSOLETE.equals(status) || FileStatus.UNKNOWN.equals(status)) {
  158. sc.disable();
  159. return;
  160. }
  161. sc.enable();
  162. }
  163. }