Thursday, May 29, 2014

Liferay Model Listeners

Introduction:

Liferay Model Listeners are event listeners which will be invoked when the changes made in Model Object.

Each model object can have its own model listener to listen changes in the model objects.

As for ORM concept any database interaction is mapped to java POJO object that is we can call it as Model Object.

Before perform any database interaction first we create or modify the model object then data will be stored or update in the tables.

In the ORM concept each table row we can treat as Model Object Instance that is called persistence object.

We can create our custom model listeners to existed models which are in portal through Hook Plugin.

We have different model classes in portal like User, Role, Group, Layout, Address, and Contact.

Apart from these we can also implement it for portlet level model class like DLFileEntry, JournalArticle and AssetEntry.

Note:

Before going implement model listener for any Model which are in portal or portlet level Please check in liferay if they are already existed or not. This you can search in portal.properties file the property prefix is value.object.listener.

If already there make sure keep existed business logic same and add your logic after that or create another model listener class and configure it with comma separate value for above property.

Example Properties for Model Listeners portal.properties


Pattern:

value.object.listeners.ActualModel Class Name=Our Custom Listener class Name


Model Listener to existed model objects which are in Portal level


value.object.listener.com.liferay.portal.model.Contact=
com.liferay.portal.model.ContactListener

value.object.listener.com.liferay.portal.model.Layout=
com.liferay.portal.model.LayoutListener,
com.liferay.portal.service.impl.LayoutSetPrototypeLayoutListener

value.object.listener.com.liferay.portal.model.LayoutSet=
com.liferay.portal.model.LayoutSetListener,
com.liferay.portal.service.impl.LayoutSetPrototypeLayoutSetListener

value.object.listener.com.liferay.portal.model.PortletPreferences=
com.liferay.portal.model.PortletPreferencesListener

value.object.listener.com.liferay.portal.model.User=
com.liferay.portal.model.UserListener

value.object.listener.com.liferay.portal.model.UserGroup=
com.liferay.portal.model.UserGroupListener


Note:

The above already existed in portal.properties file

Create Custom Model Listener to existed model object which are in portlet level.


value.object.listener.com.liferay.portal.model.Address=
com.meera.model.listeners.AddressListener

value.object.listener.com.liferay.portal.model.Contact=
com.meera.model.listeners.ContactListener

value.object.listener.com.liferay.portlet.documentlibrary.model.DLFileEntry=
com.meera.model.listeners.DLFileEntryListener


Note:

The overriding of portal properties can be done through Hook and we can use hook for existed models which are in liferay portal level and portlet related models.

So if want know changes in the above models we need create Model Listener and we can write some business logic to know all the changes made in model like ADD, DELETE and UPDATE.

Any Model Listener that should implement the ModelListener interface and it has some 
abstracted methods and we need to implement it.

The following are available methods in ModelListener interface


public interface ModelListener<T> {

public void onAfterAddAssociation(
Object classPK, String associationClassName,
Object associationClassPK)
throws ModelListenerException;

public void onAfterCreate(T model) throws ModelListenerException;

public void onAfterRemove(T model) throws ModelListenerException;

public void onAfterRemoveAssociation(
Object classPK, String associationClassName,
Object associationClassPK)
throws ModelListenerException;

public void onAfterUpdate(T model) throws ModelListenerException;

public void onBeforeAddAssociation(
Object classPK, String associationClassName,
Object associationClassPK)
throws ModelListenerException;

public void onBeforeCreate(T model) throws ModelListenerException;

public void onBeforeRemove(T model) throws ModelListenerException;

public void onBeforeRemoveAssociation(
Object classPK, String associationClassName,
Object associationClassPK)
throws ModelListenerException;

public void onBeforeUpdate(T model) throws ModelListenerException;

}


We have different named methods and these will be invoked based on action performed in Model Object.

Like if any data added in table respective model listener onAfterCreate(--) method will be invoked.

Similarly we have many methods based on action or change respective methods will be invokes on behalf of Model object.

Real time scenarios:

If any record add or delete for table based on this some tome we may need to delete or add other records such scenarios we can use model listeners.

To know more you can see source code in UserListener then we can understand importance of model listener.

If we want to track information in application then we will use Model Listeners for example if we want track document library information then we will create Model Listener for DLFileEntery then we can track all information with respect to Document Library.

We have two types of implementation
  1. Implement Model Listener for Existed Models
  2. Implement Model Listener for Plugin Portlet Models

Implement Model Listener for Existed Models

We will use hook to existed model which are in Portal Level or Portal Portlets Level.

Portal Level Models Examples:


Role, Group, Layout and Layoutset


Portlet Level Models Examples


DLFileEntry, Journal Articlle and AssetEntry


Steps: 1

Create Hook for Portal Properties

Step: 2

Add your Model Listener Implementation class name for your existed Model in hook portal properties file.

Step: 3

Implement Model Listener interface Methods in Model Listener Implementation class.

Note:

Model Listener should be thread safe that is why we have to implemented Message Bus concept to make it thread safe when concurrent actions performed in the model.

