<commit_before>/*******************************************************************************
 * Copyright (c) 2012-2016 <NAME>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   <NAME>. - initial API and implementation
 *******************************************************************************/
package org.eclipse.che.ide.ext.git.client.remove;

import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.git.gwt.client.GitServiceClient;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.app.CurrentProject;
import org.eclipse.che.ide.api.editor.EditorAgent;
import org.eclipse.che.ide.api.editor.EditorPartPresenter;
import org.eclipse.che.ide.api.event.FileEvent;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.project.node.HasStorablePath;
import org.eclipse.che.ide.api.project.node.Node;
import org.eclipse.che.ide.api.project.tree.VirtualFile;
import org.eclipse.che.ide.api.selection.Selection;
import org.eclipse.che.ide.api.selection.SelectionAgent;
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsole;
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsoleFactory;
import org.eclipse.che.ide.extension.machine.client.processes.ConsolesPanelPresenter;
import org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter;
import org.eclipse.che.ide.project.node.FileReferenceNode;
import org.eclipse.che.ide.project.node.FolderReferenceNode;
import org.eclipse.che.ide.project.node.ResourceBasedNode;
import org.eclipse.che.ide.rest.AsyncRequestCallback;

import javax.validation.constraints.NotNull;

import org.eclipse.che.commons.annotation.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;

/**
 * Presenter for removing files from index and file system.
 *
 * @author <NAME>
 */
public class RemoveFromIndexPresenter implements RemoveFromIndexView.ActionDelegate {
    public static final String REMOVE_FROM_INDEX_COMMAND_NAME = "Git remove from index";

    private final RemoveFromIndexView      view;
    private final EventBus                 eventBus;
    private final ProjectExplorerPresenter projectExplorer;
    private final GitServiceClient         service;
    private final GitLocalizationConstant  constant;
    private final AppContext               appContext;
    private final SelectionAgent           selectionAgent;
    private final NotificationManager      notificationManager;
    private final EditorAgent              editorAgent;
    private final GitOutputConsoleFactory  gitOutputConsoleFactory;
    private final ConsolesPanelPresenter   consolesPanelPresenter;

    private CurrentProject            project;
    private List<EditorPartPresenter> openedEditors;

    /**
     * Create presenter
     *
     * @param view
     * @param service
     * @param constant
     * @param appContext
     * @param notificationManager
     */
    @Inject
    public RemoveFromIndexPresenter(RemoveFromIndexView view,
                                    EventBus eventBus,
                                    GitServiceClient service,
                                    GitLocalizationConstant constant,
                                    AppContext appContext,
                                    SelectionAgent selectionAgent,
                                    NotificationManager notificationManager,
                                    EditorAgent editorAgent,
                                    ProjectExplorerPresenter projectExplorer,
                                    GitOutputConsoleFactory gitOutputConsoleFactory,
                                    ConsolesPanelPresenter consolesPanelPresenter) {
        this.view = view;
        this.eventBus = eventBus;
        this.projectExplorer = projectExplorer;
        this.gitOutputConsoleFactory = gitOutputConsoleFactory;
        this.consolesPanelPresenter = consolesPanelPresenter;
        this.view.setDelegate(this);
        this.service = service;
        this.constant = constant;
        this.appContext = appContext;
        this.selectionAgent = selectionAgent;
        this.notificationManager = notificationManager;
        this.editorAgent = editorAgent;
    }

    /** Show dialog. */
    public void showDialog() {
        project = appContext.getCurrentProject();
        String workDir = project.getRootProject().getPath();
        view.setMessage(formMessage(workDir));
        view.setRemoved(false);
        view.showDialog();
    }

