Wednesday, January 22, 2014

Liferay Service Builder Tags Detail Part-1

Objective:

Provide detailed information about service builder root level tags and usage.

Liferay service builder is tool to generate service layer to Plugin portlets. With minimal effort developer can develop service layer to portlet.

Liferay service builder generate many java service classes and Util classes from these classes we can do most of the curd operations.

How we will use service builder in Liferay Portlets?
  • To use service builder tool in portlet we need to define service.xml file in portlet WEB-INF directory.
  • Service builder will use certain predefined tags so that we have to define those tags in service.xml file
  • All tags information will be available in liferay-service-builde_X_x.dtd file. Liferay have different versions of DTD files.
  • Once we define everything in service.xml we need run ant build-service target form eclipse or command prompt
  • Once we run ant target then all required service classes will be generated so that we can use these classes in portlet.

Assumption:

Assume we want create service builder to Student Entity so that we will generate many service classes and Util classes which will use to interact with data Student tables in data base

Example for define Entity in service.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.sb">
<author>E5410</author>
<namespace>SB</namespace>
<entity name="Student" local-service="true" remote-service="true" >
<!—Define columns tags -->
<!—Define finder tags -->
<!—Definde order tags -->
</service-builder>

Note:

Whenever we use service builder we need to specify the service builder DTD file in DOCTYPE tag so that it will use the tags those defined in dtd file. This is very important when we use service builder tool.

The following are service builder tags and its attribute details

Service builder have following important root level tags

service-builder
author
namespace
entity
service-builder-import

service-builder

The parent tag in service.xml file is service-builder all tags which are related to service builder should enclosed by parent tag.

Attributes for service-builder tag:

packeage-path:  

This is specifying that where all service builder generated classes will be placed in given package path

Example:

<service-builder package-path="com.meera.sb">
<!—Define Enities tags -->
</service-builder>

In above all service builder generated classes will be places in com.meera.sb base package.

author

This specify the author who is developing this service builder

namespace

Name space tag will used to avoid the name collegians between data base tables.
Assume some time we may have scenario tow portlet have same table name but columns are different.

If we don’t want use name space then existed tables override by another portlet table columns.

To avoid this we will use name space so that we can use same table in many portlets so that table name will be appended with name space

Example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.sb">
<author>E5410</author>
<namespace>SB</namespace>
<entity name="Student" local-service="true" remote-service="true" >
<!—Define columns tags -->
<!—Define finder tags -->
<!—Definde order tags -->
</service-builder>

Database Table Name= Name Space Tag Value + Entity Name
For above definition the Table Name will be SB_Student

Note:

To avoid Name space append to entity name we need to use table attribute in

enitity

Entity tag used to define the service layer entity class.  For each physical table we need entity definition in service.xml so that we can do data base operation on that table.
All entities are enclosed by <service-builder/> parent tag

Example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.sb">
<author>E5410</author>
<namespace>SB</namespace>
<entity>
-----
-----
</entity>
<entity>
-----
-----
</entity>

<entity>
-----
-----
</entity>
</service-builder>

Important Attributes for entity tag:


name             
table
local-service
remote-service
data-source
session-factory
tx-manager
cache-enabled
json-enabled


Name:

This specifies the name of the entity so that all service classes and model classes’ names will start with entity name.

Possible attribute values:

 Any String Value we can use as value better don’t use some special characters

Note:

This is mandatory attribute

Example:


<entity name="Student">
----
-----
</entity>


table:

This specifies the name of the table in data base. Means the service layer service will do data base operations for given table.

Possible attribute values:

This is name of table in data base nothing but string value

Note:

This is optional attribute

Example:


<entity table="Student">
----
-----
</entity>


Assume already table is existed in data bases for this we want use the service builder service then we have to table attribute in entity tag.

local-service:

This is Boolean value and this will generate the all service classes those we can use in local or within same application environment and the default value is false.

Possible attribute values:

It table Boolean values possible values can be true/false

Note:

This is optional attribute

Example:


<entity local-service="true/flase">
----
-----
</entity>


remote-service:

When we want generate web service to the entity then we will use this attribute. The default value is false. This will generate SOAP and JSON REST web service to entity. When we want expose our data to other platforms as web service then we have to use this attribute.

Possible attribute values:

It table Boolean values possible values can be true/false

Note:

This is optional attribute

Example:


<entity remote-service="true/flase">
----
-----
</entity>


data-source:

Liferay have given flexibility to define custom data sources for portlet so that we can specify the custom data source through this attribute.
This tells us in which data source our data base table is available. Default it will use liferay data source that is lportal data base to create table or access table.

Possible attribute values:

Name of the data source we configures for portlet.

Note:

This is optional attribute

Example:


<entity data-source="mydatasource">
----
-----
</entity>


For More information please go through following links:


session-factory:

This also similar to data source we can use custom session factory. When we want define our own session factory so that we can specify using this attribute so that persistence class loaded in specified session factory.

