001: /*******************************************************************************
002: * Copyright (c) 2006 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.handlers;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.HashMap;
015: import java.util.HashSet;
016: import java.util.Map;
017: import java.util.Set;
018:
019: import org.eclipse.core.commands.Command;
020: import org.eclipse.core.commands.ExecutionEvent;
021: import org.eclipse.core.commands.ExecutionException;
022: import org.eclipse.core.commands.IHandler;
023: import org.eclipse.core.commands.NotEnabledException;
024: import org.eclipse.core.commands.NotHandledException;
025: import org.eclipse.core.commands.ParameterizedCommand;
026: import org.eclipse.core.commands.common.NotDefinedException;
027: import org.eclipse.core.expressions.Expression;
028: import org.eclipse.core.expressions.IEvaluationContext;
029: import org.eclipse.swt.widgets.Event;
030: import org.eclipse.ui.ISourceProvider;
031: import org.eclipse.ui.handlers.IHandlerActivation;
032: import org.eclipse.ui.handlers.IHandlerService;
033: import org.eclipse.ui.internal.expressions.AndExpression;
034:
035: /**
036: * A handler service which delegates almost all responsibility to the parent
037: * service. It is only responsible for disposing of locally activated handlers
038: * when it is disposed.
039: * <p>
040: * This class is not intended for use outside of the
041: * <code>org.eclipse.ui.workbench</code> plug-in.
042: * </p>
043: *
044: * @since 3.2
045: */
046: public class SlaveHandlerService implements IHandlerService {
047:
048: /**
049: * The default expression to use when
050: * {@link #activateHandler(String, IHandler)} is called. Handlers
051: * contributed using that method will only be active when this service is
052: * active. However, this expression will be used for conflict resolution.
053: */
054: protected final Expression defaultExpression;
055:
056: /**
057: * A collection of source providers. The listeners are not
058: * activated/deactivated, but they will be removed when this service is
059: * disposed.
060: */
061: private Collection fSourceProviders = new ArrayList();
062:
063: /**
064: * A map of the local activation to the parent activations. If this service
065: * is inactive, then all parent activations are <code>null</code>.
066: * Otherwise, they point to the corresponding activation in the parent
067: * service.
068: */
069: protected final Map localActivationsToParentActivations = new HashMap();
070:
071: /**
072: * The parent handler service to which all requests are ultimately routed.
073: * This value is never <code>null</code>.
074: */
075: protected final IHandlerService parent;
076:
077: /**
078: * The activations registered with the parent handler service. This value is
079: * never <code>null</code>.
080: */
081: protected final Set parentActivations = new HashSet();
082:
083: /**
084: * Constructs a new instance.
085: *
086: * @param parentHandlerService
087: * The parent handler service for this slave; must not be
088: * <code>null</code>.
089: * @param defaultExpression
090: * The default expression to use if none is provided. This is
091: * primarily used for conflict resolution. This value may be
092: * <code>null</code>.
093: */
094: public SlaveHandlerService(
095: final IHandlerService parentHandlerService,
096: final Expression defaultExpression) {
097: if (parentHandlerService == null) {
098: throw new NullPointerException(
099: "The parent handler service cannot be null"); //$NON-NLS-1$
100: }
101:
102: this .defaultExpression = defaultExpression;
103: this .parent = parentHandlerService;
104: }
105:
106: public final IHandlerActivation activateHandler(
107: final IHandlerActivation childActivation) {
108: final String commandId = childActivation.getCommandId();
109: final IHandler handler = childActivation.getHandler();
110: final Expression childExpression = childActivation
111: .getExpression();
112: final AndExpression expression;
113: if (childExpression instanceof AndExpression) {
114: expression = (AndExpression) childExpression;
115: } else {
116: expression = new AndExpression();
117: if (childExpression != null) {
118: expression.add(childExpression);
119: }
120: }
121: if (defaultExpression != null) {
122: expression.add(defaultExpression);
123: }
124: final int depth = childActivation.getDepth() + 1;
125: final IHandlerActivation localActivation = new HandlerActivation(
126: commandId, handler, expression, depth, this );
127:
128: return doActivation(localActivation);
129: }
130:
131: public final IHandlerActivation activateHandler(
132: final String commandId, final IHandler handler) {
133: final IHandlerActivation localActivation = new HandlerActivation(
134: commandId, handler, defaultExpression,
135: IHandlerActivation.ROOT_DEPTH, this );
136: return doActivation(localActivation);
137: }
138:
139: public final IHandlerActivation activateHandler(
140: final String commandId, final IHandler handler,
141: final Expression expression) {
142: return activateHandler(commandId, handler, expression, false);
143: }
144:
145: public final IHandlerActivation activateHandler(
146: final String commandId, final IHandler handler,
147: final Expression expression, final boolean global) {
148: if (global) {
149: final IHandlerActivation activation = parent
150: .activateHandler(commandId, handler, expression,
151: global);
152: parentActivations.add(activation);
153: return activation;
154: }
155:
156: final AndExpression andExpression;
157: if (expression instanceof AndExpression) {
158: andExpression = (AndExpression) expression;
159: } else {
160: andExpression = new AndExpression();
161: if (expression != null) {
162: andExpression.add(expression);
163: }
164: }
165: if (defaultExpression != null) {
166: andExpression.add(defaultExpression);
167: }
168: final IHandlerActivation localActivation = new HandlerActivation(
169: commandId, handler, andExpression,
170: IHandlerActivation.ROOT_DEPTH, this );
171: return doActivation(localActivation);
172: }
173:
174: public final IHandlerActivation activateHandler(
175: final String commandId, final IHandler handler,
176: final Expression expression, final int sourcePriorities) {
177: return activateHandler(commandId, handler, expression);
178: }
179:
180: public final void addSourceProvider(final ISourceProvider provider) {
181: if (!fSourceProviders.contains(provider)) {
182: fSourceProviders.add(provider);
183: }
184: parent.addSourceProvider(provider);
185: }
186:
187: public final ExecutionEvent createExecutionEvent(
188: final Command command, final Event event) {
189: return parent.createExecutionEvent(command, event);
190: }
191:
192: public final ExecutionEvent createExecutionEvent(
193: final ParameterizedCommand command, final Event event) {
194: return parent.createExecutionEvent(command, event);
195: }
196:
197: public final void deactivateHandler(
198: final IHandlerActivation activation) {
199: final IHandlerActivation parentActivation;
200: if (localActivationsToParentActivations.containsKey(activation)) {
201: parentActivation = (IHandlerActivation) localActivationsToParentActivations
202: .remove(activation);
203: } else {
204: parentActivation = activation;
205: }
206:
207: if (parentActivation != null) {
208: parent.deactivateHandler(parentActivation);
209: parentActivations.remove(parentActivation);
210: }
211: }
212:
213: public final void deactivateHandlers(final Collection activations) {
214: Object[] array = activations.toArray();
215: for (int i = 0; i < array.length; i++) {
216: deactivateHandler((IHandlerActivation) array[i]);
217: array[i] = null;
218: }
219: }
220:
221: public final void dispose() {
222: parent.deactivateHandlers(parentActivations);
223: parentActivations.clear();
224: localActivationsToParentActivations.clear();
225:
226: // Remove any "resource", like listeners, that were associated
227: // with this service.
228: if (!fSourceProviders.isEmpty()) {
229: Object[] array = fSourceProviders.toArray();
230: for (int i = 0; i < array.length; i++) {
231: removeSourceProvider((ISourceProvider) array[i]);
232: }
233: fSourceProviders.clear();
234: }
235: }
236:
237: protected IHandlerActivation doActivation(
238: final IHandlerActivation localActivation) {
239: final IHandlerActivation parentActivation;
240: parentActivation = parent.activateHandler(localActivation);
241: parentActivations.add(parentActivation);
242: localActivationsToParentActivations.put(localActivation,
243: parentActivation);
244: return localActivation;
245: }
246:
247: public final Object executeCommand(
248: final ParameterizedCommand command, final Event event)
249: throws ExecutionException, NotDefinedException,
250: NotEnabledException, NotHandledException {
251: return parent.executeCommand(command, event);
252: }
253:
254: public final Object executeCommand(final String commandId,
255: final Event event) throws ExecutionException,
256: NotDefinedException, NotEnabledException,
257: NotHandledException {
258: return parent.executeCommand(commandId, event);
259: }
260:
261: public final IEvaluationContext getCurrentState() {
262: return parent.getCurrentState();
263: }
264:
265: public final void readRegistry() {
266: parent.readRegistry();
267: }
268:
269: public final void removeSourceProvider(
270: final ISourceProvider provider) {
271: fSourceProviders.remove(provider);
272: parent.removeSourceProvider(provider);
273: }
274:
275: public final void setHelpContextId(final IHandler handler,
276: final String helpContextId) {
277: parent.setHelpContextId(handler, helpContextId);
278: }
279:
280: }
|