    /**
     * Form the message to display for removing from index, telling the user what is gonna to be removed.
     *
     * @return {@link String} message to display
     */
    @NotNull
    private String formMessage(@NotNull String workDir) {
        Selection<ResourceBasedNode<?>> selection = (Selection<ResourceBasedNode<?>>)selectionAgent.getSelection();

        String path;
        if (selection == null || selection.getHeadElement() == null) {
            path = project.getRootProject().getPath();
        } else {
            path = ((HasStorablePath)selection.getHeadElement()).getStorablePath();
        }

        String pattern = path.replaceFirst(workDir, "");
        pattern = (pattern.startsWith("/")) ? pattern.replaceFirst("/", "") : pattern;

        // Root of the working tree:
        if (pattern.isEmpty() || "/".equals(pattern)) {
            return constant.removeFromIndexAll();
        }

        // Do not display path longer 40 characters
        if (pattern.length() > 40) {
            pattern = pattern.substring(0, 40) + "...";
        }

        if (selection != null && selection.getHeadElement() instanceof FolderReferenceNode) {
            return constant.removeFromIndexFolder(pattern).asString();
        } else {
            return constant.removeFromIndexFile(pattern).asString();
        }
    }

    /** {@inheritDoc} */
    @Override
    public void onRemoveClicked() {
        openedEditors = new ArrayList<>();
        for (EditorPartPresenter partPresenter : editorAgent.getOpenedEditors().values()) {
            openedEditors.add(partPresenter);
        }
        final GitOutputConsole console = gitOutputConsoleFactory.create(REMOVE_FROM_INDEX_COMMAND_NAME);
        service.remove(appContext.getWorkspaceId(), project.getRootProject(), getFilePatterns(), view.isRemoved(),
                       new AsyncRequestCallback<String>() {
                           @Override
                           protected void onSuccess(String result) {
                               console.printInfo(constant.removeFilesSuccessfull());
                               consolesPanelPresenter.addCommandOutput(appContext.getDevMachineId(), console);
                               notificationManager.notify(constant.removeFilesSuccessfull(), project.getRootProject());

                               if (!view.isRemoved()) {
                                   projectExplorer.reloadChildren(getResourceBasedNode());

                                   if (projectExplorer.getSelection().getHeadElement() instanceof FileReferenceNode) {
                                       FileReferenceNode selectFile = ((FileReferenceNode)projectExplorer.getSelection().getHeadElement());
                                       for (EditorPartPresenter partPresenter : openedEditors) {
                                           VirtualFile openFile = partPresenter.getEditorInput().getFile();
                                           //to close selected file if it open
                                           if (selectFile.getStorablePath().equals(openFile.getPath())) {
                                               eventBus.fireEvent(new FileEvent(openFile, FileEvent.FileOperation.CLOSE));
                                           }
                                       }
                                   }
                               }
                           }

                           @Override
                           protected void onFailure(Throwable exception) {
                               handleError(exception, console);
                               consolesPanelPresenter.addCommandOutput(appContext.getDevMachineId(), console);
                           }
                       }
                      );
        view.close();
    }

    @Nullable
    protected ResourceBasedNode<?> getResourceBasedNode() {
        List<?> selection = projectExplorer.getSelection().getAllElements();
        //we should be sure that user selected single element to work with it
        if (selection != null && selection.size() > 1) {

            Object o = selection.get(0);

            if (o instanceof ResourceBasedNode<?>) {
                ResourceBasedNode<?> node = (ResourceBasedNode<?>)o;
                //it may be file node, so we should take parent node
                if (node.isLeaf() && isResourceAndStorableNode(node.getParent())) {
                    return (ResourceBasedNode<?>)node.getParent();
                }

                return isResourceAndStorableNode(node) ? node : null;
            }
        }
        return null;
    }

    protected boolean isResourceAndStorableNode(@Nullable Node node) {
        return node != null && node instanceof ResourceBasedNode<?> && node instanceof HasStorablePath;
    }

