Creating your own Actions - Creating an Action

As you can see, Action(s) is a powerful and flexible tool for users of all experience levels. If you are an application developer, it should be clear that letting users access the functionality of your application from Action(s) will enhance its value to them. Providing actions is a powerful additional path to the features and services that make your products unique.

Actions are easy to create. A public API is available for creating Java based actions. With this API, you can create actions, variables and loadable bundles (called collections) that Action(s) uses.

There are three general types of actions that you can create:
  • Actions that control an application to get something done.
  • Actions that use system frameworks or other system resources to get something done.
  • Actions that perform a "bridge" function, such as prompting the user for input, writing output to disk, or converting data from one type to another.

The public API provides abstract classes that you can easily implement to quickly develop your own actions. Those classes are available in the com.jbbres.lib.actions.tools.elements package of the Action(s) API.

To illustrate this article, we will create an action that, once placed in a workflow, returns the path of the file it receives from the previous action. You can download the code of this example here.

You’ll become more familiar with many of the files that will constitute your action in the sections that follow. But here is a summary of the more significant items:
  • getFileName.properties: The information property list includes the action description.

Creating the Project

Depending on the EDI you are using for developing in Java, the process to create a new project might be different. Refer to your EDI documentation for more information on how to create a project.

You might need to include the Action(s) API as a known library of your tool in order to be able to develop and compile your action. You can download this API at http://app.jbbres.com/actions/developers/.

Creating the Action Class

The com.jbbres.lib.actions.tools.elements.SimpleAction class is a very basic implementation of the action class. It does most of the work for you as most of the functions and methods that this class should contain are pre-defined by this abstract class.

SimpleAction is a parameterized abstract class with two type-variables, which means that all implementation of this class requires two type-arguments:
  1. The first argument represents the type of object that the action accepts as an input.
  2. The second argument is the type of object that the action generates as a result.

If an action does not have to deal with the input data handed it – for example, its role is to select some items in the file system – the first parameterized argument should be java.lang.Void. On the opposite, if the action is able to handle any type of input data, the first parameterized argument will be java.lang.Object.

These conventions also apply to the result data type too. A second parameterized argument sets to Void means that the action is not expected returning a result. Object informs that the result of the action can be any type of object.

A particular case in action is a service not receiving input nor generating result. Following the convention, such a service should extend SimpleAction<Void, Void>. Action(s) will recognize this specific case and will route the flow of data around the action.

In our example, we expect to receive a file and return a text. However, most of the actions return and receive arrays, so we know that we are most likely to receive an array of files (File[]) instead of a single file. Having say that, your action will have, for each item in the array, to return its path, so the result will be an array of text (String[]).

Furthermore, if the action preceding ours in the workflow does not return an array of files but a single file, Action(s) will automatically transform the result into an array (with a single item) so we do not have to worry about the different type of data we might have to deal with.

public class GetFileName 
extends SimpleAction {

/**
* Instantiates a new action.
*/
public GetFileName(Workflow workflow) {
super(workflow);
}
}

Constructing the User Interface

The user interface of your action is displayed in the workflow definition panel in Action(s). The user can use it to define the settings of the action.
The user interface must be provided by the getUI() method in the action class.

In our example, the UI will provide a combo box allowing the user to choose if he wants the action to return the full path of the files that the action received, or only their file names:

JPanel uiPanel = new JPanel();
JLabel resultLabel = new JLabel("Result:");
String[] pathTypes =
{"Full path", "File name only"};
JComboBox pathTypeComboBox =
new JComboBox(pathTypes);

/**
* Instantiates a new action.
*/
public GetFileName(Workflow workflow) {
super(workflow);
uiPanel.add(resultLabel);
uiPanel.add(pathTypeComboBox);
}

/**
* The action UI.
*/
public Component getUI() {
return uiPanel;
}

The User Interface can be created using AWT, Swing or any other compatible toolkit.

Implementing the execute method

The most important step in creating an action is writing the execute method that implements the logic for your action.

The execute method has a single argument, input. It contains (in most instances) the output of the previous action in the workflow; it is almost always in the form of a list. The type of input is the first parameterized argument of the action class (in our example, a File[]). Remember that if the previous action result is not compatible, or if this action is the first one in the workflow, the input parameter will be null. Make sure that you handle this case properly to avoid a NullPointerException.

The method finally returns an output, which should be an object compatible with the second parameterized argument of the action class (in our example, a String[]). The method should always return an output, even if it is null or the input object.

If your action service encounters an error that prevents it from proceeding, it should give information describing the error to Action(s), which then stops executing the workflow and displays an error message. To report errors, you must throw an ActionExecutionException exception.
public String[] execute(File[] input) 
throws ActionExecutionException {
if (input == null)
return null;

String[] result = new String[input.length];

for (int i = 0; i < input.length; i++){
if (pathTypeComboBox.getSelectedItem()
.equals("Full path")){
result[i] = input[i].getPath();
} else {
result[i] = input[i].getName();
}
}
return result;
}


Saving and Restoring User Settings

The getParameters() and setParameters(Parameters) methods generate and set the parameters associated to the User Interface. The Parameters object that the getParameters() method returns is used by Action(s) to store the state of the action within the .wkfl file when the user saves the workflow. The same object is given to the setParameters(Parameters) method when the user opens a .wkfl file, so the User Interface can be reconstructed at a similar state as it was when the workflow had been saved.

In our example, the getParameters() method must store in a Parameters object the value selected by the user in the UI combo box, and the setParameters(Parameters) method should restore the combo box state based on the value stored in the Parameters object it received as an argument.
/**
* Returns the action settings as
* a Parameter object.
*/
public Parameters getParameters() {
Parameters parameters = new Parameters();
parameters.setParameter("result.path.type",
(String)pathTypeComboBox.getSelectedItem());
return parameters;
}

/**
* Sets the action settings from a
* Parameters object.
*/
public void setParameters(Parameters parameters)
throws InvalidParametersException {
String pathType =
parameters.getParameter("result.path.type");
pathTypeComboBox.setSelectedItem(pathType);
}


Specifying Action Properties

The Action(s) application uses special properties in an element information property list to get various pieces of information it needs for presenting and handling the action. This information includes:
  • The name of the action
  • The icon for the action
  • The category for the action
  • The description of types of data the action accepts and the types of data it provides
  • The description of the action

A properties file is a simple text file. You can create and maintain a properties file with just about any text editor.

The name of this file begins with the base name of your action, but start with a lower case, and ends with the .properties suffix. In our example the action class base name is GetFileName, therefore the properties file is called getFileName.properties. This file contains the following lines:
type=action
description.title=Get File Name
description.summary=This action returns the path or \
the name of files passed into it.
description.categories=#FilesCategory
description.input=Files/Folders
description.output=Files/Folders


Those properties are used by Action(s) to displays the description in its lower-left view whenever the user selects the action. The description briefly describes what the action does and tells users anything else they should know about the action.

A description has several parts:
  • type: the type of element that the properties file defines. For an action, the value of this property must always be action.
  • description.icon: a 32 x 32 pixel image displayed in the upper-left corner of the description. In the properties file you should provide the relative path of the image within the package. Accepted formats are PNG, JPEG, GIF and BMP.
  • description.title: the name of the action.
  • description.summary: a sentence or two directly under the title that succinctly states what the action does.
  • description.input and description.output: states respectively the type of data that the action accepts as an input and the type of data that the action produce as a result.
A description’s title, summary, input and ouput are required or strongly recommended.

> Next section: Deploying Actions