| /******************************************************************************* |
| * 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.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.expressions.Expression; |
| import org.eclipse.core.expressions.ExpressionInfo; |
| import org.eclipse.ui.ISources; |
| import org.eclipse.ui.internal.menus.IMenuService; |
| |
| /** |
| * <p> |
| * A static class linking the names of variables in an IEvaluationContext to the |
| * priority they should be given when doing conflict resolution. |
| * </p> |
| * <p> |
| * In the future, it will possible to define a new variable (i.e., piece of |
| * application state) that you want to use inside of the |
| * <code>org.eclipse.ui.contexts</code>, <code>org.eclipse.ui.handlers</code> |
| * or <code>org.eclipse.ui.menus</code> extension points. As it stands right |
| * now, it is not possible to run code soon enough for the |
| * <code>IHandlerService</code>, <code>IMenuService</code> or |
| * <code>IContextService</code> to become aware of the new variables. This |
| * will likely be fixed with a new extension point. |
| * </p> |
| * <p> |
| * TODO Move to "org.eclipse.ui" and resolve the above issue. |
| * </p> |
| * |
| * @since 3.2 |
| * @see org.eclipse.ui.ISources |
| * @see org.eclipse.ui.contexts.IContextService |
| * @see org.eclipse.ui.handlers.IHandlerService |
| * @see IMenuService |
| */ |
| public final class SourcePriorityNameMapping implements ISources { |
| |
| /** |
| * The variable name to use when boosting priority on an activation. |
| */ |
| public static final String LEGACY_LEGACY_NAME = "LEGACY"; //$NON-NLS-1$ |
| |
| /** |
| * The value returned if there is source priority for the given name |
| * |
| * @see SourcePriorityNameMapping#getMapping(String) |
| */ |
| public static final int NO_SOURCE_PRIORITY = 0; |
| |
| /** |
| * The map of source priorities indexed by name. This value is never |
| * <code>null</code>. |
| */ |
| private static final Map sourcePrioritiesByName = new HashMap(); |
| |
| /** |
| * The map of source names indexed by priority. This value is never |
| * <code>null</code>. |
| */ |
| private static final Map sourceNamesByPriority = new HashMap(); |
| |
| static { |
| addMapping(ACTIVE_ACTION_SETS_NAME, ACTIVE_ACTION_SETS); |
| addMapping(ACTIVE_CONTEXT_NAME, ACTIVE_CONTEXT); |
| addMapping(ACTIVE_CURRENT_SELECTION_NAME, ACTIVE_CURRENT_SELECTION); |
| addMapping(ACTIVE_EDITOR_NAME, ACTIVE_EDITOR); |
| addMapping(ACTIVE_EDITOR_ID_NAME, ACTIVE_EDITOR_ID); |
| addMapping(ACTIVE_MENU_NAME, ACTIVE_MENU); |
| addMapping(ACTIVE_PART_NAME, ACTIVE_PART); |
| addMapping(ACTIVE_PART_ID_NAME, ACTIVE_PART_ID); |
| addMapping(ACTIVE_SHELL_NAME, ACTIVE_SHELL); |
| addMapping(ACTIVE_SITE_NAME, ACTIVE_SITE); |
| addMapping(ACTIVE_WORKBENCH_WINDOW_NAME, ACTIVE_WORKBENCH_WINDOW); |
| addMapping(ACTIVE_WORKBENCH_WINDOW_SHELL_NAME, |
| ACTIVE_WORKBENCH_WINDOW_SHELL); |
| addMapping(LEGACY_LEGACY_NAME, LEGACY_LEGACY); |
| } |
| |
| /** |
| * Adds a mapping between a source name and a source priority. This method |
| * also cleans up any existing mappings using the same name or priority. |
| * There is a one-to-one relationship between name and priority. |
| * |
| * @param sourceName |
| * The name of the variable as it would appear in an XML |
| * expression; must not be <code>null</code>. |
| * @param sourcePriority |
| * The priority of the source with respect to other sources. A |
| * higher value means that expressions including this priority |
| * will win ties more often. It is recommended that this value is |
| * simply a single bit shifted to a particular place. |
| * @see ISources |
| */ |
| public static final void addMapping(final String sourceName, |
| final int sourcePriority) { |
| if (sourceName == null) { |
| throw new NullPointerException("The source name cannot be null."); //$NON-NLS-1$ |
| } |
| |
| final Integer priority = new Integer(sourcePriority); |
| |
| final Object existingPriority = sourcePrioritiesByName.get(sourceName); |
| if (existingPriority instanceof Integer) { |
| sourceNamesByPriority.remove(existingPriority); |
| } |
| sourcePrioritiesByName.put(sourceName, priority); |
| |
| final Object existingName = sourceNamesByPriority.get(priority); |
| if (existingName instanceof String) { |
| sourcePrioritiesByName.remove(existingName); |
| } |
| sourceNamesByPriority.put(priority, sourceName); |
| } |
| |
| /** |
| * Computes the source priority for the given expression. The source |
| * priority is a bit mask of all of the variables references by the |
| * expression. The default variable is considered to be |
| * {@link ISources#ACTIVE_CURRENT_SELECTION}. The source priority is used |
| * to minimize recomputations of the expression, and it can also be used for |
| * conflict resolution. |
| * |
| * @param expression |
| * The expression for which the source priority should be |
| * computed; may be <code>null</code>. |
| * @return The bit mask of all the sources required for this expression; |
| * <code>0</code> if none. |
| */ |
| public static final int computeSourcePriority(final Expression expression) { |
| int sourcePriority = ISources.WORKBENCH; |
| |
| if (expression == null) { |
| return sourcePriority; |
| } |
| |
| final ExpressionInfo info = expression.computeExpressionInfo(); |
| |
| // Add the default variable, if any. |
| if (info.hasDefaultVariableAccess()) { |
| sourcePriority |= ISources.ACTIVE_CURRENT_SELECTION; |
| } |
| |
| // Add all of the reference variables. |
| final String[] sourceNames = info.getAccessedVariableNames(); |
| for (int i = 0; i < sourceNames.length; i++) { |
| final String sourceName = sourceNames[i]; |
| sourcePriority |= getMapping(sourceName); |
| } |
| |
| return sourcePriority; |
| } |
| |
| /** |
| * Gets the priority for the source with the given name. |
| * |
| * @param sourceName |
| * The name of the variable as it would appear in an XML |
| * expression; should not be <code>null</code>. |
| * @return The source priority that matches, if any; |
| * <code>NO_SOURCE_PRIORITY</code> if none is found. |
| */ |
| public static final int getMapping(final String sourceName) { |
| final Object object = sourcePrioritiesByName.get(sourceName); |
| if (object instanceof Integer) { |
| return ((Integer) object).intValue(); |
| } |
| |
| return NO_SOURCE_PRIORITY; |
| } |
| |
| /** |
| * Gets the name of the source with the given priority. |
| * |
| * @param sourcePriority |
| * The priority of the variable. |
| * @return The name of the source that matches, if any; <code>null</code> |
| * if nothing matches. |
| */ |
| public static final String getMapping(final int sourcePriority) { |
| final Integer priority = new Integer(sourcePriority); |
| final Object object = sourcePrioritiesByName.get(priority); |
| if (object instanceof String) { |
| return (String) object; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * This class should not be instantiated. |
| */ |
| private SourcePriorityNameMapping() { |
| // This class should not be instantiated. |
| } |
| } |