blob: d007983cf5376ad6edc7638b6496330bb96a0196 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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.core.commands.contexts;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.commands.common.HandleObjectManager;
import org.eclipse.core.commands.util.Tracing;
import org.eclipse.core.internal.commands.util.Util;
/**
* <p>
* A context manager tracks the sets of defined and enabled contexts within the
* application. The manager sends notification events to listeners when these
* sets change. It is also possible to retrieve any given context with its
* identifier.
* </p>
* <p>
* This class is not intended to be extended by clients.
* </p>
*
* @since 3.1
*/
public final class ContextManager extends HandleObjectManager implements
IContextListener {
/**
* This flag can be set to <code>true</code> if the context manager should
* print information to <code>System.out</code> when certain boundary
* conditions occur.
*/
public static boolean DEBUG = false;
/**
* The set of active context identifiers. This value may be empty, but it is
* never <code>null</code>.
*/
private Set activeContextIds = new HashSet();
/**
* Activates a context in this context manager.
*
* @param contextId
* The identifier of the context to activate; must not be
* <code>null</code>.
*/
public final void addActiveContext(final String contextId) {
if (activeContextIds.contains(contextId)) {
return;
}
final Set previouslyActiveContextIds = new HashSet(activeContextIds);
activeContextIds.add(contextId);
if (DEBUG) {
Tracing.printTrace("CONTEXTS", activeContextIds.toString()); //$NON-NLS-1$
}
fireContextManagerChanged(new ContextManagerEvent(this, null, false,
true, previouslyActiveContextIds));
}
/**
* Adds a listener to this context manager. The listener will be notified
* when the set of defined contexts changes. This can be used to track the
* global appearance and disappearance of contexts.
*
* @param listener
* The listener to attach; must not be <code>null</code>.
*/
public final void addContextManagerListener(
final IContextManagerListener listener) {
addListenerObject(listener);
}
public final void contextChanged(final ContextEvent contextEvent) {
if (contextEvent.isDefinedChanged()) {
final Context context = contextEvent.getContext();
final String contextId = context.getId();
final boolean contextIdAdded = context.isDefined();
if (contextIdAdded) {
definedHandleObjects.add(context);
} else {
definedHandleObjects.remove(context);
}
fireContextManagerChanged(new ContextManagerEvent(this, contextId,
contextIdAdded, false, null));
}
}
/**
* Notifies all of the listeners to this manager that the set of defined
* context identifiers has changed.
*
* @param event
* The event to send to all of the listeners; must not be
* <code>null</code>.
*/
private final void fireContextManagerChanged(final ContextManagerEvent event) {
if (event == null)
throw new NullPointerException();
final Object[] listeners = getListeners();
for (int i = 0; i < listeners.length; i++) {
final IContextManagerListener listener = (IContextManagerListener) listeners[i];
listener.contextManagerChanged(event);
}
}
/**
* Returns the set of active context identifiers.
*
* @return The set of active context identifiers; this value may be
* <code>null</code> if no active contexts have been set yet. If
* the set is not <code>null</code>, then it contains only
* instances of <code>String</code>.
*/
public final Set getActiveContextIds() {
return Collections.unmodifiableSet(activeContextIds);
}
/**
* Gets the context with the given identifier. If no such context currently
* exists, then the context will be created (but be undefined).
*
* @param contextId
* The identifier to find; must not be <code>null</code>.
* @return The context with the given identifier; this value will never be
* <code>null</code>, but it might be undefined.
* @see Context
*/
public final Context getContext(final String contextId) {
checkId(contextId);
Context context = (Context) handleObjectsById.get(contextId);
if (context == null) {
context = new Context(contextId);
handleObjectsById.put(contextId, context);
context.addContextListener(this);
}
return context;
}
/**
* Returns the set of identifiers for those contexts that are defined.
*
* @return The set of defined context identifiers; this value may be empty,
* but it is never <code>null</code>.
*/
public final Set getDefinedContextIds() {
return getDefinedHandleObjectIds();
}
/**
* Returns the those contexts that are defined.
*
* @return The defined contexts; this value may be empty, but it is never
* <code>null</code>.
* @since 3.2
*/
public final Context[] getDefinedContexts() {
return (Context[]) definedHandleObjects
.toArray(new Context[definedHandleObjects.size()]);
}
/**
* Deactivates a context in this context manager.
*
* @param contextId
* The identifier of the context to deactivate; must not be
* <code>null</code>.
*/
public final void removeActiveContext(final String contextId) {
if (!activeContextIds.contains(contextId)) {
return;
}
final Set previouslyActiveContextIds = new HashSet(activeContextIds);
activeContextIds.remove(contextId);
if (DEBUG) {
Tracing.printTrace("CONTEXTS", activeContextIds.toString()); //$NON-NLS-1$
}
fireContextManagerChanged(new ContextManagerEvent(this, null, false,
true, previouslyActiveContextIds));
}
/**
* Removes a listener from this context manager.
*
* @param listener
* The listener to be removed; must not be <code>null</code>.
*/
public final void removeContextManagerListener(
final IContextManagerListener listener) {
removeListenerObject(listener);
}
/**
* Changes the set of active contexts for this context manager. The whole
* set is required so that internal consistency can be maintained and so
* that excessive recomputations do nothing occur.
*
* @param activeContextIds
* The new set of active context identifiers; may be
* <code>null</code>.
*/
public final void setActiveContextIds(final Set activeContextIds) {
if (Util.equals(this.activeContextIds, activeContextIds)) {
return;
}
final Set previouslyActiveContextIds = this.activeContextIds;
if (activeContextIds != null) {
this.activeContextIds = new HashSet();
this.activeContextIds.addAll(activeContextIds);
} else {
this.activeContextIds = null;
}
if (DEBUG) {
Tracing.printTrace("CONTEXTS", activeContextIds.toString()); //$NON-NLS-1$
}
fireContextManagerChanged(new ContextManagerEvent(this, null, false,
true, previouslyActiveContextIds));
}
}