Package org.eclipse.core.commands

Source Code of org.eclipse.core.commands.CommandManager$ExecutionListener

/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* 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:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.commands;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.core.commands.common.HandleObjectManager;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.ListenerList;

/**
* <p>
* A central repository for commands -- both in the defined and undefined
* states. Commands can be created and retrieved using this manager. It is
* possible to listen to changes in the collection of commands by attaching a
* listener to the manager.
* </p>
*
* @see CommandManager#getCommand(String)
* @since 3.1
*/
public final class CommandManager extends HandleObjectManager implements
    ICategoryListener, ICommandListener, IParameterTypeListener {

  /**
   * A listener that forwards incoming execution events to execution listeners
   * on this manager. The execution events will come from any command on this
   * manager.
   *
   * @since 3.1
   */
  private final class ExecutionListener implements
      IExecutionListenerWithChecks {

    public void notDefined(String commandId, NotDefinedException exception) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListenerWithChecks) {
            final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object;
            listener.notDefined(commandId, exception);
          }
        }
      }
    }

    public void notEnabled(String commandId, NotEnabledException exception) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListenerWithChecks) {
            final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object;
            listener.notEnabled(commandId, exception);
          }
        }
      }
    }

    public final void notHandled(final String commandId,
        final NotHandledException exception) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListener) {
            final IExecutionListener listener = (IExecutionListener) object;
            listener.notHandled(commandId, exception);
          }
        }
      }
    }

    public final void postExecuteFailure(final String commandId,
        final ExecutionException exception) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListener) {
            final IExecutionListener listener = (IExecutionListener) object;
            listener.postExecuteFailure(commandId, exception);
          }
        }
      }
    }

    public final void postExecuteSuccess(final String commandId,
        final Object returnValue) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListener) {
            final IExecutionListener listener = (IExecutionListener) object;
            listener.postExecuteSuccess(commandId, returnValue);
          }
        }
      }
    }

    public final void preExecute(final String commandId,
        final ExecutionEvent event) {
      if (executionListeners != null) {
        final Object[] listeners = executionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
          final Object object = listeners[i];
          if (object instanceof IExecutionListener) {
            final IExecutionListener listener = (IExecutionListener) object;
            listener.preExecute(commandId, event);
          }
        }
      }
    }
  }

  /**
   * The identifier of the category in which all auto-generated commands will
   * appear. This value must never be <code>null</code>.
   *
   * @since 3.2
   */
  public static final String AUTOGENERATED_CATEGORY_ID = "org.eclipse.core.commands.categories.autogenerated"; //$NON-NLS-1$

  /**
   * The escape character to use for serialization and deserialization of
   * parameterized commands.
   */
  static final char ESCAPE_CHAR = '%';

  /**
   * The character that separates a parameter id from its value.
   */
  static final char ID_VALUE_CHAR = '=';

  /**
   * The character that indicates the end of a list of parameters.
   */
  static final char PARAMETER_END_CHAR = ')';

  /**
   * The character that separators parameters from each other.
   */
  static final char PARAMETER_SEPARATOR_CHAR = ',';

  /**
   * The character that indicates the start of a list of parameters.
   */
  static final char PARAMETER_START_CHAR = '(';

  /**
   * Unescapes special characters in the command id, parameter ids and
   * parameter values for {@link #deserialize(String)}. The special characters
   * {@link #PARAMETER_START_CHAR}, {@link #PARAMETER_END_CHAR},
   * {@link #ID_VALUE_CHAR}, {@link #PARAMETER_SEPARATOR_CHAR} and
   * {@link #ESCAPE_CHAR} are escaped by prepending an {@link #ESCAPE_CHAR}
   * character.
   * <p>
   * See also ParameterizedCommand.escape(String)
   * </p>
   *
   * @param escapedText
   *            a <code>String</code> that may contain escaped special
   *            characters for command serialization.
   * @return a <code>String</code> representing <code>escapedText</code>
   *         with any escaped characters replaced by their literal values
   * @throws SerializationException
   *             if <code>escapedText</code> contains an invalid escape
   *             sequence
   * @since 3.2
   */
  private static final String unescape(final String escapedText)
      throws SerializationException {

    // defer initialization of a StringBuffer until we know we need one
    StringBuffer buffer = null;

    for (int i = 0; i < escapedText.length(); i++) {

      char c = escapedText.charAt(i);
      if (c != ESCAPE_CHAR) {
        // normal unescaped character
        if (buffer != null) {
          buffer.append(c);
        }
      } else {
        if (buffer == null) {
          buffer = new StringBuffer(escapedText.substring(0, i));
        }

        if (++i < escapedText.length()) {
          c = escapedText.charAt(i);
          switch (c) {
          case PARAMETER_START_CHAR:
          case PARAMETER_END_CHAR:
          case ID_VALUE_CHAR:
          case PARAMETER_SEPARATOR_CHAR:
          case ESCAPE_CHAR:
            buffer.append(c);
            break;
          default:
            throw new SerializationException(
                "Invalid character '" + c + "' in escape sequence"); //$NON-NLS-1$ //$NON-NLS-2$
          }
        } else {
          throw new SerializationException(
              "Unexpected termination of escape sequence"); //$NON-NLS-1$
        }
      }

    }

    if (buffer == null) {
      return escapedText;
    }

    return buffer.toString();
  }

  /**
   * The map of category identifiers (<code>String</code>) to categories (
   * <code>Category</code>). This collection may be empty, but it is never
   * <code>null</code>.
   */
  private final Map categoriesById = new HashMap();

  /**
   * The set of identifiers for those categories that are defined. This value
   * may be empty, but it is never <code>null</code>.
   */
  private final Set definedCategoryIds = new HashSet();

  /**
   * The set of identifiers for those command parameter types that are
   * defined. This value may be empty, but it is never <code>null</code>.
   *
   * @since 3.2
   */
  private final Set definedParameterTypeIds = new HashSet();

  /**
   * The execution listener for this command manager. This just forwards
   * events from commands controlled by this manager to listeners on this
   * manager.
   */
  private IExecutionListenerWithChecks executionListener = null;
 
  private boolean shouldCommandFireEvents = true;

  /**
   * The collection of execution listeners. This collection is
   * <code>null</code> if there are no listeners.
   */
  private ListenerList executionListeners = null;

  /**
   * The help context identifiers ({@link String}) for a handler ({@link IHandler}).
   * This map may be empty, but it is never <code>null</code>. Entries are
   * removed if all strong references to the handler are removed.
   *
   * @since 3.2
   */
  private final Map helpContextIdsByHandler = new WeakHashMap();

  /**
   * The map of parameter type identifiers (<code>String</code>) to
   * parameter types ( <code>ParameterType</code>). This collection may be
   * empty, but it is never <code>null</code>.
   *
   * @since 3.2
   */
  private final Map parameterTypesById = new HashMap();

  /**
   * Adds a listener to this command manager. The listener will be notified
   * when the set of defined commands changes. This can be used to track the
   * global appearance and disappearance of commands.
   *
   * @param listener
   *            The listener to attach; must not be <code>null</code>.
   */
  public final void addCommandManagerListener(
      final ICommandManagerListener listener) {
    addListenerObject(listener);
  }

  /**
   * Adds an execution listener to this manager. This listener will be
   * notified if any of the commands controlled by this manager execute. This
   * can be used to support macros and instrumentation of commands.
   *
   * @param listener
   *            The listener to attach; must not be <code>null</code>.
   */
  public final void addExecutionListener(final IExecutionListener listener) {
    if (listener == null) {
      throw new NullPointerException(
          "Cannot add a null execution listener"); //$NON-NLS-1$
    }

    if (executionListeners == null) {
      executionListeners = new ListenerList(ListenerList.IDENTITY);

      // Add an execution listener to every command.
      executionListener = new ExecutionListener();
      final Iterator commandItr = handleObjectsById.values().iterator();
      while (commandItr.hasNext()) {
        final Command command = (Command) commandItr.next();
        command.addExecutionListener(executionListener);
      }

    }

    executionListeners.add(listener);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.core.commands.ICategoryListener#categoryChanged(org.eclipse.core.commands.CategoryEvent)
   */
  public final void categoryChanged(CategoryEvent categoryEvent) {
    if (categoryEvent.isDefinedChanged()) {
      final Category category = categoryEvent.getCategory();
      final String categoryId = category.getId();
      final boolean categoryIdAdded = category.isDefined();
      if (categoryIdAdded) {
        definedCategoryIds.add(categoryId);
      } else {
        definedCategoryIds.remove(categoryId);
      }
      if (isListenerAttached()) {
        fireCommandManagerChanged(new CommandManagerEvent(this, null,
            false, false, categoryId, categoryIdAdded, true));
      }
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.commands.ICommandListener#commandChanged(org.eclipse.commands.CommandEvent)
   */
  public final void commandChanged(final CommandEvent commandEvent) {
    if (commandEvent.isDefinedChanged()) {
      final Command command = commandEvent.getCommand();
      final String commandId = command.getId();
      final boolean commandIdAdded = command.isDefined();
      if (commandIdAdded) {
        definedHandleObjects.add(command);
      } else {
        definedHandleObjects.remove(command);
      }
      if (isListenerAttached()) {
        fireCommandManagerChanged(new CommandManagerEvent(this,
            commandId, commandIdAdded, true, null, false, false));
      }
    }
  }

  /**
   * Sets the name and description of the category for uncategorized commands.
   * This is the category that will be returned if
   * {@link #getCategory(String)} is called with <code>null</code>.
   *
   * @param name
   *            The name of the category for uncategorized commands; must not
   *            be <code>null</code>.
   * @param description
   *            The description of the category for uncategorized commands;
   *            may be <code>null</code>.
   * @since 3.2
   */
  public final void defineUncategorizedCategory(final String name,
      final String description) {
    final Category category = getCategory(AUTOGENERATED_CATEGORY_ID);
    category.define(name, description);
  }

  /**
   * <p>
   * Returns a {@link ParameterizedCommand} with a command and
   * parameterizations as specified in the provided
   * <code>serializedParameterizedCommand</code> string. The
   * <code>serializedParameterizedCommand</code> must use the format
   * returned by {@link ParameterizedCommand#serialize()} and described in the
   * Javadoc for that method.
   * </p>
   * <p>
   * If a parameter id encoded in the
   * <code>serializedParameterizedCommand</code> does not exist in the
   * encoded command, that parameter id and value are ignored. A given
   * parameter id should not be used more than once in
   * <code>serializedParameterizedCommand</code>. This will not result in
   * an exception, but in this case the value of the parameter when the
   * command is executed is unspecified.
   * </p>
   * <p>
   * This method will never return <code>null</code>, however it may throw
   * an exception if there is a problem processing the serialization string or
   * the encoded command is undefined.
   * </p>
   *
   * @param serializedParameterizedCommand
   *            a string representing a command id and parameter ids and
   *            values; must not be <code>null</code>
   * @return a {@link ParameterizedCommand} with the command and
   *         parameterizations encoded in the
   *         <code>serializedParameterizedCommand</code>; never
   *         <code>null</code>.
   * @throws NotDefinedException
   *             if the command indicated in
   *             <code>serializedParameterizedCommand</code> is not defined
   * @throws SerializationException
   *             if there is an error deserializing
   *             <code>serializedParameterizedCommand</code>
   * @see ParameterizedCommand#serialize()
   * @since 3.2
   */
  public final ParameterizedCommand deserialize(
      final String serializedParameterizedCommand)
      throws NotDefinedException, SerializationException {

    final int lparenPosition = unescapedIndexOf(
        serializedParameterizedCommand, PARAMETER_START_CHAR);

    final String commandIdEscaped;
    final String serializedParameters;
    if (lparenPosition == -1) {
      commandIdEscaped = serializedParameterizedCommand;
      serializedParameters = null;
    } else {
      commandIdEscaped = serializedParameterizedCommand.substring(0,
          lparenPosition);

      if (serializedParameterizedCommand
          .charAt(serializedParameterizedCommand.length() - 1) != PARAMETER_END_CHAR) {
        throw new SerializationException(
            "Parentheses must be balanced in serialized ParameterizedCommand"); //$NON-NLS-1$
      }

      serializedParameters = serializedParameterizedCommand.substring(
          lparenPosition + 1, // skip PARAMETER_START_CHAR
          serializedParameterizedCommand.length() - 1); // skip
      // PARAMETER_END_CHAR
    }

    final String commandId = unescape(commandIdEscaped);
    final Command command = getCommand(commandId);
    final IParameter[] parameters = command.getParameters();
    final Parameterization[] parameterizations = getParameterizations(
        serializedParameters, parameters);

    return new ParameterizedCommand(command, parameterizations);
  }

  /**
   * Notifies all of the listeners to this manager that the set of defined
   * command identifiers has changed.
   *
   * @param event
   *            The event to send to all of the listeners; must not be
   *            <code>null</code>.
   */
  private final void fireCommandManagerChanged(final CommandManagerEvent event) {
    if (event == null) {
      throw new NullPointerException();
    }

    final Object[] listeners = getListeners();
    for (int i = 0; i < listeners.length; i++) {
      final ICommandManagerListener listener = (ICommandManagerListener) listeners[i];
      listener.commandManagerChanged(event);
    }
  }

  /**
   * Returns all of the commands known by this manager -- defined and
   * undefined.
   *
   * @return All of the commands; may be empty, but never <code>null</code>.
   * @since 3.2
   */
  public final Command[] getAllCommands() {
    return (Command[]) handleObjectsById.values().toArray(
        new Command[handleObjectsById.size()]);
  }

  /**
   * Gets the category with the given identifier. If no such category
   * currently exists, then the category will be created (but be undefined).
   *
   * @param categoryId
   *            The identifier to find; must not be <code>null</code>. If
   *            the category is <code>null</code>, then a category suitable
   *            for uncategorized items is defined and returned.
   * @return The category with the given identifier; this value will never be
   *         <code>null</code>, but it might be undefined.
   * @see Category
   */
  public final Category getCategory(final String categoryId) {
    if (categoryId == null) {
      return getCategory(AUTOGENERATED_CATEGORY_ID);
    }

    checkId(categoryId);

    Category category = (Category) categoriesById.get(categoryId);
    if (category == null) {
      category = new Category(categoryId);
      categoriesById.put(categoryId, category);
      category.addCategoryListener(this);
    }

    return category;
  }

  /**
   * Gets the command with the given identifier. If no such command currently
   * exists, then the command will be created (but will be undefined).
   *
   * @param commandId
   *            The identifier to find; must not be <code>null</code> and
   *            must not be zero-length.
   * @return The command with the given identifier; this value will never be
   *         <code>null</code>, but it might be undefined.
   * @see Command
   */
  public final Command getCommand(final String commandId) {
    checkId(commandId);

    Command command = (Command) handleObjectsById.get(commandId);
    if (command == null) {
      command = new Command(commandId);
      command.shouldFireEvents = shouldCommandFireEvents;
      handleObjectsById.put(commandId, command);
      command.addCommandListener(this);

      if (executionListener != null) {
        command.addExecutionListener(executionListener);
      }
    }

    return command;
  }

  /**
   * Returns the categories that are defined.
   *
   * @return The defined categories; this value may be empty, but it is never
   *         <code>null</code>.
   * @since 3.2
   */
  public final Category[] getDefinedCategories() {
    final Category[] categories = new Category[definedCategoryIds.size()];
    final Iterator categoryIdItr = definedCategoryIds.iterator();
    int i = 0;
    while (categoryIdItr.hasNext()) {
      String categoryId = (String) categoryIdItr.next();
      categories[i++] = getCategory(categoryId);
    }
    return categories;
  }

  /**
   * Returns the set of identifiers for those category that are defined.
   *
   * @return The set of defined category identifiers; this value may be empty,
   *         but it is never <code>null</code>.
   */
  public final Set getDefinedCategoryIds() {
    return Collections.unmodifiableSet(definedCategoryIds);
  }

  /**
   * Returns the set of identifiers for those commands that are defined.
   *
   * @return The set of defined command identifiers; this value may be empty,
   *         but it is never <code>null</code>.
   */
  public final Set getDefinedCommandIds() {
    return getDefinedHandleObjectIds();
  }

  /**
   * Returns the commands that are defined.
   *
   * @return The defined commands; this value may be empty, but it is never
   *         <code>null</code>.
   * @since 3.2
   */
  public final Command[] getDefinedCommands() {
    return (Command[]) definedHandleObjects
        .toArray(new Command[definedHandleObjects.size()]);
  }

  /**
   * Returns the set of identifiers for those parameter types that are
   * defined.
   *
   * @return The set of defined command parameter type identifiers; this value
   *         may be empty, but it is never <code>null</code>.
   * @since 3.2
   */
  public final Set getDefinedParameterTypeIds() {
    return Collections.unmodifiableSet(definedParameterTypeIds);
  }

  /**
   * Returns the command parameter types that are defined.
   *
   * @return The defined command parameter types; this value may be empty, but
   *         it is never <code>null</code>.
   * @since 3.2
   */
  public final ParameterType[] getDefinedParameterTypes() {
    final ParameterType[] parameterTypes = new ParameterType[definedParameterTypeIds
        .size()];
    final Iterator iterator = definedParameterTypeIds.iterator();
    int i = 0;
    while (iterator.hasNext()) {
      final String parameterTypeId = (String) iterator.next();
      parameterTypes[i++] = getParameterType(parameterTypeId);
    }
    return parameterTypes;
  }

  /**
   * Gets the help context identifier for a particular command. The command's
   * handler is first checked for a help context identifier. If the handler
   * does not have a help context identifier, then the help context identifier
   * for the command is returned. If neither has a help context identifier,
   * then <code>null</code> is returned.
   *
   * @param command
   *            The command for which the help context should be retrieved;
   *            must not be <code>null</code>.
   * @return The help context identifier to use for the given command; may be
   *         <code>null</code>.
   * @throws NotDefinedException
   *             If the given command is not defined.
   * @since 3.2
   */
  public final String getHelpContextId(final Command command)
      throws NotDefinedException {
    // Check if the command is defined.
    if (!command.isDefined()) {
      throw new NotDefinedException("The command is not defined. " //$NON-NLS-1$
          + command.getId());
    }

    // Check the handler.
    final IHandler handler = command.getHandler();
    if (handler != null) {
      final String helpContextId = (String) helpContextIdsByHandler
          .get(handler);
      if (helpContextId != null) {
        return helpContextId;
      }
    }

    // Simply return whatever the command has as a help context identifier.
    return command.getHelpContextId();
  }

  /**
   * Returns an array of parameterizations for the provided command by
   * deriving the parameter ids and values from the provided
   * <code>serializedParameters</code> string.
   *
   * @param serializedParameters
   *            a String encoding parameter ids and values; must not be
   *            <code>null</code>.
   * @param parameters
   *            array of parameters of the command being deserialized; may be
   *            <code>null</code>.
   * @return an array of parameterizations; may be <code>null</code>.
   * @throws SerializationException
   *             if there is an error deserializing the parameters
   * @since 3.2
   */
  private final Parameterization[] getParameterizations(
      String serializedParameters, final IParameter[] parameters)
      throws SerializationException {

    if (serializedParameters == null
        || (serializedParameters.length() == 0)) {
      return null;
    }

    if ((parameters == null) || (parameters.length == 0)) {
      return null;
    }

    final ArrayList paramList = new ArrayList();

    int commaPosition; // split off each param by looking for ','
    do {
      commaPosition = unescapedIndexOf(serializedParameters, ',');

      final String idEqualsValue;
      if (commaPosition == -1) {
        // no more parameters after this
        idEqualsValue = serializedParameters;
      } else {
        // take the first parameter...
        idEqualsValue = serializedParameters
            .substring(0, commaPosition);

        // ... and put the rest back into serializedParameters
        serializedParameters = serializedParameters
            .substring(commaPosition + 1);
      }

      final int equalsPosition = unescapedIndexOf(idEqualsValue, '=');

      final String parameterId;
      final String parameterValue;
      if (equalsPosition == -1) {
        // missing values are null
        parameterId = unescape(idEqualsValue);
        parameterValue = null;
      } else {
        parameterId = unescape(idEqualsValue.substring(0,
            equalsPosition));
        parameterValue = unescape(idEqualsValue
            .substring(equalsPosition + 1));
      }

      for (int i = 0; i < parameters.length; i++) {
        final IParameter parameter = parameters[i];
        if (parameter.getId().equals(parameterId)) {
          paramList.add(new Parameterization(parameter,
              parameterValue));
          break;
        }
      }

    } while (commaPosition != -1);

    return (Parameterization[]) paramList
        .toArray(new Parameterization[paramList.size()]);
  }

  /**
   * Gets the command {@link ParameterType} with the given identifier. If no
   * such command parameter type currently exists, then the command parameter
   * type will be created (but will be undefined).
   *
   * @param parameterTypeId
   *            The identifier to find; must not be <code>null</code> and
   *            must not be zero-length.
   * @return The {@link ParameterType} with the given identifier; this value
   *         will never be <code>null</code>, but it might be undefined.
   * @since 3.2
   */
  public final ParameterType getParameterType(final String parameterTypeId) {
    checkId(parameterTypeId);

    ParameterType parameterType = (ParameterType) parameterTypesById
        .get(parameterTypeId);
    if (parameterType == null) {
      parameterType = new ParameterType(parameterTypeId);
      parameterTypesById.put(parameterTypeId, parameterType);
      parameterType.addListener(this);
    }

    return parameterType;
  }

  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public final void parameterTypeChanged(
      final ParameterTypeEvent parameterTypeEvent) {
    if (parameterTypeEvent.isDefinedChanged()) {
      final ParameterType parameterType = parameterTypeEvent
          .getParameterType();
      final String parameterTypeId = parameterType.getId();
      final boolean parameterTypeIdAdded = parameterType.isDefined();
      if (parameterTypeIdAdded) {
        definedParameterTypeIds.add(parameterTypeId);
      } else {
        definedParameterTypeIds.remove(parameterTypeId);
      }

      fireCommandManagerChanged(new CommandManagerEvent(this,
          parameterTypeId, parameterTypeIdAdded, true));
    }
  }

  /**
   * Removes a listener from this command manager.
   *
   * @param listener
   *            The listener to be removed; must not be <code>null</code>.
   */
  public final void removeCommandManagerListener(
      final ICommandManagerListener listener) {
    removeListenerObject(listener);
  }

  /**
   * Removes an execution listener from this command manager.
   *
   * @param listener
   *            The listener to be removed; must not be <code>null</code>.
   */
  public final void removeExecutionListener(final IExecutionListener listener) {
    if (listener == null) {
      throw new NullPointerException("Cannot remove a null listener"); //$NON-NLS-1$
    }

    if (executionListeners == null) {
      return;
    }

    executionListeners.remove(listener);

    if (executionListeners.isEmpty()) {
      executionListeners = null;

      // Remove the execution listener to every command.
      final Iterator commandItr = handleObjectsById.values().iterator();
      while (commandItr.hasNext()) {
        final Command command = (Command) commandItr.next();
        command.removeExecutionListener(executionListener);
      }
      executionListener = null;

    }
  }

  /**
   * Block updates all of the handlers for all of the commands. If the handler
   * is <code>null</code> or the command id does not exist in the map, then
   * the command becomes unhandled. Otherwise, the handler is set to the
   * corresponding value in the map.
   *
   * @param handlersByCommandId
   *            A map of command identifiers (<code>String</code>) to
   *            handlers (<code>IHandler</code>). This map may be
   *            <code>null</code> if all handlers should be cleared.
   *            Similarly, if the map is empty, then all commands will become
   *            unhandled.
   */
  public final void setHandlersByCommandId(final Map handlersByCommandId) {
    // Make that all the reference commands are created.
    final Iterator commandIdItr = handlersByCommandId.keySet().iterator();
    while (commandIdItr.hasNext()) {
      getCommand((String) commandIdItr.next());
    }

    // Now, set-up the handlers on all of the existing commands.
    final Iterator commandItr = handleObjectsById.values().iterator();
    while (commandItr.hasNext()) {
      final Command command = (Command) commandItr.next();
      final String commandId = command.getId();
      final Object value = handlersByCommandId.get(commandId);
      if (value instanceof IHandler) {
        command.setHandler((IHandler) value);
      } else {
        command.setHandler(null);
      }
    }
  }

  /**
   * Sets the help context identifier to associate with a particular handler.
   *
   * @param handler
   *            The handler with which to register a help context identifier;
   *            must not be <code>null</code>.
   * @param helpContextId
   *            The help context identifier to register; may be
   *            <code>null</code> if the help context identifier should be
   *            removed.
   * @since 3.2
   */
  public final void setHelpContextId(final IHandler handler,
      final String helpContextId) {
    if (handler == null) {
      throw new NullPointerException("The handler cannot be null"); //$NON-NLS-1$
    }
    if (helpContextId == null) {
      helpContextIdsByHandler.remove(handler);
    } else {
      helpContextIdsByHandler.put(handler, helpContextId);
    }
  }

  /**
   * Searches for the index of a <code>char</code> in a <code>String</code>
   * but disregards characters prefixed with the {@link #ESCAPE_CHAR} escape
   * character. This is used by {@link #deserialize(String)} and
   * {@link #getParameterizations(String, IParameter[])} to parse the
   * serialized parameterized command string.
   *
   * @param escapedText
   *            the string to search for the index of <code>ch</code> in
   * @param ch
   *            a character to search for in <code>escapedText</code>
   * @return the index of the first unescaped occurrence of the character in
   *         <code>escapedText</code>, or <code>-1</code> if the
   *         character does not occur unescaped.
   * @see String#indexOf(int)
   */
  private final int unescapedIndexOf(final String escapedText, final char ch) {

    int pos = escapedText.indexOf(ch);

    // first char can't be escaped
    if (pos == 0) {
      return pos;
    }

    while (pos != -1) {
      // look back for the escape character
      if (escapedText.charAt(pos - 1) != ESCAPE_CHAR) {
        return pos;
      }

      // scan for the next instance of ch
      pos = escapedText.indexOf(ch, pos + 1);
    }

    return pos;

  }
 
  /**
   * Fires the <code>notEnabled</code> event for
   * <code>executionListeners</code>.
   * <p>
   * <b>Note:</b> This supports bridging actions to the command framework,
   * and should not be used outside the framework.
   * </p>
   *
   * @param commandId
   *            The command id of the command about to execute, never
   *            <code>null</code>.
   * @param exception
   *            The exception, never <code>null</code>.
   * @since 3.4
   */
  public void fireNotEnabled(String commandId, NotEnabledException exception) {
    if (executionListener != null) {
      executionListener.notEnabled(commandId, exception);
    }
  }
 
  /**
   * Fires the <code>notDefined</code> event for
   * <code>executionListeners</code>.
   * <p>
   * <b>Note:</b> This supports bridging actions to the command framework,
   * and should not be used outside the framework.
   * </p>
   *
   * @param commandId
   *            The command id of the command about to execute, never
   *            <code>null</code>.
   * @param exception
   *            The exception, never <code>null</code>.
   * @since 3.4
   */
  public void fireNotDefined(String commandId, NotDefinedException exception) {
    if (executionListener != null) {
      executionListener.notDefined(commandId, exception);
    }
  }
 
  /**
   * Fires the <code>preExecute</code> event for
   * <code>executionListeners</code>.
   * <p>
   * <b>Note:</b> This supports bridging actions to the command framework,
   * and should not be used outside the framework.
   * </p>
   *
   * @param commandId
   *            The command id of the command about to execute, never
   *            <code>null</code>.
   * @param event
   *            The event that triggered the command, may be <code>null</code>.
   * @since 3.4
   */
  public void firePreExecute(String commandId, ExecutionEvent event) {
    if (executionListener != null) {
      executionListener.preExecute(commandId, event);
    }
  }
 
  /**
   * Fires the <code>postExecuteSuccess</code> event for
   * <code>executionListeners</code>.
   * <p>
   * <b>Note:</b> This supports bridging actions to the command framework,
   * and should not be used outside the framework.
   * </p>
   *
   * @param commandId
   *            The command id of the command executed, never
   *            <code>null</code>.
   * @param returnValue
   *            The value returned from the command, may be <code>null</code>.
   * @since 3.4
   */
  public void firePostExecuteSuccess(String commandId, Object returnValue) {
    if (executionListener != null) {
      executionListener.postExecuteSuccess(commandId, returnValue);
    }
  }
 
  /**
   * Fires the <code>postExecuteFailure</code> event for
   * <code>executionListeners</code>.
   * <p>
   * <b>Note:</b> This supports bridging actions to the command framework,
   * and should not be used outside the framework.
   * </p>
   *
   * @param commandId
   *            The command id of the command executed, never
   *            <code>null</code>.
   * @param exception
   *            The exception, never <code>null</code>.
   * @since 3.4
   */
  public void firePostExecuteFailure(String commandId,
      ExecutionException exception) {
    if (executionListener != null) {
      executionListener.postExecuteFailure(commandId, exception);
    }
  }
}
TOP

Related Classes of org.eclipse.core.commands.CommandManager$ExecutionListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.