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.contexts;
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.contexts.Context;
020: import org.eclipse.core.commands.contexts.IContextManagerListener;
021: import org.eclipse.core.expressions.Expression;
022: import org.eclipse.swt.widgets.Shell;
023: import org.eclipse.ui.ISourceProvider;
024: import org.eclipse.ui.contexts.IContextActivation;
025: import org.eclipse.ui.contexts.IContextService;
026: import org.eclipse.ui.internal.expressions.AndExpression;
027:
028: /**
029: * A context service which delegates almost all responsibility to the parent
030: * service.
031: * <p>
032: * This class is not intended for use outside of the
033: * <code>org.eclipse.ui.workbench</code> plug-in.
034: * </p>
035: *
036: * @since 3.2
037: *
038: */
039: public class SlaveContextService implements IContextService {
040:
041: /**
042: * The parent context service, which is never <code>null</code>.
043: */
044: protected IContextService fParentService;
045:
046: /**
047: * The default expression used when {@link #activateContext(String) } is
048: * called. Contexts contributed that use this expression will only be active
049: * with this service is active.
050: */
051: protected Expression fDefaultExpression;
052:
053: /**
054: * Our contexts that are currently active with the parent context service.
055: */
056: protected Set fParentActivations;
057:
058: /**
059: * A map of the local activation to the parent activations. If this service
060: * is inactive, then all parent activations are <code>null</code>.
061: * Otherwise, they point to the corresponding activation in the parent
062: * service.
063: */
064: protected Map fLocalActivations;
065:
066: /**
067: * A collection of context manager listeners. The listeners are not
068: * activated/deactivated, but they will be removed when this service is
069: * disposed.
070: */
071: private Collection fContextManagerListeners;
072:
073: /**
074: * A collection of source providers. The listeners are not
075: * activated/deactivated, but they will be removed when this service is
076: * disposed.
077: */
078: private Collection fSourceProviders;
079:
080: /**
081: * A collection of shells registered through this service. The listeners are
082: * not activated/deactivated, but they will be removed when this service is
083: * disposed.
084: */
085: private Collection fRegisteredShells;
086:
087: /**
088: * Construct the new slave.
089: *
090: * @param parentService
091: * the parent context service; must not be <code>null</code>.
092: * @param defaultExpression
093: * A default expression to use to determine viability. It's
094: * mainly used for conflict resolution. It can be
095: * <code>null</code>.
096: */
097: public SlaveContextService(IContextService parentService,
098: Expression defaultExpression) {
099: if (parentService == null) {
100: throw new NullPointerException(
101: "The parent context service must not be null"); //$NON-NLS-1$
102: }
103: fParentService = parentService;
104: fDefaultExpression = defaultExpression;
105: fParentActivations = new HashSet();
106: fLocalActivations = new HashMap();
107: fContextManagerListeners = new ArrayList();
108: fSourceProviders = new ArrayList();
109: fRegisteredShells = new ArrayList();
110: }
111:
112: /*
113: * (non-Javadoc)
114: *
115: * @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String)
116: */
117: public IContextActivation activateContext(String contextId) {
118: ContextActivation activation = new ContextActivation(contextId,
119: fDefaultExpression, this );
120: return doActivateContext(activation);
121: }
122:
123: /*
124: * (non-Javadoc)
125: *
126: * @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
127: * org.eclipse.core.expressions.Expression)
128: */
129: public IContextActivation activateContext(String contextId,
130: Expression expression) {
131: return activateContext(contextId, expression, false);
132: }
133:
134: /*
135: * (non-Javadoc)
136: *
137: * @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
138: * org.eclipse.core.expressions.Expression, boolean)
139: */
140: public IContextActivation activateContext(String contextId,
141: Expression expression, boolean global) {
142: if (global) {
143: IContextActivation activation = fParentService
144: .activateContext(contextId, expression, global);
145: fParentActivations.add(activation);
146: return activation;
147: }
148: AndExpression andExpression = null;
149: if (expression instanceof AndExpression) {
150: andExpression = (AndExpression) expression;
151: } else {
152: andExpression = new AndExpression();
153: if (expression != null) {
154: andExpression.add(expression);
155: }
156: }
157: if (fDefaultExpression != null) {
158: andExpression.add(fDefaultExpression);
159: }
160: ContextActivation activation = new ContextActivation(contextId,
161: andExpression, this );
162: return doActivateContext(activation);
163: }
164:
165: /*
166: * (non-Javadoc)
167: *
168: * @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
169: * org.eclipse.core.expressions.Expression, int)
170: */
171: public IContextActivation activateContext(String contextId,
172: Expression expression, int sourcePriorities) {
173: return activateContext(contextId, expression);
174: }
175:
176: /*
177: * (non-Javadoc)
178: *
179: * @see org.eclipse.ui.contexts.IContextService#addContextManagerListener(org.eclipse.core.commands.contexts.IContextManagerListener)
180: */
181: public void addContextManagerListener(
182: IContextManagerListener listener) {
183: if (!fContextManagerListeners.contains(listener)) {
184: fContextManagerListeners.add(listener);
185: }
186: fParentService.addContextManagerListener(listener);
187: }
188:
189: /*
190: * (non-Javadoc)
191: *
192: * @see org.eclipse.ui.services.IServiceWithSources#addSourceProvider(org.eclipse.ui.ISourceProvider)
193: */
194: public void addSourceProvider(ISourceProvider provider) {
195: if (!fSourceProviders.contains(provider)) {
196: fSourceProviders.add(provider);
197: }
198: fParentService.addSourceProvider(provider);
199: }
200:
201: /*
202: * (non-Javadoc)
203: *
204: * @see org.eclipse.ui.contexts.IContextService#deactivateContext(org.eclipse.ui.contexts.IContextActivation)
205: */
206: public void deactivateContext(IContextActivation activation) {
207: IContextActivation parentActivation = null;
208: if (fLocalActivations.containsKey(activation)) {
209: parentActivation = (IContextActivation) fLocalActivations
210: .remove(activation);
211: } else {
212: parentActivation = activation;
213: }
214: if (parentActivation != null) {
215: fParentService.deactivateContext(parentActivation);
216: fParentActivations.remove(parentActivation);
217: }
218: }
219:
220: /*
221: * (non-Javadoc)
222: *
223: * @see org.eclipse.ui.contexts.IContextService#deactivateContexts(java.util.Collection)
224: */
225: public void deactivateContexts(Collection activations) {
226: Object[] array = activations.toArray();
227: for (int i = 0; i < array.length; i++) {
228: deactivateContext((IContextActivation) array[i]);
229: array[i] = null;
230: }
231: }
232:
233: /*
234: * (non-Javadoc)
235: *
236: * @see org.eclipse.ui.services.IDisposable#dispose()
237: */
238: public void dispose() {
239: fParentService.deactivateContexts(fParentActivations);
240: fParentActivations.clear();
241: fLocalActivations.clear();
242:
243: // Remove any "resource", like listeners, that were associated
244: // with this service.
245: if (!fContextManagerListeners.isEmpty()) {
246: Object[] array = fContextManagerListeners.toArray();
247: for (int i = 0; i < array.length; i++) {
248: removeContextManagerListener((IContextManagerListener) array[i]);
249: }
250: fContextManagerListeners.clear();
251: }
252: if (!fSourceProviders.isEmpty()) {
253: Object[] array = fSourceProviders.toArray();
254: for (int i = 0; i < array.length; i++) {
255: removeSourceProvider((ISourceProvider) array[i]);
256: }
257: fSourceProviders.clear();
258: }
259: if (!fRegisteredShells.isEmpty()) {
260: Object[] array = fRegisteredShells.toArray();
261: for (int i = 0; i < array.length; i++) {
262: unregisterShell((Shell) array[i]);
263: }
264: fRegisteredShells.clear();
265: }
266: }
267:
268: /**
269: * Activate the context with respect to this slave service.
270: *
271: * @param contextId
272: * the context id
273: * @param expression
274: * the expression to use
275: * @return the activated context
276: */
277: protected IContextActivation doActivateContext(
278: IContextActivation activation) {
279: IContextActivation parentActivation = fParentService
280: .activateContext(activation.getContextId(), activation
281: .getExpression());
282: fParentActivations.add(parentActivation);
283: fLocalActivations.put(activation, parentActivation);
284: return activation;
285: }
286:
287: /*
288: * (non-Javadoc)
289: *
290: * @see org.eclipse.ui.contexts.IContextService#getActiveContextIds()
291: */
292: public Collection getActiveContextIds() {
293: return fParentService.getActiveContextIds();
294: }
295:
296: /*
297: * (non-Javadoc)
298: *
299: * @see org.eclipse.ui.contexts.IContextService#getContext(java.lang.String)
300: */
301: public Context getContext(String contextId) {
302: return fParentService.getContext(contextId);
303: }
304:
305: /*
306: * (non-Javadoc)
307: *
308: * @see org.eclipse.ui.contexts.IContextService#getDefinedContextIds()
309: */
310: public Collection getDefinedContextIds() {
311: return fParentService.getDefinedContextIds();
312: }
313:
314: /*
315: * (non-Javadoc)
316: *
317: * @see org.eclipse.ui.contexts.IContextService#getDefinedContexts()
318: */
319: public Context[] getDefinedContexts() {
320: return fParentService.getDefinedContexts();
321: }
322:
323: /*
324: * (non-Javadoc)
325: *
326: * @see org.eclipse.ui.contexts.IContextService#getShellType(org.eclipse.swt.widgets.Shell)
327: */
328: public int getShellType(Shell shell) {
329: return fParentService.getShellType(shell);
330: }
331:
332: /*
333: * (non-Javadoc)
334: *
335: * @see org.eclipse.ui.contexts.IContextService#readRegistry()
336: */
337: public void readRegistry() {
338: fParentService.readRegistry();
339: }
340:
341: /*
342: * (non-Javadoc)
343: *
344: * @see org.eclipse.ui.contexts.IContextService#registerShell(org.eclipse.swt.widgets.Shell,
345: * int)
346: */
347: public boolean registerShell(Shell shell, int type) {
348: if (!fRegisteredShells.contains(shell)) {
349: fRegisteredShells.add(shell);
350: }
351: return fParentService.registerShell(shell, type);
352: }
353:
354: /*
355: * (non-Javadoc)
356: *
357: * @see org.eclipse.ui.contexts.IContextService#removeContextManagerListener(org.eclipse.core.commands.contexts.IContextManagerListener)
358: */
359: public void removeContextManagerListener(
360: IContextManagerListener listener) {
361: fContextManagerListeners.remove(listener);
362: fParentService.removeContextManagerListener(listener);
363: }
364:
365: /*
366: * (non-Javadoc)
367: *
368: * @see org.eclipse.ui.services.IServiceWithSources#removeSourceProvider(org.eclipse.ui.ISourceProvider)
369: */
370: public void removeSourceProvider(ISourceProvider provider) {
371: fSourceProviders.remove(provider);
372: fParentService.removeSourceProvider(provider);
373: }
374:
375: /*
376: * (non-Javadoc)
377: *
378: * @see org.eclipse.ui.contexts.IContextService#unregisterShell(org.eclipse.swt.widgets.Shell)
379: */
380: public boolean unregisterShell(Shell shell) {
381: fRegisteredShells.remove(shell);
382: return fParentService.unregisterShell(shell);
383: }
384: }
|