Skip to content

UI Command Pattern

Bill Majurski edited this page Aug 11, 2016 · 3 revisions

I have introduced the Command Pattern into the interface between the GWT UI and the server. This offers several benefits:

  • Requests can include values that keep the UI and the server in sync. The key values are current environment selection and current test session. When the user is not focused on the toolkit UI the web session with the server can timeout. The server looses context but the UI does not know this. The next request made to server assumes an intact session. The typical error message to see is Environment Not Selected. This is very confusing since the UI still displays the correct value but the server has "forgotten" the value. Using the command pattern, these values are included in every request to the server.

  • Centralized error handling - each server call coded in a tool has its own error handling. This makes it very hard to have a consistent UI style.

In this interface style, each call to the server has one parameter and one return value. The single call parameter is a class with base class CommandModule where C is an instance of ToolWindow. This class intercepts the normal GWT onFailure and onSuccess callbacks and replaces them with its own onFailure and onComplete. Every use of a command must supply the onComplete method to capture the response message. OnFailure defaults to a common error handler but can be overridden by the user.

The command request message is formed by the interface CommandRequest<R, T> where R is the object type of the request and T is the object type of the callback.

An example command is:

abstract public class SendPidToRegistryCommand  extends GenericCommand<SendPidToRegistryRequest, List<Result>> {
    public SendPidToRegistryCommand(ToolWindow toolWindow) {
        super(toolWindow);
    }

    @Override
    public void run(SendPidToRegistryRequest var1) {
        toolkitService.sendPidToRegistry(var1, this);
    }
}

which sends a newly create Patient ID to the Patient ID Feed port of a Document Registry. This is an abstract class because the user must supply the onComplete method to accept the results of the command. The invocation looks like:

new SendPidToRegistryCommand(this) {
    @Override
    public void onComplete(List<Result> var1) {
        queryCallback.onSuccess(var1);
    }
}.run(new SendPidToRegistryRequest(getCommandContext(), getSiteSelection(), pid));

The command is the class SendPidToRegistryCommand. All commands are built as classes ending in Command. The this reference is the tab class (extends ToolWindow). The onComplete captures the response. The single parameter to onComplete is the return value of the server call.

The run method takes a single request object which contains all parameterization of the call. The constructor for all Request objects has as its first parameter a CommandContext object which is common to all server calls. It is retrieved by the getCommandContext() call. The rest of the parameters to SendPidtoRegistryRequest (and all other request builders) are dependent on the needs of the call. Note that every command has a custom request builder such as this.

Clone this wiki locally