Possible attribute values:

Name of the session factory we configures for portlet.

Note:

This is optional attribute

Example:


<entity session-factory="mysessionfactory">
----
-----
</entity>


For More information please go through following links:


tx-manager:

This attribute specify that the entity/table whether use the transactions or not.

Possible attribute values:

 Name of transaction manager configured for portlet/none

If we use none value it won’t use transaction manager and by default every entity use the        liferay transaction manager specify in spring configuration files.

Note:

This is option attribute

Example:


<entity tx-manager="none/mytxmaneger">
----
-----
</entity>


cache-enabled:

When want handle cache mechanism on entity then we have to use this attribute
Possible attribute values:

It will take true/false values.

This is option attribute and by default for all entities cache is implemented by service builder if we don’t want then we need to make it false value. Set the value to false if data in the table will be updated by other programs.

Note:

This is option attribute

Example:


<entity cache-enabled="true/flase">
----
-----
</entity>


json-enabled :

The json-enabled value specifies whether or not the entity should be annotated
for JSON serialization. By default, if the remote-service value is true, then
The json-enabled value is true.

Example:


<entity json-enabled="true/flase">
----
-----
</entity>


service-builder-import:
The service-builder-import allows you to split up a large Service Builder file
into smaller files by aggregating the smaller Service Builder into one file.
Note that there can be at most one author element among all the files. There can
Also only be one and only one namespace element among all the files.

Important Attribute for service-builder-import tag

file

The attribute file is interpreted as relative to the file that is importing it.


  
Example


<service-builder-import file=”service.1xml”>


Note:

Some of the root tags have its child tags so I will post remaining child tags information on second part of the article

The following is sample example for service.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.db">
<author>E5410</author>
<namespace>meera</namespace>
<entity name="Student" local-service="true" remote-service="true" cache-enabled="true">
<!-- PK fields -->
<column name="studentId" type="long" primary="true" />
<!-- Audit fields -->
<column name="studentName" type="String" />
<column name="studentPlace" type="String" />
<column name="studentCollege" type="String" />
<!-- Order -->
<order by="asc">
<order-column name="studentId" />
</order>
<!-- Finder methods -->
<finder name="studentPlace" return-type="Collection">
<finder-column name="studentPlace" />
</finder>
</entity>
<entity name="Course" local-service="true" remote-service="true" cache-enabled="false">
<column name="courseId" type="long" primary="true" />
<!-- Audit fields -->
<column name="courseName" type="String" />
<column name="courseGroup" type="String" />
<!-- Order -->
<order by="asc">
<order-column name="courseId" />
</order>
<!-- Finder methods -->
<finder name="courseGroup" return-type="Collection">
<finder-column name="courseGroup" />
</finder>
</entity>
</service-builder>

Reference Links:


Author

Tuesday, January 21, 2014

Liferay Client Side Inter Portlet Communication Using Ajax

Objective:

Achieve inter portlet communication from client side using Ajax and Liferay Java Script.

Introduction:

Inter portlet communication is way of exchange the data between portlets in the page or portlets which reside in the other pages.

In liferay we have different ways we can achieve this one of the way is client side inter portlet communication.

Environment:

Liferay 6.2 +Tomcat 7.x+MySQL 5.1

Note:

The code will work for portal 6.2 version you can try for 6.1 too.

Download Client Side IPC portlet from following location

You can find source and war file


Portlet Screen:



Procedure for deploy portlet:

You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.

Once portlet is deployed successfully you can see the portlet in sample category names as Sender Portlet and Receiver Portlet.

Usage Of Portlets:

Drag and Drop two portlet in same page and enter email address in sender portlet then click on send button as soon as you click you can see user details in receiver portlet.

Client Side Inter Portlet Communication (IPC):

Client Side Inter Portlet Communication is one of the ways in IPC   this can apply the portlet which reside in same page. Because Client side IPC will uses java script to communicate that’s why all portlet which participated in IPC need to be in same page.

Liferay already have some java script library to implement client side IPC in portlet 
development.

The following diagram show you the IPC among Portlets


Here we have two types of portlets

Sender Portlet
Receiver Portlet

Sender Portlet:

Sender portlet will fire or trigger the event means it will initiate the sending message to other portlet.

Receiver Portlet

Receiver portlet is ready to take/listen the event from sender portlet as soon as sender portlet send the message then receiver portlet reactive the messages. Here one or more receiver portlet can be for one sender portlet.

The thing is we need to bind the receiver portlet with sender event. So that it can be listen the event as soon as sender sends the message.

Note:

All portlet which participate in client side IPC should be in same page and here page refresh will not be happened.

Assumption:

Assume we have sender and receiver portlet in page and sender will get some user data from server and the data will be pass to receiver portlet.

Sender portlet get the data from server it will use the Ajax call and once it will get the data then the data will be sending to receiver portlet using Client Side IPC with help of liferay java script implementation methods.

Register event in sender portlet as follows


