Package org.eclipse.ui.internal.services

Source Code of org.eclipse.ui.internal.services.PreferencePersistence

/*******************************************************************************
* 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.services;

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

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.util.Util;

/**
* <p>
* A manager for items parsed from the preference store. This attaches a
* listener to the registry after the first read, and monitors the preference
* for changes from that point on. When {@link #dispose()} is called, the
* listener is detached.
* </p>
* <p>
* This class is only intended for internal use within the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*/
public abstract class PreferencePersistence extends RegistryPersistence {

  /**
   * Inserts the given element into the indexed two-dimensional array in the
   * array at the index. The array is grown as necessary.
   *
   * @param elementToAdd
   *            The element to add to the indexed array; may be
   *            <code>null</code>
   * @param indexedArray
   *            The two-dimensional array that is indexed by element type;
   *            must not be <code>null</code>.
   * @param index
   *            The index at which the element should be added; must be a
   *            valid index.
   * @param currentCount
   *            The current number of items in the array at the index.
   */
  protected static final void addElementToIndexedArray(
      final IMemento elementToAdd, final IMemento[][] indexedArray,
      final int index, final int currentCount) {
    final IMemento[] elements;
    if (currentCount == 0) {
      elements = new IMemento[1];
      indexedArray[index] = elements;
    } else {
      if (currentCount >= indexedArray[index].length) {
        final IMemento[] copy = new IMemento[indexedArray[index].length * 2];
        System.arraycopy(indexedArray[index], 0, copy, 0, currentCount);
        elements = copy;
        indexedArray[index] = elements;
      } else {
        elements = indexedArray[index];
      }
    }
    elements[currentCount] = elementToAdd;
  }

  /**
   * Adds a warning to be logged at some later point in time.
   *
   * @param warningsToLog
   *            The collection of warnings to be logged; must not be
   *            <code>null</code>.
   * @param message
   *            The mesaage to log; must not be <code>null</code>.
   */
  protected static final void addWarning(final List warningsToLog,
      final String message) {
    addWarning(warningsToLog, message, null, null, null);
  }

  /**
   * Adds a warning to be logged at some later point in time. This logs the
   * identifier of the item.
   *
   * @param warningsToLog
   *            The collection of warnings to be logged; must not be
   *            <code>null</code>.
   * @param message
   *            The mesaage to log; must not be <code>null</code>.
   * @param id
   *            The identifier of the item for which a warning is being
   *            logged; may be <code>null</code>.
   */
  protected static final void addWarning(final List warningsToLog,
      final String message, final String id) {
    addWarning(warningsToLog, message, id, null, null);
  }

  /**
   * Adds a warning to be logged at some later point in time. This logs the
   * identifier of the item, as well as an extra attribute.
   *
   * @param warningsToLog
   *            The collection of warnings to be logged; must not be
   *            <code>null</code>.
   * @param message
   *            The mesaage to log; must not be <code>null</code>.
   * @param id
   *            The identifier of the item for which a warning is being
   *            logged; may be <code>null</code>.
   * @param extraAttributeName
   *            The name of extra attribute to be logged; may be
   *            <code>null</code>.
   * @param extraAttributeValue
   *            The value of the extra attribute to be logged; may be
   *            <code>null</code>.
   */
  protected static final void addWarning(final List warningsToLog,
      final String message, final String id,
      final String extraAttributeName, final String extraAttributeValue) {
    String statusMessage = message;
    if (id != null) {
      statusMessage = statusMessage + ": id='" + id + '\''; //$NON-NLS-1$
    }
    if (extraAttributeName != null) {
      if (id != null) {
        statusMessage = statusMessage + ',';
      } else {
        statusMessage = statusMessage + ':';
      }
      statusMessage = statusMessage + ' ' + extraAttributeName + "='" //$NON-NLS-1$
          + extraAttributeValue + '\'';
    }

    final IStatus status = new Status(IStatus.WARNING,
        WorkbenchPlugin.PI_WORKBENCH, 0, statusMessage, null);
    warningsToLog.add(status);
  }

