Class CommandHandler<M>
- java.lang.Object
-
- net.kautler.command.api.CommandHandler<M>
-
- Type Parameters:
M
- the class of the messages this command handler processes
public abstract class CommandHandler<M> extends Object
A base class for command handlers that does the common logic.Each method of this class starting with
do
, should usually be called by a subclass. Typically per each such method a subclass will have an according method that gets the needed arguments injected by the CDI framework. CDI cannot inject beans into methods that use wildcards (likeRestriction<? super M>
) but only into methods that define concrete type arguments (likeRestriction<? super Message>
). Due to this fact, this class cannot get the beans injected themselves, but has to rely on the subclass to get the beans injected and forward them to the superclass.If a subclass needs to do additional actions like registering message listeners on injected beans, this could for example be done in a method annotated with
@PostConstruct
.
-
-
Constructor Summary
Constructors Constructor Description CommandHandler()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected void
doHandleMessage(CommandContext<M> commandContext)
Handles the given command context.protected void
doSetAvailableRestrictions(Instance<Restriction<? super M>> availableRestrictions)
Sets the available restrictions for this command handler.protected void
doSetCommandContextTransformers(Instance<CommandContextTransformer<? super M>> commandContextTransformers)
Sets the command context transformers for this command handler.protected void
doSetCommands(Instance<Command<? super M>> commands)
Sets the commands for this command handler.protected void
executeAsync(CommandContext<M> commandContext, Runnable commandExecutor)
Executes the given command executor that is caused by the given message asynchronously.protected abstract void
fireCommandNotAllowedEvent(CommandContext<M> commandContext)
Fires a command not allowed CDI event asynchronously usingEvent.fireAsync(Object)
that can be handled using@ObservesAsync
.protected abstract void
fireCommandNotFoundEvent(CommandContext<M> commandContext)
Fires a command not found CDI event asynchronously usingEvent.fireAsync(Object)
that can be handled using@ObservesAsync
.abstract Map.Entry<Class<M>,TypeLiteral<ParameterConverter<? super M,?>>>
getParameterConverterTypeLiteralByMessageType()
Returns the map entry for mapping the message class to a parameter converter type literal.
-
-
-
Method Detail
-
doSetCommandContextTransformers
protected void doSetCommandContextTransformers(Instance<CommandContextTransformer<? super M>> commandContextTransformers)
Sets the command context transformers for this command handler.A subclass will typically have a method where it gets this injected, specific to the handled message type, and forwards its parameter as argument to this method like
Inject void setCommandContextTransformers(
@Any Instance<CommandContextTransformer<? super Message>> commandContextTransformers) { doSetCommandContextTransformers(commandContextTransformers); }
- Parameters:
commandContextTransformers
- the command context transformers for this command handler
-
doSetAvailableRestrictions
protected void doSetAvailableRestrictions(Instance<Restriction<? super M>> availableRestrictions)
Sets the available restrictions for this command handler.A subclass will typically have a method where it gets these injected, specific to the handled message type, and forwards its parameter as argument to this method like
Inject void setAvailableRestrictions(Instance<Restriction<? super Message>> availableRestrictions) { doSetAvailableRestrictions(availableRestrictions); }
- Parameters:
availableRestrictions
- the available restrictions for this command handler
-
doSetCommands
protected void doSetCommands(Instance<Command<? super M>> commands)
Sets the commands for this command handler.A subclass will typically have a method where it gets these injected, specific to the handled message type, and forwards its parameter as argument to this method like
Inject void setCommands(Instance<Command<? super Message>> commands) { doSetCommands(commands); }
- Parameters:
commands
- the available commands for this command handler
-
doHandleMessage
protected void doHandleMessage(CommandContext<M> commandContext)
Handles the given command context.- if the command is already set, fast forwards to command execution phase
- if not but the alias is already set, fast forwards to command computation phase
- if not but the prefix is already set, fast forwards to alias and parameter string computation phase
- if no fast forward was done, continues with prefix computation phase
These phases check the message content for a command invocation, check the configured restrictions for the command and if all passed, invoke the command synchronously or asynchronously as configured.
If the command was denied by any restriction, a command not allowed CDI event is fired asynchronously. (See for example
CommandNotAllowedEventJavacord
)If the message started with the command prefix, but no matching command was found, a command not found CDI event is fired asynchronously. (See for example
CommandNotFoundEventJavacord
)There are also multiple phases where
CommandContextTransformer
s are called that can influence the further command processing as well as skip phases or abort command processing with a command not found event being fired. The phases and their effect are described atCommandContextTransformer.Phase
.- Parameters:
commandContext
- the command context, usually populated with only message and message content, but not necessarily- See Also:
CommandContextTransformer.Phase
-
fireCommandNotAllowedEvent
protected abstract void fireCommandNotAllowedEvent(CommandContext<M> commandContext)
Fires a command not allowed CDI event asynchronously usingEvent.fireAsync(Object)
that can be handled using@ObservesAsync
.- Parameters:
commandContext
- the command context, usually fully populated but not necessarily- See Also:
@ObservesAsync
-
fireCommandNotFoundEvent
protected abstract void fireCommandNotFoundEvent(CommandContext<M> commandContext)
Fires a command not found CDI event asynchronously usingEvent.fireAsync(Object)
that can be handled using@ObservesAsync
.- Parameters:
commandContext
- the command context, usually populated according to current phase where the event was fired- See Also:
@ObservesAsync
-
executeAsync
protected void executeAsync(CommandContext<M> commandContext, Runnable commandExecutor)
Executes the given command executor that is caused by the given message asynchronously.The default implementation executes the command in a thread pool and logs any throwables on error level. A subclass that has some means to execute tasks asynchronously anyways like the thread pool provided by Javacord, can overwrite this message and replace the asynchronous execution implementation.
- Parameters:
commandContext
- the command context, usually fully populated but not necessarilycommandExecutor
- the executor that runs the actual command implementation
-
getParameterConverterTypeLiteralByMessageType
public abstract Map.Entry<Class<M>,TypeLiteral<ParameterConverter<? super M,?>>> getParameterConverterTypeLiteralByMessageType()
Returns the map entry for mapping the message class to a parameter converter type literal.- Returns:
- the map entry for mapping the message class to a parameter converter type literal
-
-