Documentation task Unable to locate Jira server for this macro. It may be due to Application Link configuration.

 

Goal

  • To define new (more logical?) structure of where commands are implemented and defined.
  • Allow easier use of commands by the App developers.
  • Remove command pooling.
  • Get rid of the Commons Chain library (see Greg's comment).

Further (future) goals:

  • Better documentation (list of commands with description, and for each command a list of parameters).

The Previous Status

The above class diagram represents the distribution of the command classes into the (basic) packages in the releases up to 4.5. 

Implementation

The command classes related to the activation (marked green on the above image) were moved to the Activation module (package i.m.module.activation.commands), the rest was moved to the Core module, to the i.m.commands.impl package.

The CommandsManager class was extended with a method executeCommand(String catalog, String command, Map<String,Object> parameters) , that allows to run commands without need to handle Context etc. The UI classes (actions etc.) should use command by calling this method (i.e. this will be the preferred method, but not the only one).

Command Definitions Reorganisation

The commands are still defined in particular modules, as described in http://documentation.magnolia-cms.com/technical-guide/commands.html - but the catalogs are now additive, i.e. it is possible to define a catalog in one module, and add a new command to the catalog in another module. Anyway, it is still forbidden to have two command of the same name in the catalog - if such situation happens, the CommandsManager will produce RuntimeException on its initialisation.

Besides the commands in independent modules (e.g. Data or Forum), there are following commands definitions in the (old) Admin Interface and DMS modules that requires to be moved:

Old pathNew pathNote
/modules/adminInterface/commands/default/activate/modules/activation/commands/default/activate  
/modules/adminInterface/commands/default/deactivate /modules/activation/ commands/default/deactivate  
/modules/adminInterface/commands/website/activate /modules/ui-pages-app/commands/website/activate Composite command, composed of 'version' and 'default-activate' command.
/modules/adminInterface/commands/website/delete /modules/ui-pages-app/commands/website/delete  
/modules/dms/commands/dms/activate /modules/dam-app-assets/commands/dms/activate Composite command, composed of 'version' and 'default-activate' command.
/modules/dms/commands/dms/delete /modules/dam-app-assets/commands/dms/delete  

Remove Command Pooling

The pooling capabilities were removed from the MgnlCommand base class, and the CommandsManager has been changed to create new instance for each getCommand() or executeCommand() call.

AbstractCommandAction

info.magnolia.ui.framework.action.AbstractCommandAction and its definition counterpart info.magnolia.ui.api.action.CommandActionDefinition allows for easy use of commands by the App developers by handling much of the boilerplate code they would otherwise need to write. 

TODO: Class info.magnolia.ui.framework.app.action.CommandActionBase is replaced by info.magnolia.ui.framework.action.AbstractActionBase. Unable to locate Jira server for this macro. It may be due to Application Link configuration.

In most cases it's just a matter of configuration. You define a marker interface extending CommandActionDefinition and bind AbstractCommandAction to it. The CommandActionDefinition needs to define at least the name of the command to execute, optionally it can define a catalog, otherwise it uses the default value, meaning that the command to be executed will be looked up in the registered default catalog of commands. Further parameters can be added in the param subfolder and/or my subclassing CommandActionDefinition as the example below illustrates

AbstractCommandAction provides a Map<String, Object> buildParams(final Node node) method which builds a map of parameters which will be passed to the current command for execution. It is called by the constructor.

Default implementation returns a map containing the parameters defined at CommandActionDefinition.getParams(). It also adds the following parameters with values retrieved from the passed node.

  • Context.ATTRIBUTE_REPOSITORY = current node's workspace name
  • Context.ATTRIBUTE_UUID = current node's identifier
  • Context.ATTRIBUTE_PATH = current node's path

Subclasses can override this method to add further parameters to the command execution. E.g. in the ActivationAction class

 protected Map<String, Object> buildParams(final Node node) {
     Map<String, Object> params = super.buildParams(node);
     params.put(Context.ATTRIBUTE_RECURSIVE, getDefinition().isRecursive());
     return params;
 }

1 Comment

  1. Please drop the usage of commons-chain ? We're using 1% of the actual library, abusing its pool mechanism (Philipp has been wanting to get rid of it for years), and most importantly (to my eyes), we completely revert the semantics of the Command.execute() method! (litterally, our wrapper does return \!result.