    /**
     * Returns pattern of the items to be removed.<commit_msg>IDEX-3531: Item is removed from project tree after remove from index<commit_after>/*******************************************************************************
 * Copyright (c) 2012-2016 <NAME>.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   <NAME>. - initial API and implementation
 *******************************************************************************/
package org.eclipse.che.ide.ext.git.client.remove;

import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.git.gwt.client.GitServiceClient;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.app.CurrentProject;
import org.eclipse.che.ide.api.editor.EditorAgent;
import org.eclipse.che.ide.api.editor.EditorPartPresenter;
import org.eclipse.che.ide.api.event.FileEvent;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.project.node.HasStorablePath;
import org.eclipse.che.ide.api.project.node.Node;
import org.eclipse.che.ide.api.project.tree.VirtualFile;
import org.eclipse.che.ide.api.selection.Selection;
import org.eclipse.che.ide.api.selection.SelectionAgent;
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsole;
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsoleFactory;
import org.eclipse.che.ide.extension.machine.client.processes.ConsolesPanelPresenter;
import org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter;
import org.eclipse.che.ide.project.node.FileReferenceNode;
import org.eclipse.che.ide.project.node.FolderReferenceNode;
import org.eclipse.che.ide.project.node.ResourceBasedNode;
import org.eclipse.che.ide.rest.AsyncRequestCallback;

import javax.validation.constraints.NotNull;

import org.eclipse.che.commons.annotation.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;

/**
 * Presenter for removing files from index and file system.
 *
 * @author <NAME>
 */
public class RemoveFromIndexPresenter implements RemoveFromIndexView.ActionDelegate {
    public static final String REMOVE_FROM_INDEX_COMMAND_NAME = "Git remove from index";

    private final RemoveFromIndexView      view;
    private final EventBus                 eventBus;
    private final ProjectExplorerPresenter projectExplorer;
    private final GitServiceClient         service;
    private final GitLocalizationConstant  constant;
    private final AppContext               appContext;
    private final SelectionAgent           selectionAgent;
    private final NotificationManager      notificationManager;
    private final EditorAgent              editorAgent;
    private final GitOutputConsoleFactory  gitOutputConsoleFactory;
    private final ConsolesPanelPresenter   consolesPanelPresenter;

    private CurrentProject            project;
    private List<EditorPartPresenter> openedEditors;

    /**
     * Create presenter
     *
     * @param view
     * @param service
     * @param constant
     * @param appContext
     * @param notificationManager
     */
    @Inject
    public RemoveFromIndexPresenter(RemoveFromIndexView view,
                                    EventBus eventBus,
                                    GitServiceClient service,
                                    GitLocalizationConstant constant,
                                    AppContext appContext,
                                    SelectionAgent selectionAgent,
                                    NotificationManager notificationManager,
                                    EditorAgent editorAgent,
                                    ProjectExplorerPresenter projectExplorer,
                                    GitOutputConsoleFactory gitOutputConsoleFactory,
                                    ConsolesPanelPresenter consolesPanelPresenter) {
        this.view = view;
        this.eventBus = eventBus;
        this.projectExplorer = projectExplorer;
        this.gitOutputConsoleFactory = gitOutputConsoleFactory;
        this.consolesPanelPresenter = consolesPanelPresenter;
        this.view.setDelegate(this);
        this.service = service;
        this.constant = constant;
        this.appContext = appContext;
        this.selectionAgent = selectionAgent;
        this.notificationManager = notificationManager;
        this.editorAgent = editorAgent;
    }

    /** Show dialog. */
    public void showDialog() {
        project = appContext.getCurrentProject();
        String workDir = project.getRootProject().getPath();
        view.setMessage(formMessage(workDir));
        view.setRemoved(false);
        view.showDialog();
    }

