Friday 12 March 2010

Simplifying development of callouts

Callouts are a piece of client logic in Openbravo ERP designed to be executed whenever a field changes and as a result changes parts of a tab/window without the need of refreshing it.

The logic performed by a callout is executed by a java servlet and you can use SQLC or DAL to access data. After the code has been written you only have to associate the callout to the column or columns that trigger the callout, and recompile the windows where this callout is used.

The problem for developers is that callout servlets have a lot of boilerplate code that is very similar in all callouts. This code is not related to the callout logic and makes it dificult to understand and maintain callouts.

To help here there is a new java class has been introduced to simplify the code of callouts and keep focused only in the logic and not in the plumbing needed to make the callout servlet work. This class is SimpleCallout and to develop a new callout based on this class you only have to create a new java class that extends SimpleCallout and overwrite the following method:

protected void execute(CalloutInfo info) throws ServletException;

In this method you can develop the logic of the callout and use the info object of class CalloutInfo to access window fields, database and other methods. The most important are:
  • public String getStringParameter(String param) : This method returns the value of a field named param as an String.
  • public String getStringParameter(String param, RequestFilter filter) : Returns the value of a field named param as an String using the filter to accept values.
  • public BigDecimal getBigDecimalParameter(String param) throws ServletException : This method returns the value of of a field named param as a BigDecimal.
  • public void addResult(String param, String value) : This method sets the value of a field named param with the String value indicated.
  • public void addResult(String param, Object value) : This method sets the value of a field named param with the value indicated. This method is useful to set numbers like BigDecimal objects.
  • public void addSelect(String param) : Starts the inclusion of values of a field named param of type select.
  • public void addSelectResult(String name, String value) : Adds an entry to the select field and marks it as unselected.
  • public void addSelectResult(String name, String value, boolean selected) : Adds an entry to the select field.
  • public void endSelect() : Finish the inclusion of values to the select field.
  • public String getLastFieldChanged() : Returns the name of field that triggered the callout.
  • public String getTabId() : Returns the Tab Id that triggered the callout.
  • public String getWindowId() : Returns the Window Id that triggered the callout.
  • public VariablesSecureApp vars : This instance field contains the VariablesSecureApp associated to the callout servlet.
You can find an example of a class that currently uses SimpleCallout to implement the logic of a callout. The class is SL_Project_Service. This callout just takes the numeric value of two fields, calculate the sum and writes the result in other field. This is the interesting part of the code that performs the logic:

@Override
protected void execute(CalloutInfo info) throws ServletException {

BigDecimal serviceSerCost = info.getBigDecimalParameter("inpservsercost");
BigDecimal serviceOutCost = info.getBigDecimalParameter("inpservoutcost");

BigDecimal serviceTotalCost = serviceSerCost.add(serviceOutCost);

info.addResult("inpservcost", serviceTotalCost);
}

SimpleCallout is currently in the pi repository of Openbravo ERP, there has not been released any version with this class included. It is not also part of the Openbravo ERP public API and until it is not included here you cannot rely on it because could change without notice. If you find that this class is interesting to be included in the public API, let me know and I will push to include it and extend it with more new functionality and functionality from other Callout helper classes.

3 comments:

Fernando La Chica said...

Very interesting. Is great!

Zaien Aji Trahutomo said...

function public String getStringParameter(String param) doesn't appear

Adrián Romero said...

Hi Zaien

Yes, after some reviews with other members of the team now there only exists:

public String getStringParameter(String param, RequestFilter filter)

The reason is that we want to make the developer think always about the type of parameter he is getting and put the correct RequestFilter to avoid XSS attacks as much as possible.

In any case you can also pass "null" in the filter parameter that is exacty the same as the previous existing call.

public String getStringParameter(String param)

But I do not recommend id ;-)