Java script syntax

 Liferay.fire('eventName',{
                param1:paramValue1,
                param2:paramValue2
});

Example code as follows in sender portlet view.jsp

Liferay.fire('getUserData',{
              name: Meera Prince
});
                 
                

Receive the event from Sender Portlet in receiver portlet as Follows


Java script syntax

Liferay.on('eventName',function(event) {
// write code to get the veluese that sent by sender portlet
});

Example code as follows in receiver portlet view.jsp

Liferay.on('getUserData',function(event) {
 alert('User Name:'+ event.name)
});



Implementation In development

The following are the steps to implement
  1. Create Two Liferay MVC portlets
  2. Make it <requires-namespaced-parameters/>   tag value to false in portlets
  3. Register Event in Sender Portlet
  4. Receive Event in Receive portlet

Note:

This is Client Side IPC events mechanism using java script and the portlet all are in same page.

Create Two Liferay MVC portlets

Create two Liferay MVC portlet from Liferay IDE with eclipse environment and decide Sender and Receiver portlets.

The following is more information to set up Liferay Development Environment


Make it <requires-namespaced-parameters/>   tag value to false in portlets

In liferay-portlet.xml file we need to make <requires-namespaced-parameters/>   tag value to false so that we can pass data in request using Ajax call.

This we need to make it false in spring portlet and when we use ajax as well.

If we make it false then only we can pass data to server using Ajax call.

The following is example for liferat-portlet.xml file as follows


<portlet>
<portlet-name>sender</portlet-name>
<icon>/icon.png</icon>
<instanceable>false</instanceable>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>sender-portlet</css-class-wrapper>
</portlet>

Which portlet need Ajax interaction then we need to make it false to that portlet.

Register Event in Sender Portlet

Now we need register required even in Sender portlet so that it will send events to receiver portlets. This is complete java script implementation and we will use Liferay java script implementation.

Here we will get user information from server using jQuery Ajax call and once we get user data then we are sending to receiver portlet  using liferay java script implementation method i.e. Liferay.fire(----)

The following is example code in Sender Portlet view.jsp page

<%@page import="com.liferay.portal.theme.ThemeDisplay"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ page import="com.liferay.portal.kernel.portlet.LiferayWindowState" %>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<portlet:resourceURL var="getUserData">
</portlet:resourceURL>
<script>
$(document).on('ready',function(){
jQuery('#<portlet:namespace/>getUserByEmail').click(function(event) {
var emailAddessValue = jQuery('#<portlet:namespace/>emailAddess').val();
  $.ajax({
url:'<%=getUserData%>',
dataType: "json",
data:{emailAddess:emailAddessValue,
companyId:'<%=themeDisplay.getCompanyId()%>'
},
type: "get",
success: function(data){
Liferay.fire('getUserData', {userData:data});
},
beforeSend: function(){
//before send this method will be called
},
complete: function(){
//after completed request then this method will be called.
},
error: function(){
$('#userContent').html('<span style="color:red">Connection problems</span>');
}
});
});
});
</script>
<aui:form method="POST" action="<%=getUserData%>" >
<aui:input type="text" name="emailAddess"   id="emailAddess" label="Email Address"/>
<aui:button type="button" name="getUserByEmail" value="Send" id="getUserByEmail" />
</aui:form>

Receive Event in Receive portlet

Now we need to receive the even in receiver portlet. We already know sender send the message or event now we need to catch the message using Liferay.on(---) method.

Note:

We can have multiple receiver portlet for one sender portlet.

The following is complete code in receiver portlet view.jsp page


<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<portlet:defineObjects />
<style>
#userData td{
font-weight: bold;
width:200px;
border: 1px solid gary;
}
</style>
<script>
Liferay.on(
'getUserData',function(event) {
jQuery('#userInformation').empty();
jQuery('#errorInformation').empty();
if(event.userData.error!=null){
            jQuery('#errorInformation').html(event.userData.error);
}else{
var htmlString="<table id='userData'>"+
"<tr><td>User Id</td><td>"+event.userData.userId+"</td></tr>"+
"<tr><td>First Name</td><td>"+event.userData.firstName+"</td></tr>"+
"<tr><td>Last Name</td><td>"+event.userData.lastName+"</td></tr>"+
"<tr><td>Email Address</td><td>"+event.userData.emailAddress+"</td></tr>"+
"</table>";
jQuery('#userInformation').html(htmlString);
}
});
</script>
<div id="userInformation"></div>
<div id="errorInformation" style="color:red;font-weight:bold;"></div>

Important points:
  • Inter Portlet Communication (IPC) can be achieved in different ways and client side IPC is one of the way.
  • Client Side IPC is pure java script implementation so that It apply only the portlet which are in same page.
  • Liferay implemented some java script methods to implement Client Side IPC.
  • We used Ajax call to get data from server one we get the data we populated in other portlet using Client Side IPC.

Author
Liferay Top Contributor Award Winner

Recent Posts

Recent Posts Widget

Popular Posts