/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.jetbrains.idea.svn.actions;

import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnVcs;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

import static com.intellij.openapi.application.ApplicationManager.getApplication;
import static com.intellij.util.ArrayUtil.isEmpty;

public abstract class BasicAction extends AnAction implements DumbAware {

  @Override
  public void actionPerformed(@NotNull AnActionEvent e) {
    Project project = e.getData(CommonDataKeys.PROJECT);
    VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
    if (isEmpty(files)) return;

    SvnVcs vcs = SvnVcs.getInstance(project);
    if (!ProjectLevelVcsManager.getInstance(project).checkAllFilesAreUnder(vcs, files)) return;

    project.save();

    String actionName = getActionName();
    LocalHistoryAction action = LocalHistory.getInstance().startAction(actionName);
    AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project);

    try {
      List<VcsException> exceptions = helper.runTransactionRunnable(vcs, exceptionList -> {
        VirtualFile badFile = null;
        try {
          if (isBatchAction()) {
            batchExecute(vcs, files, e.getDataContext());
          }
          else {
            for (VirtualFile file : files) {
              badFile = file;
              execute(vcs, file, e.getDataContext());
            }
          }
        }
        catch (VcsException ex) {
          ex.setVirtualFile(badFile);
          exceptionList.add(ex);
        }
      }, null);

      helper.showErrors(exceptions, actionName);
    }
    finally {
      action.finish();
    }
  }

  @Override
  public void update(@NotNull AnActionEvent e) {
    Project project = e.getProject();
    SvnVcs vcs = project != null ? SvnVcs.getInstance(project) : null;
    VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
    boolean visible = project != null;

    e.getPresentation().setEnabled(visible && vcs != null && !isEmpty(files) && isEnabled(vcs, files));
    e.getPresentation().setVisible(visible);
  }

  protected boolean needsAllFiles() {
    return true;
  }

  protected void execute(@NotNull SvnVcs vcs, @NotNull VirtualFile file, @NotNull DataContext context) throws VcsException {
    perform(vcs, file, context);

    getApplication().runWriteAction(() -> file.refresh(false, true));
    doVcsRefresh(vcs, file);
  }

  protected void doVcsRefresh(@NotNull SvnVcs vcs, @NotNull VirtualFile file) {
    VcsDirtyScopeManager.getInstance(vcs.getProject()).fileDirty(file);
  }

  private void batchExecute(@NotNull SvnVcs vcs, @NotNull VirtualFile[] files, @NotNull DataContext context) throws VcsException {
    batchPerform(vcs, files, context);

    getApplication().runWriteAction(() -> {
      for (VirtualFile file : files) {
        file.refresh(false, true);
      }
    });
    for (VirtualFile file : files) {
      doVcsRefresh(vcs, file);
    }
  }

  @NotNull
  protected abstract String getActionName();

  protected boolean isEnabled(@NotNull SvnVcs vcs, @NotNull VirtualFile[] files) {
    Stream<VirtualFile> fileStream = Stream.of(files);
    Predicate<VirtualFile> enabledPredicate = file -> isEnabled(vcs, file);

    return ProjectLevelVcsManager.getInstance(vcs.getProject()).checkAllFilesAreUnder(vcs, files) &&
           (needsAllFiles() ? fileStream.allMatch(enabledPredicate) : fileStream.anyMatch(enabledPredicate));
  }

  protected abstract boolean isEnabled(@NotNull SvnVcs vcs, @NotNull VirtualFile file);

  protected abstract void perform(@NotNull SvnVcs vcs, @NotNull VirtualFile file, @NotNull DataContext context) throws VcsException;

  protected abstract void batchPerform(@NotNull SvnVcs vcs, @NotNull VirtualFile[] files, @NotNull DataContext context) throws VcsException;

  protected abstract boolean isBatchAction();
}

@@ -1,13 +1,10 @@
 /
-*%0A *
+/
  Copyrig
@@ -17,10 +17,10 @@
 0-20
-09
+18
  Jet
@@ -36,566 +36,109 @@
 r.o.
-%0A *%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A *%0A * http://www.apache.org/licenses/LICENSE-2.0%0A *%0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A */
+ Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 %0A%0A%0Ap
@@ -1124,30 +1124,210 @@
 lij.
-util.ArrayUtil.isEmpty
+openapi.util.text.StringUtil.trimEnd;%0Aimport static com.intellij.util.ArrayUtil.isEmpty;%0Aimport static com.intellij.util.ui.SwingHelper.ELLIPSIS;%0Aimport static com.intellij.util.ui.UIUtil.removeMnemonic
 ;%0A%0Ap
@@ -1820,16 +1820,39 @@
 nName = 
+removeMnemonic(trimEnd(
 getActio
@@ -1858,16 +1858,28 @@
 onName()
+, ELLIPSIS))
 ;%0A    Lo

Fix "Messages" tool window tab names for svn actions errors