  /**
   * Reads a boolean attribute from a memnto.
   *
   * @param memento
   *            The memento from which to read the attribute; must not be
   *            <code>null</code>.
   * @param attribute
   *            The attribute to read; must not be <code>null</code>.
   * @param defaultValue
   *            The default boolean value.
   * @return The attribute's value; may be <code>null</code> if none.
   */
  protected static final boolean readBoolean(final IMemento memento,
      final String attribute, final boolean defaultValue) {
    final String value = memento.getString(attribute);
    if (value == null) {
      return defaultValue;
    }

    if (defaultValue) {
      return !value.equalsIgnoreCase("false"); //$NON-NLS-1$
    }

    return !value.equalsIgnoreCase("true"); //$NON-NLS-1$
  }

  /**
   * Reads an optional attribute from a memento. This converts zero-length
   * strings into <code>null</code>.
   *
   * @param memento
   *            The memento from which to read the attribute; must not be
   *            <code>null</code>.
   * @param attribute
   *            The attribute to read; must not be <code>null</code>.
   * @return The attribute's value; may be <code>null</code> if none.
   */
  protected static final String readOptional(final IMemento memento,
      final String attribute) {
    String value = memento.getString(attribute);
    if ((value != null) && (value.length() == 0)) {
      value = null;
    }

    return value;
  }

  /**
   * Reads the parameterized command from a parent memento. This is used to
   * read the parameter sub-elements from a key element, as well as the
   * command id. 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. The command id is required, or a
   * warning will be logged.
   *
   * @param memento
   *            The memento from which the parameters should be read; must not
   *            be <code>null</code>.
   * @param commandService
   *            The service providing commands for the workbench; must not be
   *            <code>null</code>.
   * @param warningsToLog
   *            The list of warnings found during parsing. Warnings found will
   *            parsing the parameters will be appended to this list. This
   *            value must not be <code>null</code>.
   * @param message
   *            The message to print if the command identifier is not present;
   *            must not be <code>null</code>.
   * @return The array of parameters found for this configuration element;
   *         <code>null</code> if none can be found.
   */
  protected static final ParameterizedCommand readParameterizedCommand(
      final IMemento memento, final ICommandService commandService,
      final List warningsToLog, final String message, final String id) {
    final String commandId = readRequired(memento, ATT_COMMAND_ID,
        warningsToLog, message, id);
    if (commandId == null) {
      return null;
    }

    final Command command = commandService.getCommand(commandId);
    final ParameterizedCommand parameterizedCommand = readParameters(
        memento, warningsToLog, command);

    return parameterizedCommand;
  }

  /**
   * Reads the parameters from a parent memento. This is used to read the
   * parameter sub-elements from a key 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 memento
   *            The memento from which the parameters should be read; must not
   *            be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings found during parsing. Warnings found will
   *            parsing the parameters will be appended to this list. This
   *            value must not be <code>null</code>.
   * @param command
   *            The command around which the parameterization should be
   *            created; must not be <code>null</code>.
   * @return The array of parameters found for this memento; <code>null</code>
   *         if none can be found.
   */
  protected static final ParameterizedCommand readParameters(
      final IMemento memento, final List warningsToLog,
      final Command command) {
    final IMemento[] parameterMementos = memento
        .getChildren(TAG_PARAMETER);
    if ((parameterMementos == null) || (parameterMementos.length == 0)) {
      return new ParameterizedCommand(command, null);
    }

    final Collection parameters = new ArrayList();
    for (int i = 0; i < parameterMementos.length; i++) {
      final IMemento parameterMemento = parameterMementos[i];

      // Read out the id.
      final String id = parameterMemento.getString(ATT_ID);
      if ((id == null) || (id.length() == 0)) {
        // The name should never be null. This is invalid.
        addWarning(warningsToLog, "Parameters need a name"); //$NON-NLS-1$
        continue;
      }

      // Find the parameter on the command.
      IParameter parameter = null;
      try {
        final IParameter[] commandParameters = command.getParameters();
        if (parameters != null) {
          for (int j = 0; j < commandParameters.length; j++) {
            final IParameter currentParameter = commandParameters[j];
            if (Util.equals(currentParameter.getId(), id)) {
              parameter = currentParameter;
              break;
            }
          }

        }
      } catch (final NotDefinedException e) {
        // This should not happen.
      }
      if (parameter == null) {
        // The name should never be null. This is invalid.
        addWarning(warningsToLog,
            "Could not find a matching parameter", id); //$NON-NLS-1$
        continue;
      }

      // Read out the value.
      final String value = parameterMemento.getString(ATT_VALUE);
      if ((value == null) || (value.length() == 0)) {
        // The name should never be null. This is invalid.
        addWarning(warningsToLog, "Parameters need a value", id); //$NON-NLS-1$
        continue;
      }

      parameters.add(new Parameterization(parameter, value));
    }

    if (parameters.isEmpty()) {
      return new ParameterizedCommand(command, null);
    }

    return new ParameterizedCommand(command,
        (Parameterization[]) parameters
            .toArray(new Parameterization[parameters.size()]));
  }

