Package org.eclipse.ui.internal.commands

Source Code of org.eclipse.ui.internal.commands.CommandPersistence

/*******************************************************************************
* Copyright (c) 2005, 2006 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.ui.internal.commands;

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

import org.eclipse.core.commands.AbstractParameterValueConverter;
import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ParameterType;
import org.eclipse.core.commands.State;
import org.eclipse.core.commands.common.HandleObject;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.services.RegistryPersistence;
import org.eclipse.ui.internal.util.PrefUtil;

/**
* <p>
* A static class for accessing the registry and the preference store.
* </p>
*
* @since 3.1
*/
final class CommandPersistence extends RegistryPersistence {

  /**
   * The index of the category elements in the indexed array.
   *
   * @see CommandPersistence#read()
   */
  private static final int INDEX_CATEGORY_DEFINITIONS = 0;

  /**
   * The index of the command elements in the indexed array.
   *
   * @see CommandPersistence#read()
   */
  private static final int INDEX_COMMAND_DEFINITIONS = 1;

  /**
   * The index of the commandParameterType elements in the indexed array.
   *
   * @see CommandPersistence#read()
   * @since 3.2
   */
  private static final int INDEX_PARAMETER_TYPE_DEFINITIONS = 2;

  /**
   * Reads all of the category definitions from the commands extension point.
   *
   * @param configurationElements
   *            The configuration elements in the commands extension point;
   *            must not be <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   * @param commandService
   *            The command service to which the categories should be added;
   *            must not be <code>null</code>.
   */
  private static final void readCategoriesFromRegistry(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount,
      final ICommandService commandService) {
    // Undefine all the previous handle objects.
    final HandleObject[] handleObjects = commandService
        .getDefinedCategories();
    if (handleObjects != null) {
      for (int i = 0; i < handleObjects.length; i++) {
        handleObjects[i].undefine();
      }
    }

    // Define the uncategorized category.
    commandService
        .defineUncategorizedCategory(
            WorkbenchMessages.CommandService_AutogeneratedCategoryName,
            WorkbenchMessages.CommandService_AutogeneratedCategoryDescription);

    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement configurationElement = configurationElements[i];

      // Read out the category identifier.
      final String categoryId = readRequired(configurationElement,
          ATT_ID, warningsToLog, "Categories need an id"); //$NON-NLS-1$
      if (categoryId == null) {
        continue;
      }

      // Read out the name.
      final String name = readRequired(configurationElement, ATT_NAME,
          warningsToLog, "Categories need a name", //$NON-NLS-1$
          categoryId);
      if (name == null) {
        continue;
      }

      // Read out the description.
      final String description = readOptional(configurationElement,
          ATT_DESCRIPTION);

      final Category category = commandService.getCategory(categoryId);
      category.define(name, description);
    }

