Using Business Event Handlers in Openbravo

All current technologies supports multiple layers in the Application thereby enabling us the advantage and flexibility to separate the Application layer from the Business Layer and similarly separating the Business layer from the Database Layer. Openbravo is built on a MVC Architecture that enables us to separate the data layer, the logic layer and the application layer. But do we use it to the fullest extent? In most of the current solutions, the business logic is done database dependently in Triggers and Procedures. Openbravo has provided an efficient alternate to remove this database dependency.

Business event handler is an efficient alternative to database triggers.Since the business event handlers are written using DAL, it has all the advantages of using DAL and also it becomes database independent. The business event handler gets triggered whenever save, update and delete operations are performed. The event gets triggered even before the object gets into the database because of which the changes will be committed as a single transaction with all our business logics. The DAL layer uses clean and readable coding which can be used in business event handler. The business event handler uses Weld framework which will automatically detect the all the business event handlers through the using the annotation. This makes very easy for the developers to create the business event handler in a few minutes. Its enough if we just create a DAL file which extends the class EntityPersistenceEventObserver.

package org.openbravo.erpCommon.businessHandler;
import javax.enterprise.event.Observes;
import org.apache.log4j.Logger;
import org.openbravo.base.model.Entity;
import org.openbravo.base.model.ModelProvider;
import org.openbravo.base.model.Property;
import org.openbravo.model.common.businesspartner.BusinessPartner;
import org.openbravo.client.kernel.event.EntityDeleteEvent;
import org.openbravo.client.kernel.event.EntityNewEvent;
import org.openbravo.client.kernel.event.EntityPersistenceEventObserver;
import org.openbravo.client.kernel.event.EntityUpdateEvent;
/**
* Listens to events on the {@link BusinessPartnerHandler} entity.
*
* @author Pandeeswari
*/
public class BusinessPartnerHandler extends EntityPersistenceEventObserver {
private static Entity[] entities = { ModelProvider.getInstance().getEntity(BusinessPartnerHandler.ENTITY_NAME) };
private static Logger log = Logger.getLogger(BusinessPartnerHandler.class);
@Override
protected Entity[] getObservedEntities() {
return entities;
}
public void onUpdate(@Observes
EntityUpdateEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
public void onSave(@Observes
EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
public void onDelete(@Observes
EntityDeleteEvent event) {
if (!isValidEvent(event)) {
return;
}
}
}

The above program appends the searchkey and name of the business partner and updates in the name2 field in business partner whenever the value is inserted or updated. Whenever an action is performed, the getObservedEntities() Method will be called which will return the array of entities that are being observed. In short, it will give the array of entities that has business event handlers. This entity array is used to check if a certain event is targeted for this observer. Say if an entity is being updated. The getObservedEntities() method will give all the observed entities and the method isValidEvent will check whether the entity is an observed entity. If the target entity exists in the list of observed entity, then it will return true. Also the event is automatically captured by @Observes and routed correspondingly to any of the methods onUpdate, onSave, onDelete.

The old and new values of a field can be accessed using OLD and NEW Identifier in database triggers. This can be done in business event handlers using the methods, getPreviousState and getCurrentState method. The method getCurrentState will be available in all the 3 classes EntityUpdateEvent, EntityNewEvent and EntityDeleteEvent whereas the getPreviousState method will be available only in EntityUpdateEvent class. This makes sense because we can get the previous state(old values) only when the record is being updated. Similarly, we can set a new value to a property(field) using the method setCurrentState which will be available in all the 3 classes. Though it is available in all the 3 classes, it is applicable only for new and update event.

final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
Object previousName = event.getPreviousState(name2Property);
Object currentName = event.getCurrentState(name2Property);

When we want to interrupt certain event, we can throw an exception as we raise exception in database triggers. It can be done as follows,

public void onSave(@Observes EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
if(searchKey != null && name != null) {
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
else {
String language = OBContext.getOBContext().getLanguage().getLanguage();
ConnectionProvider conn = new DalConnectionProvider(false);
throw new OBException(Utility.messageBD(conn, "C_NullValue", language));
}
}

Leave in your comments about your views on implementing business logics at the database level or at the DAL layer.

Advertisements

About Pandeeswari Ramakrishnan
Applications Engineer, Openbravo

2 Responses to Using Business Event Handlers in Openbravo

  1. venkata reddy dwarampudi says:

    Hi Pandeeswari Ramakrishnan,
    I have gone through the tutorial on the event handlers. I am look forward that how message type set to the UI using the Event handlers.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: