Tuesday, April 27, 2010

Command Pattern implementation

Our Clinical applications have HIPAA requirements that require a user to be logged out if there is no activity for a specified number of minutes. It is also common in our applications that Users do partial data entry and attend to Patients. If the session were to be "logged out" we want to preserve the data that was entered by the user so far and "requeue" the request once the User "re-logs" in. We implemented the command pattern described by Ryan so we can do the "requeuing" of requests on session timeouts/logout. Our goal was also to keep the Server implementation standard and also retain the strong typing provided by standard GWT RPC interfaces.

Defined an abstract class Action as
public abstract class Action<T> implements AsyncCallback<T> {
protected AsyncCallback<T> _callback;
protected Action() {}
protected void setCallback(AsyncCallback<T> callback) {
_callback = callback;
}
public void onSuccess(T result) {
_callback.onSuccess(result);
}
public void onFailure(Throwable t) {
_callback.onFailure(t);
}
public abstract void execute();

...
}
We wrote a simple Code Generator which took as argument an RemoteService interface and generated an Async Interface and an "Action" class for each method in the interface.
For Example if the following interface name was passed to the code generator
interface PatientCondition extends RemoteService {
void addConditions(int accountID, ArrayList<conditioninfo> list);
PatientConditionInfo get(int accountID, int PatientConditionID);
...
}
the code generator would use Java Reflection to generate the Async interface
interface PatientConditionAsync {
void addConditions(int p0, ArrayList<conditioninfo> p1, AsyncCallback<Void> ret);
void get(int p0, int p1, AsyncCallback<PatientConditionInfo> ret);
..
}
and a class for method addConditions
PatientCondition_addConditions extends Action<void> {
private PatientConditionsAsync _svc;
private java.util.ArrayList _p0;

public PatientCondition_addConditions(PatientConditionsAync svc){
_svc = svc;
}
public void initialize(java.util.ArrayList p0, AsyncCallback<void> callback){
_p0 = p0;
setCallback(callback);
}
public void execute() {
_svc.addConditions(_p0, this);
}
..
}
and another class for method get
PatientCondition_get extends Action<patientconditioninfo> {
...
}
The code generator is essentially generating "wrapper" classes for each method and caching the arguments and callback so it can "re-execute" the call if needed. In the next post I will describe how the Action classes interact with Security.

No comments:

Post a Comment