    // If there were any warnings, then log them now.
    logWarnings(
        warningsToLog,
        "Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points."); //$NON-NLS-1$
  }

  /**
   * Reads all of the command definitions from the commands extension point.
   *
   * @param configurationElements
   *            The configuration elements in the commands extension point;
   *            must not be <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   * @param commandService
   *            The command service to which the commands should be added;
   *            must not be <code>null</code>.
   */
  private static final void readCommandsFromRegistry(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount,
      final ICommandService commandService) {
    // Undefine all the previous handle objects.
    final HandleObject[] handleObjects = commandService
        .getDefinedCommands();
    if (handleObjects != null) {
      for (int i = 0; i < handleObjects.length; i++) {
        handleObjects[i].undefine();
      }
    }

    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement configurationElement = configurationElements[i];

      // Read out the command identifier.
      final String commandId = readRequired(configurationElement, ATT_ID,
          warningsToLog, "Commands need an id"); //$NON-NLS-1$
      if (commandId == null) {
        continue;
      }

      // Read out the name.
      final String name = readRequired(configurationElement, ATT_NAME,
          warningsToLog, "Commands need a name"); //$NON-NLS-1$
      if (name == null) {
        continue;
      }

      // Read out the description.
      final String description = readOptional(configurationElement,
          ATT_DESCRIPTION);

      // Read out the category id.
      String categoryId = configurationElement
          .getAttribute(ATT_CATEGORY_ID);
      if ((categoryId == null) || (categoryId.length() == 0)) {
        categoryId = configurationElement.getAttribute(ATT_CATEGORY);
        if ((categoryId != null) && (categoryId.length() == 0)) {
          categoryId = null;
        }
      }

      // Read out the parameters.
      final Parameter[] parameters = readParameters(configurationElement,
          warningsToLog, commandService);

      // Read out the returnTypeId.
      final String returnTypeId = readOptional(configurationElement,
          ATT_RETURN_TYPE_ID);

      // Read out the help context identifier.
      final String helpContextId = readOptional(configurationElement,
          ATT_HELP_CONTEXT_ID);

      final Command command = commandService.getCommand(commandId);
      final Category category = commandService.getCategory(categoryId);
      if (!category.isDefined()) {
        addWarning(
            warningsToLog,
            "Commands should really have a category", //$NON-NLS-1$
            configurationElement, commandId,
            "categoryId", categoryId); //$NON-NLS-1$
      }

      final ParameterType returnType;
      if (returnTypeId == null) {
        returnType = null;
      } else {
        returnType = commandService.getParameterType(returnTypeId);
      }

      command.define(name, description, category, parameters, returnType,
          helpContextId);
      readState(configurationElement, warningsToLog, command);
    }

    // If there were any warnings, then log them now.
    logWarnings(
        warningsToLog,
        "Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points."); //$NON-NLS-1$
  }

  /**
   * Reads the parameters from a parent configuration element. This is used to
   * read the parameter sub-elements from a command element. Each parameter is
   * guaranteed to be valid. If invalid parameters are found, then a warning
   * status will be appended to the <code>warningsToLog</code> list.
   *
   * @param configurationElement
   *            The configuration element from which the parameters should be
   *            read; must not be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings found during parsing. Warnings found
   *            while parsing the parameters will be appended to this list.
   *            This value must not be <code>null</code>.
   * @param commandService
   *            The command service from which the parameter can get parameter
   *            types; must not be <code>null</code>.
   * @return The array of parameters found for this configuration element;
   *         <code>null</code> if none can be found.
   */
  private static final Parameter[] readParameters(
      final IConfigurationElement configurationElement,
      final List warningsToLog, final ICommandService commandService) {
    final IConfigurationElement[] parameterElements = configurationElement
        .getChildren(TAG_COMMAND_PARAMETER);
    if ((parameterElements == null) || (parameterElements.length == 0)) {
      return null;
    }

    int insertionIndex = 0;
    Parameter[] parameters = new Parameter[parameterElements.length];
    for (int i = 0; i < parameterElements.length; i++) {
      final IConfigurationElement parameterElement = parameterElements[i];
      // Read out the id
      final String id = readRequired(parameterElement, ATT_ID,
          warningsToLog, "Parameters need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      // Read out the name.
      final String name = readRequired(parameterElement, ATT_NAME,
          warningsToLog, "Parameters need a name"); //$NON-NLS-1$
      if (name == null) {
        continue;
      }

      /*
       * The IParameterValues will be initialized lazily as an
       * IExecutableExtension.
       */

      // Read out the typeId attribute, if present.
      final String typeId = readOptional(parameterElement, ATT_TYPE_ID);

      // Read out the optional attribute, if present.
      final boolean optional = readBoolean(parameterElement,
          ATT_OPTIONAL, true);

      final ParameterType type;
      if (typeId == null) {
        type = null;
      } else {
        type = commandService.getParameterType(typeId);
      }

      final Parameter parameter = new Parameter(id, name,
          parameterElement, type, optional);
      parameters[insertionIndex++] = parameter;
    }

    if (insertionIndex != parameters.length) {
      final Parameter[] compactedParameters = new Parameter[insertionIndex];
      System.arraycopy(parameters, 0, compactedParameters, 0,
          insertionIndex);
      parameters = compactedParameters;
    }

    return parameters;
  }

  /**
   * Reads all of the commandParameterType definitions from the commands
   * extension point.
   *
   * @param configurationElements
   *            The configuration elements in the commands extension point;
   *            must not be <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   * @param commandService
   *            The command service to which the commands should be added;
   *            must not be <code>null</code>.
   * @since 3.2
   */
  private static final void readParameterTypesFromRegistry(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount,
      final ICommandService commandService) {

    // Undefine all the previous handle objects.
    final HandleObject[] handleObjects = commandService
        .getDefinedParameterTypes();
    if (handleObjects != null) {
      for (int i = 0; i < handleObjects.length; i++) {
        handleObjects[i].undefine();
      }
    }

    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement configurationElement = configurationElements[i];

      // Read out the commandParameterType identifier.
      final String parameterTypeId = readRequired(configurationElement,
          ATT_ID, warningsToLog, "Command parameter types need an id"); //$NON-NLS-1$
      if (parameterTypeId == null) {
        continue;
      }

      // Read out the type.
      final String type = readOptional(configurationElement, ATT_TYPE);

      // Read out the converter.
      final String converter = readOptional(configurationElement,
          ATT_CONVERTER);

      /*
       * if the converter attribute was given, create a proxy
       * AbstractParameterValueConverter for the ParameterType, otherwise
       * null indicates there is no converter
       */
      final AbstractParameterValueConverter parameterValueConverter = (converter == null) ? null
          : new ParameterValueConverterProxy(configurationElement);

      final ParameterType parameterType = commandService
          .getParameterType(parameterTypeId);
      parameterType.define(type, parameterValueConverter);
    }

    // If there were any warnings, then log them now.
    logWarnings(
        warningsToLog,
        "Warnings while parsing the commandParameterTypes from the 'org.eclipse.ui.commands' extension point."); //$NON-NLS-1$

  }

  /**
   * Reads the states from a parent configuration element. This is used to
   * read the state sub-elements from a command element. Each state is
   * guaranteed to be valid. If invalid states are found, then a warning
   * status will be appended to the <code>warningsToLog</code> list.
   *
   * @param configurationElement
   *            The configuration element from which the states should be
   *            read; must not be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings found during parsing. Warnings found
   *            while parsing the parameters will be appended to this list.
   *            This value must not be <code>null</code>.
   * @param command
   *            The command for which the state is being read; may be
   *            <code>null</code>.
   */
  private static final void readState(
      final IConfigurationElement configurationElement,
      final List warningsToLog, final Command command) {
    final IConfigurationElement[] stateElements = configurationElement
        .getChildren(TAG_STATE);
    if ((stateElements == null) || (stateElements.length == 0)) {
      return;
    }

    for (int i = 0; i < stateElements.length; i++) {
      final IConfigurationElement stateElement = stateElements[i];

      final String id = readRequired(stateElement, ATT_ID, warningsToLog,
          "State needs an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      if (checkClass(stateElement, warningsToLog,
          "State must have an associated class", id)) { //$NON-NLS-1$
        final State state = new CommandStateProxy(stateElement,
            ATT_CLASS, PrefUtil.getInternalPreferenceStore(),
            CommandService.createPreferenceKey(command, id));
        command.addState(id, state);
      }
    }
  }

  /**
   * The command service with which this persistence class is associated;
   * never <code>null</code>.
   */
  private final ICommandService commandService;

  /**
   * Constructs a new instance of <code>CommandPersistence</code>.
   *
   * @param commandService
   *            The command service which should be populated with the values
   *            from the registry; must not be <code>null</code>.
   */
  CommandPersistence(final ICommandService commandService) {
    if (commandService == null) {
      throw new NullPointerException("The command service cannot be null"); //$NON-NLS-1$
    }
    this.commandService = commandService;
  }

  protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
    final IExtensionDelta[] commandDeltas = event.getExtensionDeltas(
        PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_COMMANDS);
    if (commandDeltas.length == 0) {
      final IExtensionDelta[] actionDefinitionDeltas = event
          .getExtensionDeltas(PlatformUI.PLUGIN_ID,
              IWorkbenchRegistryConstants.PL_ACTION_DEFINITIONS);
      if (actionDefinitionDeltas.length == 0) {
        return false;
      }
    }

    return true;
  }

  /**
   * Reads all of the commands and categories from the registry,
   *
   * @param commandService
   *            The command service which should be populated with the values
   *            from the registry; must not be <code>null</code>.
   */
  protected final void read() {
    super.read();

    // Create the extension registry mementos.
    final IExtensionRegistry registry = Platform.getExtensionRegistry();
    int commandDefinitionCount = 0;
    int categoryDefinitionCount = 0;
    int parameterTypeDefinitionCount = 0;
    final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[3][];

    // Sort the commands extension point based on element name.
    final IConfigurationElement[] commandsExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_COMMANDS);
    for (int i = 0; i < commandsExtensionPoint.length; i++) {
      final IConfigurationElement configurationElement = commandsExtensionPoint[i];
      final String name = configurationElement.getName();

      // Check if it is a binding definition.
      if (TAG_COMMAND.equals(name)) {
        addElementToIndexedArray(configurationElement,
            indexedConfigurationElements,
            INDEX_COMMAND_DEFINITIONS, commandDefinitionCount++);
      } else if (TAG_CATEGORY.equals(name)) {
        addElementToIndexedArray(configurationElement,
            indexedConfigurationElements,
            INDEX_CATEGORY_DEFINITIONS, categoryDefinitionCount++);
      } else if (TAG_COMMAND_PARAMETER_TYPE.equals(name)) {
        addElementToIndexedArray(configurationElement,
            indexedConfigurationElements,
            INDEX_PARAMETER_TYPE_DEFINITIONS,
            parameterTypeDefinitionCount++);
      }
    }

    final IConfigurationElement[] actionDefinitionsExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_ACTION_DEFINITIONS);
    for (int i = 0; i < actionDefinitionsExtensionPoint.length; i++) {
      final IConfigurationElement configurationElement = actionDefinitionsExtensionPoint[i];
      final String name = configurationElement.getName();

      if (TAG_ACTION_DEFINITION.equals(name)) {
        addElementToIndexedArray(configurationElement,
            indexedConfigurationElements,
            INDEX_COMMAND_DEFINITIONS, commandDefinitionCount++);
      }
    }

    readCategoriesFromRegistry(
        indexedConfigurationElements[INDEX_CATEGORY_DEFINITIONS],
        categoryDefinitionCount, commandService);
    readCommandsFromRegistry(
        indexedConfigurationElements[INDEX_COMMAND_DEFINITIONS],
        commandDefinitionCount, commandService);
    readParameterTypesFromRegistry(
        indexedConfigurationElements[INDEX_PARAMETER_TYPE_DEFINITIONS],
        parameterTypeDefinitionCount, commandService);

  }
}
TOP

Related Classes of org.eclipse.ui.internal.commands.CommandPersistence

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.