    /**
     * Form the message to display for removing from index, telling the user what is gonna to be removed.
     *
     * @return {@link String} message to display
     */
    @NotNull
    private String formMessage(@NotNull String workDir) {
        Selection<ResourceBasedNode<?>> selection = (Selection<ResourceBasedNode<?>>)selectionAgent.getSelection();

        String path;
        if (selection == null || selection.getHeadElement() == null) {
            path = project.getRootProject().getPath();
        } else {
            path = ((HasStorablePath)selection.getHeadElement()).getStorablePath();
        }

        String pattern = path.replaceFirst(workDir, "");
        pattern = (pattern.startsWith("/")) ? pattern.replaceFirst("/", "") : pattern;

        // Root of the working tree:
        if (pattern.isEmpty() || "/".equals(pattern)) {
            return constant.removeFromIndexAll();
        }

        // Do not display path longer 40 characters
        if (pattern.length() > 40) {
            pattern = pattern.substring(0, 40) + "...";
        }

        if (selection != null && selection.getHeadElement() instanceof FolderReferenceNode) {
            return constant.removeFromIndexFolder(pattern).asString();
        } else {
            return constant.removeFromIndexFile(pattern).asString();
        }
    }

    /** {@inheritDoc} */
    @Override
    public void onRemoveClicked() {
        openedEditors = new ArrayList<>();
        for (EditorPartPresenter partPresenter : editorAgent.getOpenedEditors().values()) {
            openedEditors.add(partPresenter);
        }
        final GitOutputConsole console = gitOutputConsoleFactory.create(REMOVE_FROM_INDEX_COMMAND_NAME);
        service.remove(appContext.getWorkspaceId(), project.getRootProject(), getFilePatterns(), view.isRemoved(),
                       new AsyncRequestCallback<String>() {
                           @Override
                           protected void onSuccess(String result) {
                               console.printInfo(constant.removeFilesSuccessfull());
                               consolesPanelPresenter.addCommandOutput(appContext.getDevMachineId(), console);
                               notificationManager.notify(constant.removeFilesSuccessfull(), project.getRootProject());

                               if (!view.isRemoved()) {
                                   projectExplorer.reloadChildren(getResourceBasedNode());

                                   if (projectExplorer.getSelection().getHeadElement() instanceof FileReferenceNode) {
                                       FileReferenceNode selectFile = ((FileReferenceNode)projectExplorer.getSelection().getHeadElement());
                                       for (EditorPartPresenter partPresenter : openedEditors) {
                                           VirtualFile openFile = partPresenter.getEditorInput().getFile();
                                           //to close selected file if it open
                                           if (selectFile.getStorablePath().equals(openFile.getPath())) {
                                               eventBus.fireEvent(new FileEvent(openFile, FileEvent.FileOperation.CLOSE));
                                           }
                                       }
                                   }
                               }
                           }

                           @Override
                           protected void onFailure(Throwable exception) {
                               handleError(exception, console);
                               consolesPanelPresenter.addCommandOutput(appContext.getDevMachineId(), console);
                           }
                       }
                      );
        view.close();
    }

    @Nullable
    protected ResourceBasedNode<?> getResourceBasedNode() {
        List<?> selection = projectExplorer.getSelection().getAllElements();
        //we should be sure that user selected single element to work with it
        if (selection != null && !selection.isEmpty()) {

            Object o = selection.get(0);

            if (o instanceof ResourceBasedNode<?>) {
                ResourceBasedNode<?> node = (ResourceBasedNode<?>)o;
                //it may be file node, so we should take parent node
                if (node.isLeaf() && isResourceAndStorableNode(node.getParent())) {
                    return (ResourceBasedNode<?>)node.getParent();
                }

                return isResourceAndStorableNode(node) ? node : null;
            }
        }
        return null;
    }

    protected boolean isResourceAndStorableNode(@Nullable Node node) {
        return node != null && node instanceof ResourceBasedNode<?> && node instanceof HasStorablePath;
    }

    /**
     * Returns pattern of the items to be removed.
{'fraction_non_alphanumeric': 0.10239894507277983, 'fraction_numerical': 0.0022822944667038594, 'mean_word_length': 2.193198380566802, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 54, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2411302', 'n_tokens_mistral': 4680, 'n_tokens_neox': 4528, 'n_words': 982}