blob: 7422e28412e1910189923394b082f897187559f8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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.contexts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.IContextManagerListener;
import org.eclipse.core.expressions.Expression;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.internal.expressions.AndExpression;
/**
* A context service which delegates almost all responsibility to the parent
* service.
* <p>
* This class is not intended for use outside of the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*
*/
public class SlaveContextService implements IContextService {
/**
* The parent context service, which is never <code>null</code>.
*/
protected IContextService fParentService;
/**
* The default expression used when {@link #activateContext(String) } is
* called. Contexts contributed that use this expression will only be active
* with this service is active.
*/
protected Expression fDefaultExpression;
/**
* Our contexts that are currently active with the parent context service.
*/
protected Set fParentActivations;
/**
* A map of the local activation to the parent activations. If this service
* is inactive, then all parent activations are <code>null</code>.
* Otherwise, they point to the corresponding activation in the parent
* service.
*/
protected Map fLocalActivations;
/**
* A collection of context manager listeners. The listeners are not
* activated/deactivated, but they will be removed when this service is
* disposed.
*/
private Collection fContextManagerListeners;
/**
* A collection of source providers. The listeners are not
* activated/deactivated, but they will be removed when this service is
* disposed.
*/
private Collection fSourceProviders;
/**
* A collection of shells registered through this service. The listeners are
* not activated/deactivated, but they will be removed when this service is
* disposed.
*/
private Collection fRegisteredShells;
/**
* Construct the new slave.
*
* @param parentService
* the parent context service; must not be <code>null</code>.
* @param defaultExpression
* A default expression to use to determine viability. It's
* mainly used for conflict resolution. It can be
* <code>null</code>.
*/
public SlaveContextService(IContextService parentService,
Expression defaultExpression) {
if (parentService == null) {
throw new NullPointerException(
"The parent context service must not be null"); //$NON-NLS-1$
}
fParentService = parentService;
fDefaultExpression = defaultExpression;
fParentActivations = new HashSet();
fLocalActivations = new HashMap();
fContextManagerListeners = new ArrayList();
fSourceProviders = new ArrayList();
fRegisteredShells = new ArrayList();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String)
*/
public IContextActivation activateContext(String contextId) {
ContextActivation activation = new ContextActivation(contextId,
fDefaultExpression, this);
return doActivateContext(activation);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
* org.eclipse.core.expressions.Expression)
*/
public IContextActivation activateContext(String contextId,
Expression expression) {
return activateContext(contextId, expression, false);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
* org.eclipse.core.expressions.Expression, boolean)
*/
public IContextActivation activateContext(String contextId,
Expression expression, boolean global) {
if (global) {
IContextActivation activation = fParentService.activateContext(
contextId, expression, global);
fParentActivations.add(activation);
return activation;
}
AndExpression andExpression = null;
if (expression instanceof AndExpression) {
andExpression = (AndExpression) expression;
} else {
andExpression = new AndExpression();
if (expression!=null) {
andExpression.add(expression);
}
}
if (fDefaultExpression!=null) {
andExpression.add(fDefaultExpression);
}
ContextActivation activation = new ContextActivation(contextId,
andExpression, this);
return doActivateContext(activation);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#activateContext(java.lang.String,
* org.eclipse.core.expressions.Expression, int)
*/
public IContextActivation activateContext(String contextId,
Expression expression, int sourcePriorities) {
return activateContext(contextId, expression);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#addContextManagerListener(org.eclipse.core.commands.contexts.IContextManagerListener)
*/
public void addContextManagerListener(IContextManagerListener listener) {
if (!fContextManagerListeners.contains(listener)) {
fContextManagerListeners.add(listener);
}
fParentService.addContextManagerListener(listener);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.services.IServiceWithSources#addSourceProvider(org.eclipse.ui.ISourceProvider)
*/
public void addSourceProvider(ISourceProvider provider) {
if (!fSourceProviders.contains(provider)) {
fSourceProviders.add(provider);
}
fParentService.addSourceProvider(provider);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#deactivateContext(org.eclipse.ui.contexts.IContextActivation)
*/
public void deactivateContext(IContextActivation activation) {
IContextActivation parentActivation = null;
if (fLocalActivations.containsKey(activation)) {
parentActivation = (IContextActivation) fLocalActivations
.remove(activation);
} else {
parentActivation = activation;
}
if (parentActivation != null) {
fParentService.deactivateContext(parentActivation);
fParentActivations.remove(parentActivation);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#deactivateContexts(java.util.Collection)
*/
public void deactivateContexts(Collection activations) {
Object[] array = activations.toArray();
for (int i = 0; i < array.length; i++) {
deactivateContext((IContextActivation) array[i]);
array[i] = null;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.services.IDisposable#dispose()
*/
public void dispose() {
fParentService.deactivateContexts(fParentActivations);
fParentActivations.clear();
fLocalActivations.clear();
// Remove any "resource", like listeners, that were associated
// with this service.
if (!fContextManagerListeners.isEmpty()) {
Object[] array = fContextManagerListeners.toArray();
for (int i = 0; i < array.length; i++) {
removeContextManagerListener((IContextManagerListener) array[i]);
}
fContextManagerListeners.clear();
}
if (!fSourceProviders.isEmpty()) {
Object[] array = fSourceProviders.toArray();
for (int i = 0; i < array.length; i++) {
removeSourceProvider((ISourceProvider) array[i]);
}
fSourceProviders.clear();
}
if (!fRegisteredShells.isEmpty()) {
Object[] array = fRegisteredShells.toArray();
for (int i = 0; i < array.length; i++) {
unregisterShell((Shell) array[i]);
}
fRegisteredShells.clear();
}
}
/**
* Activate the context with respect to this slave service.
*
* @param contextId
* the context id
* @param expression
* the expression to use
* @return the activated context
*/
protected IContextActivation doActivateContext(IContextActivation activation) {
IContextActivation parentActivation = fParentService.activateContext(
activation.getContextId(), activation.getExpression());
fParentActivations.add(parentActivation);
fLocalActivations.put(activation, parentActivation);
return activation;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#getActiveContextIds()
*/
public Collection getActiveContextIds() {
return fParentService.getActiveContextIds();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#getContext(java.lang.String)
*/
public Context getContext(String contextId) {
return fParentService.getContext(contextId);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#getDefinedContextIds()
*/
public Collection getDefinedContextIds() {
return fParentService.getDefinedContextIds();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#getDefinedContexts()
*/
public Context[] getDefinedContexts() {
return fParentService.getDefinedContexts();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#getShellType(org.eclipse.swt.widgets.Shell)
*/
public int getShellType(Shell shell) {
return fParentService.getShellType(shell);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#readRegistry()
*/
public void readRegistry() {
fParentService.readRegistry();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#registerShell(org.eclipse.swt.widgets.Shell,
* int)
*/
public boolean registerShell(Shell shell, int type) {
if (!fRegisteredShells.contains(shell)) {
fRegisteredShells.add(shell);
}
return fParentService.registerShell(shell, type);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#removeContextManagerListener(org.eclipse.core.commands.contexts.IContextManagerListener)
*/
public void removeContextManagerListener(IContextManagerListener listener) {
fContextManagerListeners.remove(listener);
fParentService.removeContextManagerListener(listener);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.services.IServiceWithSources#removeSourceProvider(org.eclipse.ui.ISourceProvider)
*/
public void removeSourceProvider(ISourceProvider provider) {
fSourceProviders.remove(provider);
fParentService.removeSourceProvider(provider);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.contexts.IContextService#unregisterShell(org.eclipse.swt.widgets.Shell)
*/
public boolean unregisterShell(Shell shell) {
fRegisteredShells.remove(shell);
return fParentService.unregisterShell(shell);
}
}