Copyright (c) 2004, 2016 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, 2016 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;
import java.util.Arrays;
import java.util.Objects;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.internal.util.Tracing;
import org.eclipse.core.internal.commands.util.Util;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
A command is an abstract representation for some semantic behaviour. It is
not the actual implementation of this behaviour, nor is it the visual
appearance of this behaviour in the user interface. Instead, it is a bridge
between the two.
The concept of a command is based on the command design pattern. The notable
difference is how the command delegates responsibility for execution. Rather
than allowing concrete subclasses, it uses a handler mechanism (see the
handlers
extension point). This provides another level of
indirection.
A command will exist in two states: defined and undefined. A command is
defined if it is declared in the XML of a resolved plug-in. If the plug-in is
unloaded or the command is simply not declared, then it is undefined. Trying
to reference an undefined command will succeed, but trying to access any of
its functionality will fail with a NotDefinedException
. If
you need to know when a command changes from defined to undefined (or vice
versa), then attach a command listener.
Commands are mutable and will change as their definition changes.
Since: 3.1
/**
* <p>
* A command is an abstract representation for some semantic behaviour. It is
* not the actual implementation of this behaviour, nor is it the visual
* appearance of this behaviour in the user interface. Instead, it is a bridge
* between the two.
* </p>
* <p>
* The concept of a command is based on the command design pattern. The notable
* difference is how the command delegates responsibility for execution. Rather
* than allowing concrete subclasses, it uses a handler mechanism (see the
* <code>handlers</code> extension point). This provides another level of
* indirection.
* </p>
* <p>
* A command will exist in two states: defined and undefined. A command is
* defined if it is declared in the XML of a resolved plug-in. If the plug-in is
* unloaded or the command is simply not declared, then it is undefined. Trying
* to reference an undefined command will succeed, but trying to access any of
* its functionality will fail with a <code>NotDefinedException</code>. If
* you need to know when a command changes from defined to undefined (or vice
* versa), then attach a command listener.
* </p>
* <p>
* Commands are mutable and will change as their definition changes.
* </p>
*
* @since 3.1
*/
@SuppressWarnings("rawtypes")
public final class Command extends NamedHandleObjectWithState implements Comparable {
This flag can be set to true
if commands should print
information to System.out
when executing.
/**
* This flag can be set to <code>true</code> if commands should print
* information to <code>System.out</code> when executing.
*/
public static boolean DEBUG_COMMAND_EXECUTION;
This flag can be set to true
if commands should print
information to System.out
when changing handlers.
/**
* This flag can be set to <code>true</code> if commands should print
* information to <code>System.out</code> when changing handlers.
*/
public static boolean DEBUG_HANDLERS;
This flag can be set to a particular command identifier if only that
command should print information to System.out
when
changing handlers.
/**
* This flag can be set to a particular command identifier if only that
* command should print information to <code>System.out</code> when
* changing handlers.
*/
public static String DEBUG_HANDLERS_COMMAND_ID;
The category to which this command belongs. This value should not be
null
unless the command is undefined.
/**
* The category to which this command belongs. This value should not be
* <code>null</code> unless the command is undefined.
*/
private Category category;
A collection of objects listening to the execution of this command. This
collection is null
if there are no listeners.
/**
* A collection of objects listening to the execution of this command. This
* collection is <code>null</code> if there are no listeners.
*/
private transient ListenerList<IExecutionListener> executionListeners;
boolean shouldFireEvents = true;
The handler currently associated with this command. This value may be
null
if there is no handler currently.
/**
* The handler currently associated with this command. This value may be
* <code>null</code> if there is no handler currently.
*/
private transient IHandler handler;
The help context identifier for this command. This can be
null
if there is no help currently associated with the
command.
Since: 3.2
/**
* The help context identifier for this command. This can be
* <code>null</code> if there is no help currently associated with the
* command.
*
* @since 3.2
*/
private String helpContextId;
The ordered array of parameters understood by this command. This value
may be null
if there are no parameters, or if the command
is undefined. It may also be empty.
/**
* The ordered array of parameters understood by this command. This value
* may be <code>null</code> if there are no parameters, or if the command
* is undefined. It may also be empty.
*/
private IParameter[] parameters;
The type of the return value of this command. This value may be
null
if the command does not declare a return type.
Since: 3.2
/**
* The type of the return value of this command. This value may be
* <code>null</code> if the command does not declare a return type.
*
* @since 3.2
*/
private ParameterType returnType;
Our command will listen to the active handler for enablement changes so
that they can be fired from the command itself.
Since: 3.3
/**
* Our command will listen to the active handler for enablement changes so
* that they can be fired from the command itself.
*
* @since 3.3
*/
private IHandlerListener handlerListener;
Constructs a new instance of Command
based on the given
identifier. When a command is first constructed, it is undefined.
Commands should only be constructed by the CommandManager
to ensure that the identifier remains unique.
Params: - id –
The identifier for the command. This value must not be
null
, and must be unique amongst all commands.
/**
* Constructs a new instance of <code>Command</code> based on the given
* identifier. When a command is first constructed, it is undefined.
* Commands should only be constructed by the <code>CommandManager</code>
* to ensure that the identifier remains unique.
*
* @param id
* The identifier for the command. This value must not be
* <code>null</code>, and must be unique amongst all commands.
*/
Command(final String id) {
super(id);
}
Adds a listener to this command that will be notified when this command's
state changes.
Params: - commandListener –
The listener to be added; must not be
null
.
/**
* Adds a listener to this command that will be notified when this command's
* state changes.
*
* @param commandListener
* The listener to be added; must not be <code>null</code>.
*/
public void addCommandListener(final ICommandListener commandListener) {
if (commandListener == null) {
throw new NullPointerException("Cannot add a null command listener"); //$NON-NLS-1$
}
addListenerObject(commandListener);
}
Adds a listener to this command that will be notified when this command
is about to execute.
Params: - executionListener –
The listener to be added; must not be
null
.
/**
* Adds a listener to this command that will be notified when this command
* is about to execute.
*
* @param executionListener
* The listener to be added; must not be <code>null</code>.
*/
public void addExecutionListener(final IExecutionListener executionListener) {
if (executionListener == null) {
throw new NullPointerException("Cannot add a null execution listener"); //$NON-NLS-1$
}
if (executionListeners == null) {
executionListeners = new ListenerList<>(ListenerList.IDENTITY);
}
executionListeners.add(executionListener);
}
Adds a state to this command. This will add this state to the active handler, if the active handler is an instance of IObjectWithState
.
A single instance of State
cannot be registered with multiple commands. Each command requires its own unique instance.
Params: - id –
The identifier of the state to add; must not be
null
. - state –
The state to add; must not be
null
.
Since: 3.2
/**
* <p>
* Adds a state to this command. This will add this state to the active
* handler, if the active handler is an instance of {@link IObjectWithState}.
* </p>
* <p>
* A single instance of {@link State} cannot be registered with multiple
* commands. Each command requires its own unique instance.
* </p>
*
* @param id
* The identifier of the state to add; must not be
* <code>null</code>.
* @param state
* The state to add; must not be <code>null</code>.
* @since 3.2
*/
@Override
public void addState(final String id, final State state) {
super.addState(id, state);
state.setId(id);
if (handler instanceof IObjectWithState) {
((IObjectWithState) handler).addState(id, state);
}
}
Compares this command with another command by comparing each of its
non-transient attributes.
Params: - object –
The object with which to compare; must be an instance of
Command
.
Returns: A negative integer, zero or a postivie integer, if the object is
greater than, equal to or less than this command.
/**
* Compares this command with another command by comparing each of its
* non-transient attributes.
*
* @param object
* The object with which to compare; must be an instance of
* <code>Command</code>.
* @return A negative integer, zero or a postivie integer, if the object is
* greater than, equal to or less than this command.
*/
@Override
public int compareTo(final Object object) {
final Command castedObject = (Command) object;
int compareTo = Util.compare(category, castedObject.category);
if (compareTo == 0) {
compareTo = Util.compare(defined, castedObject.defined);
if (compareTo == 0) {
compareTo = Util.compare(description, castedObject.description);
if (compareTo == 0) {
compareTo = Util.compare(handler, castedObject.handler);
if (compareTo == 0) {
compareTo = Util.compare(id, castedObject.id);
if (compareTo == 0) {
compareTo = Util.compare(name, castedObject.name);
if (compareTo == 0) {
compareTo = Util.compare(parameters, castedObject.parameters);
}
}
}
}
}
}
return compareTo;
}
Defines this command by giving it a name, and possibly a description as
well. The defined property automatically becomes true
.
Notification is sent to all listeners that something has changed.
Params: - name –
The name of this command; must not be
null
. - description –
The description for this command; may be
null
. - category –
The category for this command; must not be
null
.
Since: 3.2
/**
* <p>
* Defines this command by giving it a name, and possibly a description 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 command; must not be <code>null</code>.
* @param description
* The description for this command; may be <code>null</code>.
* @param category
* The category for this command; must not be <code>null</code>.
* @since 3.2
*/
public void define(final String name, final String description, final Category category) {
define(name, description, category, null);
}
Defines this command by giving it a name, and possibly a description as
well. The defined property automatically becomes true
.
Notification is sent to all listeners that something has changed.
Params: - name –
The name of this command; must not be
null
. - description –
The description for this command; may be
null
. - category –
The category for this command; must not be
null
. - parameters –
The parameters understood by this command. This value may be
either
null
or empty if the command does not
accept parameters.
/**
* <p>
* Defines this command by giving it a name, and possibly a description 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 command; must not be <code>null</code>.
* @param description
* The description for this command; may be <code>null</code>.
* @param category
* The category for this command; must not be <code>null</code>.
* @param parameters
* The parameters understood by this command. This value may be
* either <code>null</code> or empty if the command does not
* accept parameters.
*/
public void define(final String name, final String description,
final Category category, final IParameter[] parameters) {
define(name, description, category, parameters, null);
}
Defines this command by giving it a name, and possibly a description as
well. The defined property automatically becomes true
.
Notification is sent to all listeners that something has changed.
Params: - name –
The name of this command; must not be
null
. - description –
The description for this command; may be
null
. - category –
The category for this command; must not be
null
. - parameters –
The parameters understood by this command. This value may be
either
null
or empty if the command does not
accept parameters. - returnType –
The type of value returned by this command. This value may be
null
if the command does not declare a return
type.
Since: 3.2
/**
* <p>
* Defines this command by giving it a name, and possibly a description 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 command; must not be <code>null</code>.
* @param description
* The description for this command; may be <code>null</code>.
* @param category
* The category for this command; must not be <code>null</code>.
* @param parameters
* The parameters understood by this command. This value may be
* either <code>null</code> or empty if the command does not
* accept parameters.
* @param returnType
* The type of value returned by this command. This value may be
* <code>null</code> if the command does not declare a return
* type.
* @since 3.2
*/
public void define(final String name, final String description,
final Category category, final IParameter[] parameters,
ParameterType returnType) {
define(name, description, category, parameters, returnType, null);
}
Defines this command by giving it a name, and possibly a description as
well. The defined property automatically becomes true
.
Notification is sent to all listeners that something has changed.
Params: - name –
The name of this command; must not be
null
. - description –
The description for this command; may be
null
. - category –
The category for this command; must not be
null
. - parameters –
The parameters understood by this command. This value may be
either
null
or empty if the command does not
accept parameters. - returnType –
The type of value returned by this command. This value may be
null
if the command does not declare a return
type. - helpContextId –
The identifier of the help context to associate with this
command; may be
null
if this command does not
have any help associated with it.
Since: 3.2
/**
* <p>
* Defines this command by giving it a name, and possibly a description 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 command; must not be <code>null</code>.
* @param description
* The description for this command; may be <code>null</code>.
* @param category
* The category for this command; must not be <code>null</code>.
* @param parameters
* The parameters understood by this command. This value may be
* either <code>null</code> or empty if the command does not
* accept parameters.
* @param returnType
* The type of value returned by this command. This value may be
* <code>null</code> if the command does not declare a return
* type.
* @param helpContextId
* The identifier of the help context to associate with this
* command; may be <code>null</code> if this command does not
* have any help associated with it.
* @since 3.2
*/
public void define(final String name, final String description,
final Category category, final IParameter[] parameters,
ParameterType returnType, final String helpContextId) {
if (name == null) {
throw new NullPointerException("The name of a command cannot be null"); //$NON-NLS-1$
}
if (category == null) {
throw new NullPointerException("The category of a command 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 categoryChanged = !Objects.equals(this.category, category);
this.category = category;
final boolean parametersChanged = !Arrays.equals(this.parameters,
parameters);
this.parameters = parameters;
final boolean returnTypeChanged = !Objects.equals(this.returnType,
returnType);
this.returnType = returnType;
final boolean helpContextIdChanged = !Objects.equals(this.helpContextId,
helpContextId);
this.helpContextId = helpContextId;
fireCommandChanged(new CommandEvent(this, categoryChanged,
definedChanged, descriptionChanged, false, nameChanged,
parametersChanged, returnTypeChanged, helpContextIdChanged));
}
Executes this command by delegating to the current handler, if any. If the debugging flag is set, then this method prints information about which handler is selected for performing this command. This method will succeed regardless of whether the command is enabled or defined. It is generally preferred to call executeWithChecks(ExecutionEvent)
. Params: - event –
An event containing all the information about the current
state of the application; must not be
null
.
Throws: - ExecutionException –
If the handler has problems executing this command.
- NotHandledException –
If there is no handler.
Returns: The result of the execution; may be null
. This
result will be available to the client executing the command, and
execution listeners. Deprecated: Please use executeWithChecks(ExecutionEvent)
instead.
/**
* Executes this command by delegating to the current handler, if any. If
* the debugging flag is set, then this method prints information about
* which handler is selected for performing this command. This method will
* succeed regardless of whether the command is enabled or defined. It is
* generally preferred to call {@link #executeWithChecks(ExecutionEvent)}.
*
* @param event
* An event containing all the information about the current
* state of the application; must not be <code>null</code>.
* @return The result of the execution; may be <code>null</code>. This
* result will be available to the client executing the command, and
* execution listeners.
* @throws ExecutionException
* If the handler has problems executing this command.
* @throws NotHandledException
* If there is no handler.
* @deprecated Please use {@link #executeWithChecks(ExecutionEvent)}
* instead.
*/
@Deprecated
public Object execute(final ExecutionEvent event) throws ExecutionException, NotHandledException {
if (shouldFireEvents) {
firePreExecute(event);
}
final IHandler handler = this.handler;
// Perform the execution, if there is a handler.
if ((handler != null) && (handler.isHandled())) {
try {
final Object returnValue = handler.execute(event);
if (shouldFireEvents) {
firePostExecuteSuccess(returnValue);
}
return returnValue;
} catch (final ExecutionException e) {
if (shouldFireEvents) {
firePostExecuteFailure(e);
}
throw e;
}
}
final NotHandledException e = new NotHandledException("There is no handler to execute. " + getId()); //$NON-NLS-1$
if (shouldFireEvents) {
fireNotHandled(e);
}
throw e;
}
Executes this command by delegating to the current handler, if any. If
the debugging flag is set, then this method prints information about
which handler is selected for performing this command. This does checks
to see if the command is enabled and defined. If it is not both enabled
and defined, then the execution listeners will be notified and an
exception thrown.
Params: - event –
An event containing all the information about the current
state of the application; must not be
null
.
Throws: - ExecutionException –
If the handler has problems executing this command.
- NotDefinedException –
If the command you are trying to execute is not defined.
- NotEnabledException –
If the command you are trying to execute is not enabled.
- NotHandledException –
If there is no handler.
Returns: The result of the execution; may be null
. This
result will be available to the client executing the command, and
execution listeners. Since: 3.2
/**
* Executes this command by delegating to the current handler, if any. If
* the debugging flag is set, then this method prints information about
* which handler is selected for performing this command. This does checks
* to see if the command is enabled and defined. If it is not both enabled
* and defined, then the execution listeners will be notified and an
* exception thrown.
*
* @param event
* An event containing all the information about the current
* state of the application; must not be <code>null</code>.
* @return The result of the execution; may be <code>null</code>. This
* result will be available to the client executing the command, and
* execution listeners.
* @throws ExecutionException
* If the handler has problems executing this command.
* @throws NotDefinedException
* If the command you are trying to execute is not defined.
* @throws NotEnabledException
* If the command you are trying to execute is not enabled.
* @throws NotHandledException
* If there is no handler.
* @since 3.2
*/
public Object executeWithChecks(final ExecutionEvent event)
throws ExecutionException, NotDefinedException, NotEnabledException, NotHandledException {
if (shouldFireEvents) {
firePreExecute(event);
}
final IHandler handler = this.handler;
if (!isDefined()) {
final NotDefinedException exception = new NotDefinedException(
"Trying to execute a command that is not defined. " //$NON-NLS-1$
+ getId());
if (shouldFireEvents) {
fireNotDefined(exception);
}
throw exception;
}
// Perform the execution, if there is a handler.
if ((handler != null) && (handler.isHandled())) {
setEnabled(event.getApplicationContext());
if (!isEnabled()) {
final NotEnabledException exception = new NotEnabledException(
"Trying to execute the disabled command " + getId()); //$NON-NLS-1$
if (shouldFireEvents) {
fireNotEnabled(exception);
}
throw exception;
}
try {
final Object returnValue = handler.execute(event);
if (shouldFireEvents) {
firePostExecuteSuccess(returnValue);
}
return returnValue;
} catch (final ExecutionException e) {
if (shouldFireEvents) {
firePostExecuteFailure(e);
}
throw e;
}
}
final NotHandledException e = new NotHandledException("There is no handler to execute for command " + getId()); //$NON-NLS-1$
if (shouldFireEvents) {
fireNotHandled(e);
}
throw e;
}
Notifies the listeners for this command that it has changed in some way.
Params: - commandEvent –
The event to send to all of the listener; must not be
null
.
/**
* Notifies the listeners for this command that it has changed in some way.
*
* @param commandEvent
* The event to send to all of the listener; must not be
* <code>null</code>.
*/
private void fireCommandChanged(final CommandEvent commandEvent) {
if (commandEvent == null) {
throw new NullPointerException("Cannot fire a null event"); //$NON-NLS-1$
}
for (Object listener : getListeners()) {
final ICommandListener commandListener = (ICommandListener) listener;
SafeRunner.run(new ISafeRunnable() {
@Override
public void handleException(Throwable exception) {
}
@Override
public void run() throws Exception {
commandListener.commandChanged(commandEvent);
}
});
}
}
Notifies the execution listeners for this command that an attempt to
execute has failed because the command is not defined.
Params: - e –
The exception that is about to be thrown; never
null
.
Since: 3.2
/**
* Notifies the execution listeners for this command that an attempt to
* execute has failed because the command is not defined.
*
* @param e
* The exception that is about to be thrown; never
* <code>null</code>.
* @since 3.2
*/
private void fireNotDefined(final NotDefinedException e) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "not defined: id=" + getId() + "; exception=" + e); //$NON-NLS-1$ //$NON-NLS-2$
}
if (executionListeners != null) {
for (final IExecutionListener object : executionListeners) {
if (object instanceof IExecutionListenerWithChecks) {
final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object;
listener.notDefined(getId(), e);
}
}
}
}
Notifies the execution listeners for this command that an attempt to
execute has failed because there is no handler.
Params: - e –
The exception that is about to be thrown; never
null
.
Since: 3.2
/**
* Notifies the execution listeners for this command that an attempt to
* execute has failed because there is no handler.
*
* @param e
* The exception that is about to be thrown; never
* <code>null</code>.
* @since 3.2
*/
private void fireNotEnabled(final NotEnabledException e) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "not enabled: id=" + getId() + "; exception=" + e); //$NON-NLS-1$ //$NON-NLS-2$
}
if (executionListeners != null) {
for (final IExecutionListener object : executionListeners) {
if (object instanceof IExecutionListenerWithChecks) {
final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object;
listener.notEnabled(getId(), e);
}
}
}
}
Notifies the execution listeners for this command that an attempt to
execute has failed because there is no handler.
Params: - e –
The exception that is about to be thrown; never
null
.
/**
* Notifies the execution listeners for this command that an attempt to
* execute has failed because there is no handler.
*
* @param e
* The exception that is about to be thrown; never
* <code>null</code>.
*/
private void fireNotHandled(final NotHandledException e) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "not handled: id=" + getId() + "; exception=" + e); //$NON-NLS-1$ //$NON-NLS-2$
}
if (executionListeners != null) {
for (final IExecutionListener listener : executionListeners) {
listener.notHandled(getId(), e);
}
}
}
Notifies the execution listeners for this command that an attempt to
execute has failed during the execution.
Params: - e –
The exception that has been thrown; never
null
.
After this method completes, the exception will be thrown
again.
/**
* Notifies the execution listeners for this command that an attempt to
* execute has failed during the execution.
*
* @param e
* The exception that has been thrown; never <code>null</code>.
* After this method completes, the exception will be thrown
* again.
*/
private void firePostExecuteFailure(final ExecutionException e) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "failure: id=" + getId() + "; exception=" + e); //$NON-NLS-1$ //$NON-NLS-2$
}
if (executionListeners != null) {
for (final IExecutionListener listener : executionListeners) {
listener.postExecuteFailure(getId(), e);
}
}
}
Notifies the execution listeners for this command that an execution has
completed successfully.
Params: - returnValue –
The return value from the command; may be
null
.
/**
* Notifies the execution listeners for this command that an execution has
* completed successfully.
*
* @param returnValue
* The return value from the command; may be <code>null</code>.
*/
private void firePostExecuteSuccess(final Object returnValue) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "success: id=" + getId() + "; returnValue=" //$NON-NLS-1$ //$NON-NLS-2$
+ returnValue);
}
if (executionListeners != null) {
for (final IExecutionListener listener : executionListeners) {
listener.postExecuteSuccess(getId(), returnValue);
}
}
}
Notifies the execution listeners for this command that an attempt to
execute is about to start.
Params: - event –
The execution event that will be used; never
null
.
/**
* Notifies the execution listeners for this command that an attempt to
* execute is about to start.
*
* @param event
* The execution event that will be used; never <code>null</code>.
*/
private void firePreExecute(final ExecutionEvent event) {
// Debugging output
if (DEBUG_COMMAND_EXECUTION) {
Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR //$NON-NLS-1$ //$NON-NLS-2$
+ "starting: id=" + getId() + "; event=" + event); //$NON-NLS-1$ //$NON-NLS-2$
}
if (executionListeners != null) {
for (final IExecutionListener listener : executionListeners) {
listener.preExecute(getId(), event);
}
}
}
Returns the category for this command.
Throws: - NotDefinedException –
If the handle is not currently defined.
Returns: The category for this command; never null
.
/**
* Returns the category for this command.
*
* @return The category for this command; never <code>null</code>.
* @throws NotDefinedException
* If the handle is not currently defined.
*/
public Category getCategory() throws NotDefinedException {
if (!isDefined()) {
throw new NotDefinedException("Cannot get the category from an undefined command. " //$NON-NLS-1$
+ id);
}
return category;
}
Returns the current handler for this command. This is used by the command
manager for determining the appropriate help context identifiers and by
the command service to allow handlers to update elements.
This value can change at any time and should never be cached.
Returns: The current handler for this command; may be null
. Since: 3.3
/**
* Returns the current handler for this command. This is used by the command
* manager for determining the appropriate help context identifiers and by
* the command service to allow handlers to update elements.
* <p>
* This value can change at any time and should never be cached.
* </p>
*
* @return The current handler for this command; may be <code>null</code>.
* @since 3.3
*/
public IHandler getHandler() {
return handler;
}
Returns the help context identifier associated with this command. This method should not be called by clients. Clients should use CommandManager.getHelpContextId(Command)
instead. Returns: The help context identifier for this command; may be
null
if there is none. Since: 3.2
/**
* Returns the help context identifier associated with this command. This
* method should not be called by clients. Clients should use
* {@link CommandManager#getHelpContextId(Command)} instead.
*
* @return The help context identifier for this command; may be
* <code>null</code> if there is none.
* @since 3.2
*/
String getHelpContextId() {
return helpContextId;
}
Returns the parameter with the provided id or null
if this
command does not have a parameter with the id.
Params: - parameterId –
The id of the parameter to retrieve.
Throws: - NotDefinedException –
If the handle is not currently defined.
Returns: The parameter with the provided id or null
if this
command does not have a parameter with the id. Since: 3.2
/**
* Returns the parameter with the provided id or <code>null</code> if this
* command does not have a parameter with the id.
*
* @param parameterId
* The id of the parameter to retrieve.
* @return The parameter with the provided id or <code>null</code> if this
* command does not have a parameter with the id.
* @throws NotDefinedException
* If the handle is not currently defined.
* @since 3.2
*/
public IParameter getParameter(final String parameterId) throws NotDefinedException {
if (!isDefined()) {
throw new NotDefinedException("Cannot get a parameter from an undefined command. " //$NON-NLS-1$
+ id);
}
if (parameters == null) {
return null;
}
for (final IParameter parameter : parameters) {
if (parameter.getId().equals(parameterId)) {
return parameter;
}
}
return null;
}
Returns the parameters for this command. This call triggers provides a
copy of the array, so excessive calls to this method should be avoided.
Throws: - NotDefinedException –
If the handle is not currently defined.
Returns: The parameters for this command. This value might be
null
, if the command has no parameters.
/**
* Returns the parameters for this command. This call triggers provides a
* copy of the array, so excessive calls to this method should be avoided.
*
* @return The parameters for this command. This value might be
* <code>null</code>, if the command has no parameters.
* @throws NotDefinedException
* If the handle is not currently defined.
*/
public IParameter[] getParameters() throws NotDefinedException {
if (!isDefined()) {
throw new NotDefinedException("Cannot get the parameters from an undefined command. " //$NON-NLS-1$
+ id);
}
if ((parameters == null) || (parameters.length == 0)) {
return null;
}
final IParameter[] returnValue = new IParameter[parameters.length];
System.arraycopy(parameters, 0, returnValue, 0, parameters.length);
return returnValue;
}
Returns the ParameterType
for the parameter with the provided id or null
if this command does not have a parameter type
with the id.
Params: - parameterId – The id of the parameter to retrieve the
ParameterType
of.
Throws: - NotDefinedException –
If the handle is not currently defined.
Returns: The ParameterType
for the parameter with the provided id or null
if this command does not have a parameter
type with the provided id. Since: 3.2
/**
* Returns the {@link ParameterType} for the parameter with the provided id
* or <code>null</code> if this command does not have a parameter type
* with the id.
*
* @param parameterId
* The id of the parameter to retrieve the {@link ParameterType}
* of.
* @return The {@link ParameterType} for the parameter with the provided id
* or <code>null</code> if this command does not have a parameter
* type with the provided id.
* @throws NotDefinedException
* If the handle is not currently defined.
* @since 3.2
*/
public ParameterType getParameterType(final String parameterId) throws NotDefinedException {
final IParameter parameter = getParameter(parameterId);
if (parameter instanceof ITypedParameter) {
final ITypedParameter parameterWithType = (ITypedParameter) parameter;
return parameterWithType.getParameterType();
}
return null;
}
Returns the ParameterType
for the return value of this command or null
if this command does not declare a return value
parameter type.
Throws: - NotDefinedException –
If the handle is not currently defined.
Returns: The ParameterType
for the return value of this command or null
if this command does not declare a return
value parameter type. Since: 3.2
/**
* Returns the {@link ParameterType} for the return value of this command or
* <code>null</code> if this command does not declare a return value
* parameter type.
*
* @return The {@link ParameterType} for the return value of this command or
* <code>null</code> if this command does not declare a return
* value parameter type.
* @throws NotDefinedException
* If the handle is not currently defined.
* @since 3.2
*/
public ParameterType getReturnType() throws NotDefinedException {
if (!isDefined()) {
throw new NotDefinedException("Cannot get the return type of an undefined command. " //$NON-NLS-1$
+ id);
}
return returnType;
}
Returns whether this command has a handler, and whether this handler is
also handled and enabled.
Returns: true
if the command is handled; false
otherwise.
/**
* Returns whether this command has a handler, and whether this handler is
* also handled and enabled.
*
* @return <code>true</code> if the command is handled; <code>false</code>
* otherwise.
*/
public boolean isEnabled() {
if (handler == null) {
return false;
}
try {
return handler.isEnabled();
} catch (Exception e) {
if (DEBUG_HANDLERS) {
// since this has the ability to generate megs of logs, only
// provide information if tracing
Tracing.printTrace("HANDLERS", "Handler " + handler + " for " //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ id + " threw unexpected exception"); //$NON-NLS-1$
e.printStackTrace(System.out);
}
}
return false;
}
Called be the framework to allow the handler to update its enabled state.
Params: - evaluationContext –
the state to evaluate against. May be
null
which indicates that the handler can query whatever model that
is necessary. This context must not be cached.
Since: 3.4
/**
* Called be the framework to allow the handler to update its enabled state.
*
* @param evaluationContext
* the state to evaluate against. May be <code>null</code>
* which indicates that the handler can query whatever model that
* is necessary. This context must not be cached.
* @since 3.4
*/
public void setEnabled(Object evaluationContext) {
if (handler instanceof IHandler2) {
((IHandler2) handler).setEnabled(evaluationContext);
}
}
Returns whether this command has a handler, and whether this handler is
also handled.
Returns: true
if the command is handled; false
otherwise.
/**
* Returns whether this command has a handler, and whether this handler is
* also handled.
*
* @return <code>true</code> if the command is handled; <code>false</code>
* otherwise.
*/
public boolean isHandled() {
if (handler == null) {
return false;
}
return handler.isHandled();
}
Removes a listener from this command.
Params: - commandListener –
The listener to be removed; must not be
null
.
/**
* Removes a listener from this command.
*
* @param commandListener
* The listener to be removed; must not be <code>null</code>.
*
*/
public void removeCommandListener(final ICommandListener commandListener) {
if (commandListener == null) {
throw new NullPointerException("Cannot remove a null command listener"); //$NON-NLS-1$
}
removeListenerObject(commandListener);
}
Removes a listener from this command.
Params: - executionListener –
The listener to be removed; must not be
null
.
/**
* Removes a listener from this command.
*
* @param executionListener
* The listener to be removed; must not be <code>null</code>.
*
*/
public void removeExecutionListener(final IExecutionListener executionListener) {
if (executionListener == null) {
throw new NullPointerException("Cannot remove a null execution listener"); //$NON-NLS-1$
}
if (executionListeners != null) {
executionListeners.remove(executionListener);
if (executionListeners.isEmpty()) {
executionListeners = null;
}
}
}
Removes a state from this command. This will remove the state from the active handler, if the active handler is an instance of IObjectWithState
.
Params: - stateId –
The identifier of the state to remove; must not be
null
.
Since: 3.2
/**
* <p>
* Removes a state from this command. This will remove the state from the
* active handler, if the active handler is an instance of
* {@link IObjectWithState}.
* </p>
*
* @param stateId
* The identifier of the state to remove; must not be
* <code>null</code>.
* @since 3.2
*/
@Override
public void removeState(final String stateId) {
if (handler instanceof IObjectWithState) {
((IObjectWithState) handler).removeState(stateId);
}
super.removeState(stateId);
}
Changes the handler for this command. This will remove all the state from
the currently active handler (if any), and add it to handler
.
If debugging is turned on, then this will also print information about
the change to System.out
.
Params: - handler –
The new handler; may be
null
if none.
Returns: true
if the handler changed; false
otherwise.
/**
* Changes the handler for this command. This will remove all the state from
* the currently active handler (if any), and add it to <code>handler</code>.
* If debugging is turned on, then this will also print information about
* the change to <code>System.out</code>.
*
* @param handler
* The new handler; may be <code>null</code> if none.
* @return <code>true</code> if the handler changed; <code>false</code>
* otherwise.
*/
public boolean setHandler(final IHandler handler) {
if (Objects.equals(handler, this.handler)) {
return false;
}
// Swap the state around.
final String[] stateIds = getStateIds();
if (stateIds != null) {
for (final String stateId : stateIds) {
if (this.handler instanceof IObjectWithState) {
((IObjectWithState) this.handler).removeState(stateId);
}
if (handler instanceof IObjectWithState) {
final State stateToAdd = getState(stateId);
((IObjectWithState) handler).addState(stateId, stateToAdd);
}
}
}
boolean enabled = isEnabled();
if (this.handler != null) {
this.handler.removeHandlerListener(getHandlerListener());
}
// Update the handler, and flush the string representation.
this.handler = handler;
if (this.handler != null) {
this.handler.addHandlerListener(getHandlerListener());
}
string = null;
// Debugging output
if ((DEBUG_HANDLERS) && ((DEBUG_HANDLERS_COMMAND_ID == null) || (DEBUG_HANDLERS_COMMAND_ID.equals(id)))) {
final StringBuilder buffer = new StringBuilder("Command('"); //$NON-NLS-1$
buffer.append(id);
buffer.append("') has changed to "); //$NON-NLS-1$
if (handler == null) {
buffer.append("no handler"); //$NON-NLS-1$
} else {
buffer.append('\'');
buffer.append(handler);
buffer.append("' as its handler"); //$NON-NLS-1$
}
Tracing.printTrace("HANDLERS", buffer.toString()); //$NON-NLS-1$
}
// Send notification
fireCommandChanged(new CommandEvent(this, false, false, false, true,
false, false, false, false, enabled != isEnabled()));
return true;
}
Returns: the handler listener
/**
* @return the handler listener
*/
private IHandlerListener getHandlerListener() {
if (handlerListener == null) {
handlerListener = (HandlerEvent handlerEvent) -> {
boolean enabledChanged = handlerEvent.isEnabledChanged();
boolean handledChanged = handlerEvent.isHandledChanged();
fireCommandChanged(new CommandEvent(Command.this, false,
false, false, handledChanged, false, false, false,
false, enabledChanged));
};
}
return handlerListener;
}
The string representation of this command -- 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 command -- for debugging purposes only.
* This string should not be shown to an end user.
*
* @return The string representation; never <code>null</code>.
*/
@Override
public String toString() {
if (string == null) {
String lineSeparator = System.lineSeparator();
StringBuilder builder = new StringBuilder();
builder.append("Command("); //$NON-NLS-1$
builder.append(id);
builder.append(',');
builder.append(name == null ? "" : name); //$NON-NLS-1$
builder.append(',');
builder.append(lineSeparator);
builder.append("\t\t"); //$NON-NLS-1$
builder.append(description == null ? "" : description); //$NON-NLS-1$
builder.append(',');
builder.append(lineSeparator);
builder.append("\t\t"); //$NON-NLS-1$
builder.append(category == null ? "" : category.toString()); //$NON-NLS-1$
builder.append(',');
builder.append(lineSeparator);
builder.append("\t\t"); //$NON-NLS-1$
builder.append(handler == null ? "" : handler.toString()); //$NON-NLS-1$
builder.append(',');
builder.append(lineSeparator);
builder.append("\t\t"); //$NON-NLS-1$
builder.append(parameters == null ? "" : Arrays.toString(parameters)); //$NON-NLS-1$
builder.append(',');
builder.append(returnType == null ? "" : returnType.toString()); //$NON-NLS-1$
builder.append(',');
builder.append("" + defined); //$NON-NLS-1$
builder.append(')');
string = builder.toString();
}
return string;
}
Makes this command become undefined. This has the side effect of changing
the name and description to null
. This also removes all
state and disposes of it. Notification is sent to all listeners.
/**
* Makes this command become undefined. This has the side effect of changing
* the name and description to <code>null</code>. This also removes all
* state and disposes of it. Notification is sent to all listeners.
*/
@Override
public void undefine() {
boolean enabledChanged = isEnabled();
string = null;
final boolean definedChanged = defined;
defined = false;
final boolean nameChanged = name != null;
name = null;
final boolean descriptionChanged = description != null;
description = null;
final boolean categoryChanged = category != null;
category = null;
final boolean parametersChanged = parameters != null;
parameters = null;
final boolean returnTypeChanged = returnType != null;
returnType = null;
final String[] stateIds = getStateIds();
if (stateIds != null) {
if (handler instanceof IObjectWithState) {
final IObjectWithState handlerWithState = (IObjectWithState) handler;
for (final String stateId : stateIds) {
handlerWithState.removeState(stateId);
final State state = getState(stateId);
removeState(stateId);
state.dispose();
}
} else {
for (final String stateId : stateIds) {
final State state = getState(stateId);
removeState(stateId);
state.dispose();
}
}
}
fireCommandChanged(new CommandEvent(this, categoryChanged,
definedChanged, descriptionChanged, false, nameChanged,
parametersChanged, returnTypeChanged, false, enabledChanged));
}
}