Workflow Extension

A Workflow is a logical grouping of tasks, done in a set order to accomplish a specific goal. A Workflow is useful when multiple datasets are being processed the same way. The following section describes the key elements of a Workflow implementation.

A walkthrough is available to create a workflow.

ITaskFactory interface

ITASKFACTORY

public class MyTaskFactory implements ITaskFactory {
    public static final String ID = "MyTaskFactory";
 
    @Override
    public String getId() {
        return ID;
    }
 
    @Override
    public ITask createTask(String id) {
        return new MyTask(id);
    }
}

ITask interface

ITASK INTERFACE

import com.interactive.intviewerapi.plugins.workflow.AbstractTask;
public class MyTask extends AbstractTask {
 
    public MyTask(String id) {
        setId(id);
        setName("My Task"); // Name that is displayed in workflow tree
        setStatus(Status.Enabled); // Default value of status, may be set to Status.Disabled
    }
 
    @Override
    /** The "worker" method for ITask is the runTaskmethod.
     **
     */
    public void runTask() {
        // perform my task action
        doSomething();
    }
}

Register new factory

Register your new task factory in the META-INF.services folder by creating a new file with the name com.interactive.intviewerapi.plugins.workflow.ITaskFactory

In this file add one line for each task factory you have created. In the example, one line would be added:

com.interactive.intviewer.examples.tasks.factories.MyTaskFactory

GUI Integration with INTViewer

The INTViewer uses a workflow configuration file to build and manage a workflow. Create a new WorkflowTasks.xml to describe your workflow.

In the example below the tasklist node denotes groupings within a workflow. For example, a workflow may have several data loading tasks, followed by data processing tasks, followed by data saving tasks. There would be 3 tasklist nodes where the name attribute describes each of the groupings.

TASKLIST NODE

<workflow>
    <tasklist name="Load">
    ...
    </tasklist>
    <tasklist name="Process">
    ...
    </tasklist>
    <tasklist name="Save">
    ...
    </tasklist>
</workflow

In the next example, the task node describes each task within a workflow. There are 4 attributes used to describe each task.

  • factory - the factory class written for the task
  • tooltip - the text to display in a tool tip. The text displays in the Workflow window when the cursor lingers over this task link.

Changing the status of a task

To change the status of a task, call:

Status status = Status.Enabled // or Status.Disabled
setStatus(status);

You then need to notify any listeners that the status of a task has changed.

To do this, call:

fireListener(this);

The workflow tree, which needs to be notified when the status is changed, is added as a listener when the task is added to the workflow. Calling the fireListener method will notify the workflow tree.

Typically, the status will change due to whether a data type become available or not available. This will

be usually be determined by listening to a lookup event. Here is a simple implementation:

STATUS CHANGE EXAMPLE

   import com.interactive.intviewerapi.GlobalSelection;
import com.interactive.intviewerapi.plugins.workflow.AbstractTask;
import org.openide.util.LookupEvent;
public class MyTask extends AbstractTask implements LookupListener {
    private GlobalSelection<SomeClass> theSelection = new GlobalSelection<SomeClass>(SomeClass.class);
 
    public MyTask(String id) {
        setId(id);
        setName("My Task"); // Name that is displayed in workflow tree
        setStatus(Status.Enabled); // Default value of status, may be set to Status.Disabled
        theSelection.addLookupListener(this);
    }
    @Override
    public void resultChanged(LookupEvent arg0) {
        Status currentStatus = getStatus();
        Status newStatus;
        Collection<? extends SomeClass> selectionInstances = theSelection.allInstances();
        if (selectionInstances.isEmpty) {
            newStatus = Status.Disabled;
        } else {
            newStatus = Status.Enabled;
        }
        if (newStatus != currentStatus) {
            setStatus(newStatus);
            fireListener(this);
        }
    }
}

The example shows the basic implementation needed by a task to report status back to the Workflow manager.

The tasks that are available, or enabled, are marked with a green icon. Tasks that are not available, or disabled, are marked with a red icon. Use GlobalSelection if you need to keep track of state of the tasks in a workflow.

Two options to open workflow top components are available.