vcs: extract method
authorAleksey Pivovarov <AMPivovarov@gmail.com>
Tue, 25 Aug 2015 17:07:17 +0000 (20:07 +0300)
committerAleksey Pivovarov <AMPivovarov@gmail.com>
Mon, 31 Aug 2015 09:50:35 +0000 (12:50 +0300)
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/BinaryFilePatchInProgress.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchDiffRequestFactory.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/TextFilePatchInProgress.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesAction.java

index bd7b9de674b6ae0609da0107b457f4676105a003..dfc3cf7c99e8f568c317ad3e7ae2e0815f963787 100644 (file)
@@ -23,7 +23,6 @@
 package com.intellij.openapi.vcs.changes.patch;
 
 import com.intellij.diff.DiffManager;
-import com.intellij.diff.DiffRequestFactory;
 import com.intellij.diff.InvalidDiffRequestException;
 import com.intellij.diff.merge.MergeRequest;
 import com.intellij.diff.merge.MergeResult;
@@ -47,6 +46,7 @@ import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Getter;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsApplicationSettings;
 import com.intellij.openapi.vcs.VcsBundle;
 import com.intellij.openapi.vcs.changes.ChangeListManager;
@@ -156,11 +156,52 @@ public class ApplyPatchAction extends DumbAwareAction {
     final ApplyPatchForBaseRevisionTexts mergeData = result.getMergeData();
     if (mergeData == null) return status;
 
-    if (mergeData.getBase() != null) {
-      return showMergeDialog(project, file, mergeData.getBase(), mergeData.getPatched(), reverse, leftPanelTitle, rightPanelTitle);
+    final Document document = FileDocumentManager.getInstance().getDocument(file);
+    if (document == null) return ApplyPatchStatus.FAILURE;
+
+    String baseContent = toString(mergeData.getBase());
+    String localContent = toString(mergeData.getLocal());
+    String patchedContent = mergeData.getPatched();
+
+    if (localContent == null) return ApplyPatchStatus.FAILURE;
+
+    final Ref<Boolean> successRef = new Ref<Boolean>();
+    Consumer<MergeResult> callback = new Consumer<MergeResult>() {
+      @Override
+      public void consume(MergeResult result) {
+        FileDocumentManager.getInstance().saveDocument(document);
+        successRef.set(result != MergeResult.CANCEL);
+      }
+    };
+
+    try {
+      MergeRequest request;
+      if (baseContent != null) {
+        if (reverse) {
+          if (leftPanelTitle == null) leftPanelTitle = VcsBundle.message("patch.apply.conflict.patched.version");
+          if (rightPanelTitle == null) rightPanelTitle = VcsBundle.message("patch.apply.conflict.local.version");
+
+          List<String> contents = ContainerUtil.list(patchedContent, baseContent, localContent);
+          List<String> titles = ContainerUtil.list(leftPanelTitle, null, rightPanelTitle);
+
+          request = PatchDiffRequestFactory
+            .createMergeRequest(project, document, file, contents, null, titles, callback);
+        }
+        else {
+          request = PatchDiffRequestFactory
+            .createMergeRequest(project, document, file, baseContent, localContent, patchedContent, callback);
+        }
+      }
+      else {
+        request = PatchDiffRequestFactory.createBadMergeRequest(project, document, file, localContent, patchedContent, callback);
+      }
+
+      DiffManager.getInstance().showMerge(project, request);
+      return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
     }
-    else {
-      return showBadMergeDialog(project, file, mergeData);
+    catch (InvalidDiffRequestException e) {
+      LOG.warn(e);
+      return ApplyPatchStatus.FAILURE;
     }
   }
 
@@ -194,76 +235,8 @@ public class ApplyPatchAction extends DumbAwareAction {
       });
   }
 