  /**
   * Reads a required attribute from the memento.
   *
   * @param memento
   *            The memento from which to read; must not be <code>null</code>.
   * @param attribute
   *            The attribute to read; must not be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings; must not be <code>null</code>.
   * @param message
   *            The warning message to use if the attribute is missing; must
   *            not be <code>null</code>.
   * @return The required attribute; may be <code>null</code> if missing.
   */
  protected static final String readRequired(final IMemento memento,
      final String attribute, final List warningsToLog,
      final String message) {
    return readRequired(memento, attribute, warningsToLog, message, null);
  }

  /**
   * Reads a required attribute from the memento. This logs the identifier of
   * the item if this required element cannot be found.
   *
   * @param memento
   *            The memento from which to read; must not be <code>null</code>.
   * @param attribute
   *            The attribute to read; must not be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings; must not be <code>null</code>.
   * @param message
   *            The warning message to use if the attribute is missing; must
   *            not be <code>null</code>.
   * @param id
   *            The identifier of the element for which this is a required
   *            attribute; may be <code>null</code>.
   * @return The required attribute; may be <code>null</code> if missing.
   */
  protected static final String readRequired(final IMemento memento,
      final String attribute, final List warningsToLog,
      final String message, final String id) {
    final String value = memento.getString(attribute);
    if ((value == null) || (value.length() == 0)) {
      addWarning(warningsToLog, message, id);
      return null;
    }

    return value;
  }

  /**
   * Whether the preference and registry change listeners have been attached
   * yet.
   */
  protected boolean preferenceListenerAttached = false;

  /**
   * The registry change listener for this class.
   */
  private final IPropertyChangeListener preferenceChangeListener;

  /**
   * Detaches the preference change listener from the registry.
   */
  public final void dispose() {
    super.dispose();

    final IPreferenceStore store = WorkbenchPlugin.getDefault()
        .getPreferenceStore();
    store.removePropertyChangeListener(preferenceChangeListener);
  }

  /**
   * Checks whether the preference change could affect this persistence class.
   *
   * @param event
   *            The event indicating the preference change; must not be
   *            <code>null</code>.
   * @return <code>true</code> if the persistence instance is affected by
   *         this change; <code>false</code> otherwise.
   */
  protected abstract boolean isChangeImportant(final PropertyChangeEvent event);

  /**
   * Reads the various elements from the registry. Subclasses should extend,
   * but must not override.
   */
  protected void read() {
    super.read();

    if (!preferenceListenerAttached) {
      final IPreferenceStore store = WorkbenchPlugin.getDefault()
          .getPreferenceStore();
      store.addPropertyChangeListener(preferenceChangeListener);
    }
  }

  /**
   * Constructs a new instance of {@link PreferencePersistence}. A preference
   * change listener is created.
   */
  protected PreferencePersistence() {
    super();

    preferenceChangeListener = new IPropertyChangeListener() {
      public final void propertyChange(final PropertyChangeEvent event) {
        if (isChangeImportant(event)) {
          read();
        }
      }
    };
  }
}
TOP

Related Classes of org.eclipse.ui.internal.services.PreferencePersistence

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.