Copyright (c) 2004, 2015 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.commands.contexts;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import org.eclipse.core.commands.common.NamedHandleObject;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.internal.commands.util.Util;
A context is an answer to the question "when". Other services can listen for
the activation and deactivation of contexts, and change their own state in
response to these changes. For example, Eclipse's key binding service listens
to context activation and deactivation to determine which key bindings should
be active.
An instance of this interface can be obtained from an instance of
ContextManager
for any identifier, whether or not an context
with that identifier is defined in the extension registry.
The handle-based nature of this API allows it to work well with runtime
plugin activation and deactivation. If a context is defined, that means that
its corresponding plug-in is active. If the plug-in is then deactivated, the
context will still exist but it will be undefined. An attempts to use an
undefined context will result in a NotDefinedException
being
thrown.
This class is not intended to be extended by clients.
See Also: Since: 3.1
/**
* <p>
* A context is an answer to the question "when". Other services can listen for
* the activation and deactivation of contexts, and change their own state in
* response to these changes. For example, Eclipse's key binding service listens
* to context activation and deactivation to determine which key bindings should
* be active.
* </p>
* <p>
* An instance of this interface can be obtained from an instance of
* <code>ContextManager</code> for any identifier, whether or not an context
* with that identifier is defined in the extension registry.
* </p>
* <p>
* The handle-based nature of this API allows it to work well with runtime
* plugin activation and deactivation. If a context is defined, that means that
* its corresponding plug-in is active. If the plug-in is then deactivated, the
* context will still exist but it will be undefined. An attempts to use an
* undefined context will result in a <code>NotDefinedException</code> being
* thrown.
* </p>
* <p>
* This class is not intended to be extended by clients.
* </p>
*
* @since 3.1
* @see ContextManager
*/
@SuppressWarnings("rawtypes")
public final class Context extends NamedHandleObject implements Comparable {
The collection of all objects listening to changes on this context. This
value is null
if there are no listeners.
/**
* The collection of all objects listening to changes on this context. This
* value is <code>null</code> if there are no listeners.
*/
private Set<IContextListener> listeners;
The parent identifier for this context. The meaning of a parent is
dependent on the system using contexts. This value can be
null
if the context has no parent.
/**
* The parent identifier for this context. The meaning of a parent is
* dependent on the system using contexts. This value can be
* <code>null</code> if the context has no parent.
*/
private String parentId;
Constructs a new instance of Context
.
Params: - id –
The id for this context; must not be
null
.
/**
* Constructs a new instance of <code>Context</code>.
*
* @param id
* The id for this context; must not be <code>null</code>.
*/
Context(final String id) {
super(id);
}
Registers an instance of IContextListener
to listen for
changes to properties of this instance.
Params: - listener –
the instance to register. Must not be
null
. If
an attempt is made to register an instance which is already
registered with this instance, no operation is performed.
/**
* Registers an instance of <code>IContextListener</code> to listen for
* changes to properties of this instance.
*
* @param listener
* the instance to register. Must not be <code>null</code>. If
* an attempt is made to register an instance which is already
* registered with this instance, no operation is performed.
*/
public final void addContextListener(final IContextListener listener) {
if (listener == null) {
throw new NullPointerException();
}
if (listeners == null) {
listeners = new HashSet<>();
}
listeners.add(listener);
}
@Override
public final int compareTo(final Object object) {
final Context scheme = (Context) object;
int compareTo = Util.compare(this.id, scheme.id);
if (compareTo == 0) {
compareTo = Util.compare(this.name, scheme.name);
if (compareTo == 0) {
compareTo = Util.compare(this.parentId, scheme.parentId);
if (compareTo == 0) {
compareTo = Util.compare(this.description, scheme.description);
if (compareTo == 0) {
compareTo = Util.compare(this.defined, scheme.defined);
}
}
}
}
return compareTo;
}
Defines this context by giving it a name, and possibly a description and
a parent identifier as well. The defined property automatically becomes
true
.
Notification is sent to all listeners that something has changed.
Params: - name –
The name of this context; must not be
null
. - description –
The description for this context; may be
null
. - parentId –
The parent identifier for this context; may be
null
.
/**
* <p>
* Defines this context by giving it a name, and possibly a description and
* a parent identifier as well. The defined property automatically becomes
* <code>true</code>.
* </p>
* <p>
* Notification is sent to all listeners that something has changed.
* </p>
*
* @param name
* The name of this context; must not be <code>null</code>.
* @param description
* The description for this context; may be <code>null</code>.
* @param parentId
* The parent identifier for this context; may be
* <code>null</code>.
*/
public final void define(final String name, final String description, final String parentId) {
if (name == null) {
throw new NullPointerException("The name of a context cannot be null"); //$NON-NLS-1$
}
final boolean definedChanged = !this.defined;
this.defined = true;
final boolean nameChanged = !Objects.equals(this.name, name);
this.name = name;
final boolean descriptionChanged = !Objects.equals(this.description,
description);
this.description = description;
final boolean parentIdChanged = !Objects.equals(this.parentId, parentId);
this.parentId = parentId;
fireContextChanged(new ContextEvent(this, definedChanged, nameChanged, descriptionChanged, parentIdChanged));
}
Notifies all listeners that this context has changed. This sends the
given event to all of the listeners, if any.
Params: - event –
The event to send to the listeners; must not be
null
.
/**
* Notifies all listeners that this context has changed. This sends the
* given event to all of the listeners, if any.
*
* @param event
* The event to send to the listeners; must not be
* <code>null</code>.
*/
private final void fireContextChanged(final ContextEvent event) {
if (event == null) {
throw new NullPointerException("Cannot send a null event to listeners."); //$NON-NLS-1$
}
if (listeners == null) {
return;
}
final Iterator<IContextListener> listenerItr = listeners.iterator();
while (listenerItr.hasNext()) {
final IContextListener listener = listenerItr.next();
listener.contextChanged(event);
}
}
Returns the identifier of the parent of this instance.
Notification is sent to all registered listeners if this property
changes.
Throws: - NotDefinedException –
if this instance is not defined.
Returns: the identifier of the parent of this instance. May be
null
.
/**
* Returns the identifier of the parent of this instance.
* <p>
* Notification is sent to all registered listeners if this property
* changes.
* </p>
*
* @return the identifier of the parent of this instance. May be
* <code>null</code>.
* @throws NotDefinedException
* if this instance is not defined.
*/
public final String getParentId() throws NotDefinedException {
if (!defined) {
throw new NotDefinedException("Cannot get the parent identifier from an undefined context. " //$NON-NLS-1$
+ id);
}
return parentId;
}
Unregisters an instance of IContextListener
listening for
changes to properties of this instance.
Params: - contextListener –
the instance to unregister. Must not be
null
.
If an attempt is made to unregister an instance which is not
already registered with this instance, no operation is
performed.
/**
* Unregisters an instance of <code>IContextListener</code> listening for
* changes to properties of this instance.
*
* @param contextListener
* the instance to unregister. Must not be <code>null</code>.
* If an attempt is made to unregister an instance which is not
* already registered with this instance, no operation is
* performed.
*/
public final void removeContextListener(final IContextListener contextListener) {
if (contextListener == null) {
throw new NullPointerException("Cannot remove a null listener."); //$NON-NLS-1$
}
if (listeners == null) {
return;
}
listeners.remove(contextListener);
if (listeners.isEmpty()) {
listeners = null;
}
}
The string representation of this context -- for debugging purposes only.
This string should not be shown to an end user.
Returns: The string representation; never null
.
/**
* The string representation of this context -- for debugging purposes only.
* This string should not be shown to an end user.
*
* @return The string representation; never <code>null</code>.
*/
@Override
public final String toString() {
if (string == null) {
final StringBuilder stringBuffer = new StringBuilder("Context("); //$NON-NLS-1$
stringBuffer.append(id);
stringBuffer.append(',');
stringBuffer.append(name);
stringBuffer.append(',');
stringBuffer.append(description);
stringBuffer.append(',');
stringBuffer.append(parentId);
stringBuffer.append(',');
stringBuffer.append(defined);
stringBuffer.append(')');
string = stringBuffer.toString();
}
return string;
}
Makes this context become undefined. This has the side effect of changing
the name, description and parent identifier to null
.
Notification is sent to all listeners.
/**
* Makes this context become undefined. This has the side effect of changing
* the name, description and parent identifier to <code>null</code>.
* Notification is sent to all listeners.
*/
@Override
public final void undefine() {
string = null;
final boolean definedChanged = defined;
defined = false;
final boolean nameChanged = name != null;
name = null;
final boolean descriptionChanged = description != null;
description = null;
final boolean parentIdChanged = parentId != null;
parentId = null;
fireContextChanged(new ContextEvent(this, definedChanged, nameChanged, descriptionChanged, parentIdChanged));
}
}