-  @NotNull
-  private static ApplyPatchStatus showMergeDialog(@Nullable Project project,
-                                                  @NotNull VirtualFile file,
-                                                  @Nullable CharSequence content,
-                                                  @NotNull final String patchedContent,
-                                                  boolean reverse,
-                                                  @Nullable String leftPanelTitle,
-                                                  @Nullable String rightPanelTitle) {
-    Document document = FileDocumentManager.getInstance().getDocument(file);
-    if (content == null || document == null) {
-      return ApplyPatchStatus.FAILURE;
-    }
-
-    List<String> titles = ContainerUtil.list(
-      leftPanelTitle == null ? VcsBundle.message("patch.apply.conflict.local.version") : leftPanelTitle,
-      rightPanelTitle == null ? VcsBundle.message("patch.apply.conflict.merged.version") : rightPanelTitle,
-      VcsBundle.message("patch.apply.conflict.patched.version"));
-    String windowTitle = VcsBundle.message("patch.apply.conflict.title", file.getPresentableUrl());
-
-    final String leftText = document.getText();
-    List<String> contents = ContainerUtil.list(reverse ? patchedContent : leftText,
-                                               content.toString(),
-                                               reverse ? leftText : patchedContent);
-
-    final Ref<Boolean> successRef = new Ref<Boolean>();
-    final Consumer<MergeResult> callback = new Consumer<MergeResult>() {
-      @Override
-      public void consume(MergeResult result) {
-        successRef.set(result != MergeResult.CANCEL);
-      }
-    };
-
-    try {
-      MergeRequest request = DiffRequestFactory.getInstance()
-        .createMergeRequest(project, file.getFileType(), document, contents, windowTitle, titles, callback);
-
-      DiffManager.getInstance().showMerge(project, request);
-
-      return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
-    }
-    catch (InvalidDiffRequestException e) {
-      LOG.warn(e);
-      return ApplyPatchStatus.FAILURE;
-    }
-  }
-
-  @NotNull
-  private static ApplyPatchStatus showBadMergeDialog(@Nullable Project project,
-                                                     @NotNull VirtualFile file,
-                                                     @NotNull final ApplyPatchForBaseRevisionTexts texts) {
-    final Document document = FileDocumentManager.getInstance().getDocument(file);
-    if (texts.getLocal() == null || document == null) return ApplyPatchStatus.FAILURE;
-
-    final String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
-    final String windowTitle = "Result Of Patch Apply To " + file.getName() + " (" + fullPath + ")";
-
-    final Ref<Boolean> successRef = new Ref<Boolean>();
-    Consumer<MergeResult> callback = new Consumer<MergeResult>() {
-      @Override
-      public void consume(MergeResult result) {
-        FileDocumentManager.getInstance().saveDocument(document);
-        successRef.set(true);
-      }
-    };
-
-    MergeRequest request = new ApplyPatchMergeRequest(project, document, file, texts.getLocal().toString(), texts.getPatched(), windowTitle,
-                                                      VcsBundle.message("diff.title.local"), "Patched (with problems)", callback);
-
-    DiffManager.getInstance().showMerge(project, request);
-
-    return successRef.get() == Boolean.TRUE ? ApplyPatchStatus.SUCCESS : ApplyPatchStatus.FAILURE;
+  @Nullable
+  private static String toString(@Nullable CharSequence charSequence) {
+    return charSequence != null ? StringUtil.convertLineSeparators(charSequence.toString()) : null;
   }
 }
index 639bb0af649c8a4042be9b5534afd730a4bcf9a2..3537525a9e08d052e24e13df86aae6a833b78e17 100644 (file)
@@ -69,7 +69,7 @@ public class BinaryFilePatchInProgress extends AbstractFilePatchInProgress<Shelv
       public DiffRequest process(@NotNull UserDataHolder context, @NotNull ProgressIndicator indicator)
         throws DiffRequestProducerException, ProcessCanceledException {
         Change change = file.createChange(project);
-        return PatchDiffRequestFactory.createFromChange(project, change, getName(), context, indicator);
+        return PatchDiffRequestFactory.createDiffRequest(project, change, getName(), context, indicator);
       }
 
       @NotNull
