package com.buildml.eclipse.actions.handlers; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.handlers.HandlerUtil; import com.buildml.eclipse.MainEditor; import com.buildml.eclipse.actions.dialogs.MatchPatternSelectionDialog; import com.buildml.eclipse.bobj.UIAction; import com.buildml.eclipse.utils.AlertDialog; import com.buildml.eclipse.utils.EclipsePartUtils; import com.buildml.eclipse.utils.UndoOpAdapter; import com.buildml.eclipse.utils.errors.FatalError; import com.buildml.model.IActionMgr; import com.buildml.model.IBuildStore; import com.buildml.model.types.ActionSet; import com.buildml.model.undo.MultiUndoOp; import com.buildml.refactor.CanNotRefactorException; import com.buildml.refactor.IImportRefactorer; import com.buildml.utils.string.ShellCommandUtils; /** * An Eclipse UI Handler for managing the "Make Atomic" UI command. * This handler tries to make an action atomic (i.e. merges it with it's children) * and gives the user feedback on anything that may have gone wrong in the process. * * @author Peter Smith <psmith@arapiki.com> */ public class HandlerMakeAtomic extends AbstractHandler { /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /* (non-Javadoc) * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { MainEditor mainEditor = EclipsePartUtils.getActiveMainEditor(); IBuildStore buildStore = mainEditor.getBuildStore(); IActionMgr actionMgr = buildStore.getActionMgr(); String mode = event.getParameter("com.buildml.eclipse.commandParameters.makeAtomic"); /* * In "selected" mode, we operate on all the actions that have been selected by the user. */ if (mode.equals("selected")) { /* build an ActionSet of all the selected actions */ TreeSelection selection = (TreeSelection)HandlerUtil.getCurrentSelection(event); ActionSet selectedActions = EclipsePartUtils.getActionSetFromSelection(buildStore, selection); performMakeAtomic(mainEditor, buildStore, selectedActions); } /* * In pattern mode, we query the user for a regular expression to be used for * selecting which patterns. */ else if (mode.equals("pattern")) { TreeSelection selection = (TreeSelection)HandlerUtil.getCurrentSelection(event); if (selection.size() != 1) { AlertDialog.displayErrorDialog("Can't make atomic", "When making matching actions atomic, only one action may be selected."); return null; } /* use the selected action's command string as the initial pattern */ UIAction selectedAction = (UIAction)selection.getFirstElement(); String selectedCmd = (String) actionMgr.getSlotValue(selectedAction.getId(), IActionMgr.COMMAND_SLOT_ID); selectedCmd = ShellCommandUtils.joinCommandLine(selectedCmd); /* invoke a Dialog box to query the user to select the pattern, and then the matching actions */ MatchPatternSelectionDialog dialog = new MatchPatternSelectionDialog(buildStore, selectedCmd, "Make Atomic"); int status = dialog.open(); if (status == MatchPatternSelectionDialog.OK) { ActionSet selectedActions = dialog.getMatchingActions(); performMakeAtomic(mainEditor, buildStore, selectedActions); } } /* else, not supported - throw internal error */ else { throw new FatalError("Unsupported mode in com.buildml.eclipse.commandParameters.makeAtomic"); } return null; } /*=====================================================================================* * PRIVATE METHODS *=====================================================================================*/ /** * Perform the "make atomic" operation, but validating the operation, reporting errors * if necessary, then scheduling a MultiUndoOp. * * @param mainEditor The main editor we're operating on. * @param buildStore The IBuildStore associated with the operation. * @param selectedActions The actions to make atomic. */ private void performMakeAtomic(MainEditor mainEditor, IBuildStore buildStore, ActionSet selectedActions) { IActionMgr actionMgr = buildStore.getActionMgr(); IImportRefactorer refactorer = mainEditor.getImportRefactorer(); MultiUndoOp multiOp = new MultiUndoOp(); boolean changesMade = false; for (int actionId : selectedActions) { String actionCmd = (String) actionMgr.getSlotValue(actionId, IActionMgr.COMMAND_SLOT_ID); Integer children[] = actionMgr.getChildren(actionId); if (children.length != 0) { try { refactorer.makeActionAtomic(multiOp, actionId); changesMade = true; } catch (CanNotRefactorException e) { AlertDialog.displayErrorDialog("Operation failed", "The \"make atomic\" operation for action:\n\n" + actionCmd + "\nfailed for the following reason: " + e.getCauseCode()); } } } if (changesMade) { new UndoOpAdapter("Make Atomic", multiOp).invoke(); } } /*-------------------------------------------------------------------------------------*/ }