Message Bus:

Message bus is one of the concepts in liferay so that we can create some destinations and its respective listeners to send the information and perform further actions through its respective listeners.

Whenever any event is generated we will post information to configured destinations as soon as information posted in destination respective liters will be listening and will perform further activities.


Note:

service.properties file will be created after run the service-builder for the portlet.

One more important thing is when we re-run service builder then service.propertis file overridden with default properties file and make sure the property spring.config should have messaging-spring.xml path.

When you run service builder again need to add above file path in list of to spring-config property.

Assume we want Track Document Library Information

Create brand new liferay hook project for portal properties file.

Add following code in liferay-hook.xml file (/WEB-INF/liferay-hook.xml)

<hook>
       <portal-properties>portal.properties</portal-properties>
</hook>

Add following property in hook portal.properties file (/WEB-INF/src/portal.properties)


value.object.listener.com.liferay.portlet.documentlibrary.model.DLFileEntry=
com.meera.model.listeners.DLFileEntryListener


Implement Model Listener for DLFileEntry

We already know we need to implement all the methods which are present in the ModelListener interface and we need to implement in our Custom Model Listener class

Example Model Listener class as follows


package com.meera.model.listeners;
import com.liferay.portal.ModelListenerException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.model.BaseModelListener;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;

public class DLFileEntryListener extends BaseModelListener<DLFileEntry> {
public void onBeforeCreate(DLFileEntry dlFileEntry) throws ModelListenerException {

_log.info("This method will be called before create document");

}

public void onBeforeRemove(DLFileEntry dlFileEntry) throws ModelListenerException {
_log.info("This method will be called before DELETE document");
}

public void onBeforeUpdate(DLFileEntry newDLFileEntry) throws ModelListenerException {
_log.info("This method will be called before UPDATE document");

}

private static Log _log =LogFactoryUtil.getLog(DLFileEntryListener.class);
}


Note:

When you use Document Library portlet then these methods will be called and you can information in log file or server console.

Implement Model Listener for Plugin Portlet Models

When we work with Plugin portlet some time we need create our own enmities in Plugin portlet and we may have our own model classes.

Whenever we want create model listener in Plugin portlet we will use service.properties file to configure our custom model listener on behalf of our model class.

Assume we have Student MVC Portlet and have Student Entity

Steps:

Create Liferay MVC Portlet

Create service builder and define your entity in service.xml

Run service builder then all service layer classes and its configuration files will be created.

In the service.properties file configure our custom model listener on behalf of our model class


com.meera.dbservice.model.StudentModel=
com.meera.model.listeners.StudentModelListener


Implement our model listener and that should implement the Model Listener interface

Example


package com.meera.model.listeners;
import com.liferay.portal.ModelListenerException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.model.BaseModelListener;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;
public class StudentModelListener extends BaseModelListener<DLFileEntry> {
public void onBeforeCreate(DLFileEntry dlFileEntry) throws ModelListenerException {

_log.info("This method will be called before create Student");

}

public void onBeforeRemove(DLFileEntry dlFileEntry) throws ModelListenerException {
_log.info("This method will be called before DELETE Student");
}

public void onBeforeUpdate(DLFileEntry newDLFileEntry) throws ModelListenerException {
_log.info("This method will be called before UPDATE Student");

}

private static Log _log =LogFactoryUtil.getLog(DLFileEntryListener.class);
}


Portlet Development using Model Listeners

Assume we will find the information which is going on Document Library Portlet.

We need to implement model listener for DLFileEntry Model so that we can track all information.

Download Liferay Model Listener Example Portlet

https://sourceforge.net/projects/meeralferay/files/LiferayModelListenerPortlet/


Environment:


Liferay IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal Bundle

Important Points

We have implemented DLFileEntry Model Leister to find information in Document Library Model class.

We have created Hook for the portlet and we configured model listener information in Hook portal.properties file.

For the storing information we have defined one entity in service.xml file

Once we run service builder to portlet then we will get required configuration files and java classes to perform CRUD operation on table.

We have used Message Bus destinations and it Listeners to post data and store the data in the table.

We have configured destinations and its listeners in messaging-spring.xml file which in /WEB-INF/src/META-INF/ directory.

We need to specify the messafing-config.xml file information in service.properties file which is in /WEB-INF/src/service.properties

service.properties file will be created after run the service builder and when we’re run service builder it will be revert back it default configuration so make sure for each re run service 
builder again add messaging-spring.xml information in service.propertires file.

Deployment and its Working.

Download portlet you can source or war file to deploy into liferay portal as your convenient.
Once portlet successfully deployed drag the portlet in any desired page. Portlet is available in sample category.

Now login as admin go to Document Library portlet add some documents and Update the documents.

Now come to our portlet and click on Document Library Records and you can see all information.

Similarly in the portlet we have document download page you can download any document again see the Document Library Records page you can see downloaded information.

Portlet Screens:

Default Page


Document download screen



Document Library Information Screen



Reference Links




Author

Popular Posts

Recent Posts

Recent Posts Widget