index 5887c2e43693237ca866892221dfe22a5f806f51..dab1ef30d518e5e8ffb19a1bcaac7f76c72ed18a 100644 (file)
 package com.intellij.openapi.vcs.changes.patch;
 
 import com.intellij.diff.DiffContentFactory;
+import com.intellij.diff.DiffRequestFactory;
+import com.intellij.diff.InvalidDiffRequestException;
 import com.intellij.diff.chains.DiffRequestProducerException;
-import com.intellij.diff.contents.DiffContent;
 import com.intellij.diff.contents.DocumentContent;
+import com.intellij.diff.merge.MergeRequest;
+import com.intellij.diff.merge.MergeResult;
 import com.intellij.diff.requests.DiffRequest;
 import com.intellij.diff.requests.SimpleDiffRequest;
 import com.intellij.diff.util.DiffUtil;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Getter;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.UserDataHolder;
-import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsBundle;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -42,24 +47,24 @@ import java.util.List;
 
 public class PatchDiffRequestFactory {
   @NotNull
-  public static DiffRequest createFromChange(@Nullable Project project,
-                                             @NotNull Change change,
-                                             @NotNull String name,
-                                             @NotNull UserDataHolder context,
-                                             @NotNull ProgressIndicator indicator)
+  public static DiffRequest createDiffRequest(@Nullable Project project,
+                                              @NotNull Change change,
+                                              @NotNull String name,
+                                              @NotNull UserDataHolder context,
+                                              @NotNull ProgressIndicator indicator)
     throws DiffRequestProducerException {
     ChangeDiffRequestProducer proxyProducer = ChangeDiffRequestProducer.create(project, change);
     if (proxyProducer == null) throw new DiffRequestProducerException("Can't show diff for '" + name + "'");
     return proxyProducer.process(context, indicator);
   }
 
-  public static DiffRequest createConflict(@Nullable Project project,
-                                           @Nullable VirtualFile file,
-                                           @NotNull String afterTitle,
-                                           @NotNull final Getter<ApplyPatchForBaseRevisionTexts> textsGetter,
-                                           @NotNull String name,
-                                           @NotNull UserDataHolder context,
-                                           @NotNull ProgressIndicator indicator)
+  public static DiffRequest createConflictDiffRequest(@Nullable Project project,
+                                                      @Nullable VirtualFile file,
+                                                      @NotNull String afterTitle,
+                                                      @NotNull final Getter<ApplyPatchForBaseRevisionTexts> textsGetter,
+                                                      @NotNull String name,
+                                                      @NotNull UserDataHolder context,
+                                                      @NotNull ProgressIndicator indicator)
     throws DiffRequestProducerException {
     if (file == null) throw new DiffRequestProducerException("Can't show diff for '" + name + "'");
     if (file.getFileType().isBinary()) throw new DiffRequestProducerException("Can't show diff for binary file '" + name + "'");
@@ -73,49 +78,173 @@ public class PatchDiffRequestFactory {
     }, indicator.getModalityState());
     ApplyPatchForBaseRevisionTexts texts = textsRef.get();
 
+    if (texts.getLocal() == null) throw new DiffRequestProducerException("Can't show diff for '" + file.getPresentableUrl() + "'");
+
     if (texts.getBase() == null) {
-      return createBadDiffRequest(project, file, texts);
+      String localContent = texts.getLocal().toString();
+      String patchedContent = texts.getPatched();
+
+      return createBadDiffRequest(project, file, localContent, patchedContent, null, null, null);
     }
     else {
-      String path = FileUtil.toSystemDependentName(file.getPresentableUrl());
-      FileType type = file.getFileType();
-
-      String windowTitle = VcsBundle.message("patch.apply.conflict.title", path);
+      String localContent = texts.getLocal().toString();
+      String baseContent = texts.getBase().toString();
+      String patchedContent = texts.getPatched();
 
-      DiffContentFactory contentFactory = DiffContentFactory.getInstance();
-      DocumentContent localContent = contentFactory.createDocument(project, file);
-      if (localContent == null) localContent = contentFactory.create(texts.getLocal().toString(), type);
-      DocumentContent baseContent = contentFactory.create(texts.getBase().toString(), type);
-      DocumentContent patchedContent = contentFactory.create(texts.getPatched(), type);
-
-      return new SimpleDiffRequest(windowTitle, localContent, baseContent, patchedContent,
-                                   "Current Version", "Base Version", afterTitle);
+      return createDiffRequest(project, file, ContainerUtil.list(localContent, baseContent, patchedContent), null,
+                               ContainerUtil.list("Current Version", "Base Version", afterTitle));
     }
   }
 
   @NotNull
