/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.command.execute; import com.google.gwt.core.client.Callback; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; import org.eclipse.che.ide.api.action.Action; import org.eclipse.che.ide.api.action.ActionManager; import org.eclipse.che.ide.api.action.DefaultActionGroup; import org.eclipse.che.ide.api.command.CommandAddedEvent; import org.eclipse.che.ide.api.command.CommandGoalRegistry; import org.eclipse.che.ide.api.command.CommandImpl; import org.eclipse.che.ide.api.command.CommandManager; import org.eclipse.che.ide.api.command.CommandRemovedEvent; import org.eclipse.che.ide.api.command.CommandUpdatedEvent; import org.eclipse.che.ide.api.component.WsAgentComponent; import java.util.HashMap; import java.util.Map; import static com.google.common.base.Strings.isNullOrEmpty; import static org.eclipse.che.ide.api.action.IdeActions.GROUP_CONSOLES_TREE_CONTEXT_MENU; import static org.eclipse.che.ide.api.action.IdeActions.GROUP_EDITOR_TAB_CONTEXT_MENU; import static org.eclipse.che.ide.api.action.IdeActions.GROUP_MAIN_CONTEXT_MENU; /** * Manager listens for creating/removing commands and adds/removes * related {@link ExecuteCommandAction}s in the context menus. */ @Singleton public class ExecuteCommandActionManager implements WsAgentComponent { private static final String COMMANDS_ACTION_GROUP_ID_PREFIX = "commandsActionGroup"; private static final String COMMAND_ACTION_ID_PREFIX = "command_"; private static final String GOAL_ACTION_GROUP_ID_PREFIX = "goal_"; private final CommandManager commandManager; private final ActionManager actionManager; private final CommandsActionGroup commandsActionGroup; private final GoalPopUpGroupFactory goalPopUpGroupFactory; private final ExecuteCommandActionFactory commandActionFactory; private final CommandGoalRegistry goalRegistry; private final EventBus eventBus; /** Map of command's name to an appropriate {@link ExecuteCommandAction}. */ private final Map<String, Action> commandActions; /** Map of command goal's ID to an appropriate action group. */ private final Map<String, DefaultActionGroup> goalPopUpGroups; @Inject public ExecuteCommandActionManager(CommandManager commandManager, ActionManager actionManager, CommandsActionGroup commandsActionGroup, GoalPopUpGroupFactory goalPopUpGroupFactory, ExecuteCommandActionFactory commandActionFactory, CommandGoalRegistry goalRegistry, EventBus eventBus) { this.commandManager = commandManager; this.actionManager = actionManager; this.commandsActionGroup = commandsActionGroup; this.goalPopUpGroupFactory = goalPopUpGroupFactory; this.commandActionFactory = commandActionFactory; this.goalRegistry = goalRegistry; this.eventBus = eventBus; commandActions = new HashMap<>(); goalPopUpGroups = new HashMap<>(); } @Override public void start(Callback<WsAgentComponent, Exception> callback) { callback.onSuccess(this); eventBus.addHandler(CommandAddedEvent.getType(), e -> addAction(e.getCommand())); eventBus.addHandler(CommandRemovedEvent.getType(), e -> removeAction(e.getCommand())); eventBus.addHandler(CommandUpdatedEvent.getType(), e -> { removeAction(e.getInitialCommand()); addAction(e.getUpdatedCommand()); }); actionManager.registerAction(COMMANDS_ACTION_GROUP_ID_PREFIX, commandsActionGroup); // inject 'Commands' menu into context menus ((DefaultActionGroup)actionManager.getAction(GROUP_MAIN_CONTEXT_MENU)).add(commandsActionGroup); ((DefaultActionGroup)actionManager.getAction(GROUP_EDITOR_TAB_CONTEXT_MENU)).add(commandsActionGroup); ((DefaultActionGroup)actionManager.getAction(GROUP_CONSOLES_TREE_CONTEXT_MENU)).add(commandsActionGroup); commandManager.getCommands().forEach(this::addAction); } /** * Creates action for executing the given command and * adds created action to the appropriate action group. */ private void addAction(CommandImpl command) { final ExecuteCommandAction action = commandActionFactory.create(command); actionManager.registerAction(COMMAND_ACTION_ID_PREFIX + command.getName(), action); commandActions.put(command.getName(), action); getActionGroupForCommand(command).add(action); } /** * Returns the action group which is appropriate for placing the action for executing the given command. * If appropriate action group doesn't exist it will be created and added to the right place. */ private DefaultActionGroup getActionGroupForCommand(CommandImpl command) { String goalId = command.getGoal(); if (isNullOrEmpty(goalId)) { goalId = goalRegistry.getDefaultGoal().getId(); } DefaultActionGroup commandGoalPopUpGroup = goalPopUpGroups.get(goalId); if (commandGoalPopUpGroup == null) { commandGoalPopUpGroup = goalPopUpGroupFactory.create(goalId); actionManager.registerAction(GOAL_ACTION_GROUP_ID_PREFIX + goalId, commandGoalPopUpGroup); goalPopUpGroups.put(goalId, commandGoalPopUpGroup); commandsActionGroup.add(commandGoalPopUpGroup); } return commandGoalPopUpGroup; } /** * Removes action for executing the given command and * removes the appropriate action group in case it's empty. */ private void removeAction(CommandImpl command) { final Action commandAction = commandActions.remove(command.getName()); if (commandAction != null) { final String commandActionId = actionManager.getId(commandAction); if (commandActionId != null) { actionManager.unregisterAction(commandActionId); } // remove action from it's action group String goalId = command.getGoal(); if (isNullOrEmpty(goalId)) { goalId = goalRegistry.getDefaultGoal().getId(); } // remove action group if it's empty final DefaultActionGroup goalPopUpGroup = goalPopUpGroups.remove(goalId); if (goalPopUpGroup != null) { goalPopUpGroup.remove(commandAction); if (goalPopUpGroup.getChildrenCount() == 0) { final String goalActionId = actionManager.getId(goalPopUpGroup); if (goalActionId != null) { actionManager.unregisterAction(goalActionId); } commandsActionGroup.remove(goalPopUpGroup); } } } } }