001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.services;
011:
012: import java.util.HashMap;
013: import java.util.Map;
014:
015: import org.eclipse.core.expressions.Expression;
016: import org.eclipse.core.expressions.ExpressionInfo;
017: import org.eclipse.ui.ISources;
018:
019: /**
020: * <p>
021: * A static class linking the names of variables in an IEvaluationContext to the
022: * priority they should be given when doing conflict resolution.
023: * </p>
024: * <p>
025: * In the future, it will possible to define a new variable (i.e., piece of
026: * application state) that you want to use inside of the
027: * <code>org.eclipse.ui.contexts</code>, <code>org.eclipse.ui.handlers</code>
028: * or <code>org.eclipse.ui.menus</code> extension points. As it stands right
029: * now, it is not possible to run code soon enough for the
030: * <code>IHandlerService</code>, <code>IMenuService</code> or
031: * <code>IContextService</code> to become aware of the new variables. This
032: * will likely be fixed with a new extension point.
033: * </p>
034: * <p>
035: * TODO Move to "org.eclipse.ui" and resolve the above issue.
036: * </p>
037: *
038: * @since 3.2
039: * @see org.eclipse.ui.ISources
040: * @see org.eclipse.ui.contexts.IContextService
041: * @see org.eclipse.ui.handlers.IHandlerService
042: * @see org.eclipse.ui.menus.IMenuService
043: */
044: public final class SourcePriorityNameMapping implements ISources {
045:
046: /**
047: * The variable name to use when boosting priority on an activation.
048: */
049: public static final String LEGACY_LEGACY_NAME = "LEGACY"; //$NON-NLS-1$
050:
051: /**
052: * The value returned if there is source priority for the given name
053: *
054: * @see SourcePriorityNameMapping#getMapping(String)
055: */
056: public static final int NO_SOURCE_PRIORITY = 0;
057:
058: /**
059: * The map of source priorities indexed by name. This value is never
060: * <code>null</code>.
061: */
062: private static final Map sourcePrioritiesByName = new HashMap();
063:
064: static {
065: addMapping(ACTIVE_ACTION_SETS_NAME, ACTIVE_ACTION_SETS);
066: addMapping(ACTIVE_CONTEXT_NAME, ACTIVE_CONTEXT);
067: addMapping(ACTIVE_CURRENT_SELECTION_NAME,
068: ACTIVE_CURRENT_SELECTION);
069: addMapping(ACTIVE_EDITOR_NAME, ACTIVE_EDITOR);
070: addMapping(ACTIVE_EDITOR_ID_NAME, ACTIVE_EDITOR_ID);
071: addMapping(ACTIVE_MENU_NAME, ACTIVE_MENU);
072: addMapping(ACTIVE_MENU_SELECTION_NAME, ACTIVE_MENU);
073: addMapping(ACTIVE_MENU_EDITOR_INPUT_NAME, ACTIVE_MENU);
074: addMapping(ACTIVE_FOCUS_CONTROL_ID_NAME, ACTIVE_MENU);
075: addMapping(ACTIVE_FOCUS_CONTROL_NAME, ACTIVE_MENU);
076: addMapping(ACTIVE_PART_NAME, ACTIVE_PART);
077: addMapping(ACTIVE_PART_ID_NAME, ACTIVE_PART_ID);
078: addMapping(ACTIVE_SHELL_NAME, ACTIVE_SHELL);
079: addMapping(ACTIVE_SITE_NAME, ACTIVE_SITE);
080: addMapping(ACTIVE_WORKBENCH_WINDOW_NAME,
081: ACTIVE_WORKBENCH_WINDOW);
082: addMapping(ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
083: ACTIVE_WORKBENCH_WINDOW_SHELL);
084: addMapping(ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
085: ACTIVE_WORKBENCH_WINDOW_SUBORDINATE);
086: addMapping(
087: ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
088: ACTIVE_WORKBENCH_WINDOW_SUBORDINATE);
089: addMapping(LEGACY_LEGACY_NAME, LEGACY_LEGACY);
090: }
091:
092: /**
093: * Adds a mapping between a source name and a source priority. This method
094: * also cleans up any existing mappings using the same name or priority.
095: * There is a one-to-one relationship between name and priority.
096: *
097: * @param sourceName
098: * The name of the variable as it would appear in an XML
099: * expression; must not be <code>null</code>.
100: * @param sourcePriority
101: * The priority of the source with respect to other sources. A
102: * higher value means that expressions including this priority
103: * will win ties more often. It is recommended that this value is
104: * simply a single bit shifted to a particular place.
105: * @see ISources
106: */
107: public static final void addMapping(final String sourceName,
108: final int sourcePriority) {
109: if (sourceName == null) {
110: throw new NullPointerException(
111: "The source name cannot be null."); //$NON-NLS-1$
112: }
113:
114: final Integer priority = new Integer(sourcePriority);
115:
116: sourcePrioritiesByName.put(sourceName, priority);
117: }
118:
119: /**
120: * Computes the source priority for the given expression. The source
121: * priority is a bit mask of all of the variables references by the
122: * expression. The default variable is considered to be
123: * {@link ISources#ACTIVE_CURRENT_SELECTION}. The source priority is used
124: * to minimize recomputations of the expression, and it can also be used for
125: * conflict resolution.
126: *
127: * @param expression
128: * The expression for which the source priority should be
129: * computed; may be <code>null</code>.
130: * @return The bit mask of all the sources required for this expression;
131: * <code>0</code> if none.
132: */
133: public static final int computeSourcePriority(
134: final Expression expression) {
135: int sourcePriority = ISources.WORKBENCH;
136:
137: if (expression == null) {
138: return sourcePriority;
139: }
140:
141: final ExpressionInfo info = expression.computeExpressionInfo();
142:
143: // Add the default variable, if any.
144: if (info.hasDefaultVariableAccess()) {
145: sourcePriority |= ISources.ACTIVE_CURRENT_SELECTION;
146: }
147:
148: // Add all of the reference variables.
149: final String[] sourceNames = info.getAccessedVariableNames();
150: for (int i = 0; i < sourceNames.length; i++) {
151: final String sourceName = sourceNames[i];
152: sourcePriority |= getMapping(sourceName);
153: }
154:
155: return sourcePriority;
156: }
157:
158: /**
159: * Gets the priority for the source with the given name.
160: *
161: * @param sourceName
162: * The name of the variable as it would appear in an XML
163: * expression; should not be <code>null</code>.
164: * @return The source priority that matches, if any;
165: * <code>NO_SOURCE_PRIORITY</code> if none is found.
166: */
167: public static final int getMapping(final String sourceName) {
168: final Object object = sourcePrioritiesByName.get(sourceName);
169: if (object instanceof Integer) {
170: return ((Integer) object).intValue();
171: }
172:
173: return NO_SOURCE_PRIORITY;
174: }
175:
176: /**
177: * This class should not be instantiated.
178: */
179: private SourcePriorityNameMapping() {
180: // This class should not be instantiated.
181: }
182: }
|