-  public static DiffRequest createBadDiffRequest(@Nullable Project project,
-                                                 @NotNull final VirtualFile file,
-                                                 @NotNull final ApplyPatchForBaseRevisionTexts texts) throws DiffRequestProducerException {
-    if (texts.getLocal() == null) {
-      throw new DiffRequestProducerException("Can't show diff for '" + file.getPresentableUrl() + "'");
-    }
+  public static DiffRequest createDiffRequest(@Nullable Project project,
+                                              @Nullable VirtualFile file,
+                                              @NotNull List<String> contents,
+                                              @Nullable String windowTitle,
+                                              @NotNull List<String> titles) {
+    assert contents.size() == 3;
+    assert titles.size() == 3;
+
+    if (windowTitle == null) windowTitle = getPatchTitle(file);
+
+    String localTitle = StringUtil.notNullize(titles.get(0), VcsBundle.message("patch.apply.conflict.local.version"));
+    String baseTitle = StringUtil.notNullize(titles.get(1), "Base Version");
+    String patchedTitle = StringUtil.notNullize(titles.get(2), VcsBundle.message("patch.apply.conflict.patched.version"));
+
+    FileType fileType = file != null ? file.getFileType() : null;
+
+    DiffContentFactory contentFactory = DiffContentFactory.getInstance();
+    DocumentContent localContent = file != null ? contentFactory.createDocument(project, file) : null;
+    if (localContent == null) localContent = contentFactory.create(contents.get(0), fileType);
+    DocumentContent baseContent = contentFactory.create(contents.get(1), fileType);
+    DocumentContent patchedContent = contentFactory.create(contents.get(2), fileType);
+
+    return new SimpleDiffRequest(windowTitle, localContent, baseContent, patchedContent,
+                                 localTitle, baseTitle, patchedTitle);
+  }
 
-    final String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
-    final String windowTitle = "Result Of Patch Apply To " + file.getName() + " (" + fullPath + ")";
-    final List<String> titles = ContainerUtil.list(VcsBundle.message("diff.title.local"), "Patched (with problems)");
+  @NotNull
+  public static DiffRequest createBadDiffRequest(@Nullable Project project,
+                                                 @Nullable VirtualFile file,
+                                                 @NotNull String localContent,
+                                                 @NotNull String patchedContent,
+                                                 @Nullable String windowTitle,
+                                                 @Nullable String localTitle,
+                                                 @Nullable String patchedTitle) {
+    if (windowTitle == null) windowTitle = getBadPatchTitle(file);
+    if (localTitle == null) localTitle = VcsBundle.message("patch.apply.conflict.local.version");
+    if (patchedTitle == null) patchedTitle = "Patched (with problems)";
+
+    FileType fileType = file != null ? file.getFileType() : null;
 
     final DiffContentFactory contentFactory = DiffContentFactory.getInstance();
-    DocumentContent localContent = contentFactory.createDocument(project, file);
-    if (localContent == null) localContent = contentFactory.create(texts.getLocal().toString(), file.getFileType());
-    final DiffContent mergedContent = contentFactory.create(texts.getPatched(), file.getFileType());
+    DocumentContent leftContent = file != null ? contentFactory.createDocument(project, file) : null;
+    if (leftContent == null) leftContent = contentFactory.create(localContent, fileType);
+    DocumentContent rightContent = contentFactory.create(patchedContent, fileType);
 
-    final List<DiffContent> contents = ContainerUtil.list(localContent, mergedContent);
-
-    final DiffRequest request = new SimpleDiffRequest(windowTitle, contents, titles);
+    final DiffRequest request = new SimpleDiffRequest(windowTitle, leftContent, rightContent, localTitle, patchedTitle);
     DiffUtil.addNotification(new ApplyPatchMergeTool.DiffIsApproximateNotification(), request);
 
     return request;
   }
+
+  @NotNull
+  public static MergeRequest createMergeRequest(@Nullable Project project,
+                                                @NotNull Document document,
+                                                @NotNull VirtualFile file,
+                                                @NotNull String baseContent,
+                                                @NotNull String localContent,
+                                                @NotNull String patchedContent,
+                                                @Nullable Consumer<MergeResult> callback)
+    throws InvalidDiffRequestException {
+    List<String> titles = ContainerUtil.list(null, null, null);
+    List<String> contents = ContainerUtil.list(localContent, baseContent, patchedContent);
+
+    return createMergeRequest(project, document, file, contents, null, titles, callback);
+  }
+
+  @NotNull
+  public static MergeRequest createBadMergeRequest(@Nullable Project project,
+                                                   @NotNull Document document,
+                                                   @NotNull VirtualFile file,
+                                                   @NotNull String localContent,
+                                                   @NotNull String patchedContent,
+                                                   @Nullable Consumer<MergeResult> callback)
+    throws InvalidDiffRequestException {
+    return createBadMergeRequest(project, document, file, localContent, patchedContent, null, null, null, callback);
+  }
+
+  @NotNull
+  public static MergeRequest createMergeRequest(@Nullable Project project,
+                                                @NotNull Document document,
+                                                @Nullable VirtualFile file,
+                                                @NotNull List<String> contents,
+                                                @Nullable String windowTitle,
+                                                @NotNull List<String> titles,
+                                                @Nullable Consumer<MergeResult> callback)
+    throws InvalidDiffRequestException {
+    assert contents.size() == 3;
+    assert titles.size() == 3;
+
+    if (windowTitle == null) windowTitle = getPatchTitle(file);
+
+    String localTitle = StringUtil.notNullize(titles.get(0), VcsBundle.message("patch.apply.conflict.local.version"));
+    String baseTitle = StringUtil.notNullize(titles.get(1), VcsBundle.message("patch.apply.conflict.merged.version"));
+    String patchedTitle = StringUtil.notNullize(titles.get(2), VcsBundle.message("patch.apply.conflict.patched.version"));
+
+    List<String> actualTitles = ContainerUtil.list(localTitle, baseTitle, patchedTitle);
+
+    FileType fileType = file != null ? file.getFileType() : null;
+    return DiffRequestFactory.getInstance().createMergeRequest(project, fileType, document, contents, windowTitle, actualTitles, callback);
+  }
+
+  @NotNull
+  public static MergeRequest createBadMergeRequest(@Nullable Project project,
+                                                   @NotNull Document document,
+                                                   @Nullable VirtualFile file,
+                                                   @NotNull String localContent,
+                                                   @NotNull String patchedContent,
+                                                   @Nullable String windowTitle,
+                                                   @Nullable String localTitle,
+                                                   @Nullable String patchedTitle,
+                                                   @Nullable Consumer<MergeResult> callback)
+    throws InvalidDiffRequestException {
+    if (!DiffUtil.canMakeWritable(document)) {
+      throw new InvalidDiffRequestException("Output is read only" + (file != null ? " : '" + file.getPresentableUrl() +"'": ""));
+    }
+
+    if (windowTitle == null) windowTitle = getBadPatchTitle(file);
+    if (localTitle == null) localTitle = VcsBundle.message("patch.apply.conflict.local.version");
+    if (patchedTitle == null) patchedTitle = "Patched (with problems)";
+
+    return new ApplyPatchMergeRequest(project, document, localContent, patchedContent, windowTitle, localTitle, patchedTitle, callback);
+  }
+
+  @NotNull
+  private static String getPatchTitle(@Nullable VirtualFile file) {
+    if (file != null) {
+      return VcsBundle.message("patch.apply.conflict.title", getPresentablePath(file));
+    }
+    else {
+      return "Patch Conflict";
+    }
+  }
+
+
+  @NotNull
+  private static String getBadPatchTitle(@Nullable VirtualFile file) {
+    if (file != null) {
+      return "Result Of Patch Apply To " + getPresentablePath(file);
+    }
+    else {
+      return "Result Of Patch Apply";
+    }
+  }
+
+  @NotNull
+  private static String getPresentablePath(@NotNull VirtualFile file) {
+    String fullPath = file.getParent() == null ? file.getPath() : file.getParent().getPath();
+    return file.getName() + " (" + fullPath + ")";
+  }
 }
 
index f508220c18b8fa6077b33a8154b4f27089d94eac..c080f456171ef44218cd3097d68f0ffa7607d91f 100644 (file)
@@ -105,10 +105,10 @@ public class TextFilePatchInProgress extends AbstractFilePatchInProgress<TextFil
 
           String afterTitle = getPatch().getAfterVersionId();
           if (afterTitle == null) afterTitle = "Patched Version";
-          return PatchDiffRequestFactory.createConflict(project, file, afterTitle, getter, getName(), context, indicator);
+          return PatchDiffRequestFactory.createConflictDiffRequest(project, file, afterTitle, getter, getName(), context, indicator);
         }
         else {
-          return PatchDiffRequestFactory.createFromChange(project, change, getName(), context, indicator);
+          return PatchDiffRequestFactory.createDiffRequest(project, change, getName(), context, indicator);
         }
       }
 
index 6b75622dc17ec9e4c167a98c125ab5c8958f16fb..768e267dc2d0dbcb4f8cab89157bc81148dfe009 100644 (file)
@@ -145,7 +145,7 @@ public class DiffShelvedChangesAction extends AnAction implements DumbAware {
         public DiffRequest process(@NotNull UserDataHolder context, @NotNull ProgressIndicator indicator)
           throws DiffRequestProducerException, ProcessCanceledException {
           Change change = shelvedChange.createChange(project);
-          return PatchDiffRequestFactory.createFromChange(project, change, getName(), context, indicator);
+          return PatchDiffRequestFactory.createDiffRequest(project, change, getName(), context, indicator);
         }
 
         @NotNull
@@ -221,7 +221,7 @@ public class DiffShelvedChangesAction extends AnAction implements DumbAware {
                 }
               };
 
-              return PatchDiffRequestFactory.createConflict(project, file, "Shelved Version", getter, getName(), context, indicator);
+              return PatchDiffRequestFactory.createConflictDiffRequest(project, file, "Shelved Version", getter, getName(), context, indicator);
             }
             catch (VcsException e) {
               throw new DiffRequestProducerException("Can't show diff for '" + getName() + "'", e);
@@ -229,7 +229,7 @@ public class DiffShelvedChangesAction extends AnAction implements DumbAware {
           }
           else {
             final Change change = shelvedChange.getChange(project);
-            return PatchDiffRequestFactory.createFromChange(project, change, getName(), context, indicator);
+            return PatchDiffRequestFactory.createDiffRequest(project, change, getName(), context, indicator);
           }
         }
       });