Creating Liferay portlet with liferay-maven-sdk
This post will demonstrate how liferay-maven-sdk can be employed to build a Liferay portlet using Liferay’s Service Builder feature. For this purpose we will create service-builder-portlet which is capable of displaying a list of players and adding a new player to this list. The model, persistence layer and data access services will be generated by Service Builder
.
But first things first. Download and install liferay-maven-sdk
if you haven’t done so already (have a look at Download and Install page for instructions). Once liferay-maven-sdk
is installed in your local repository, you can create the portlet.
So enter the folder (or create one) where you keep your portlets and execute mvn archetype:generate
you should see a list of available archetypes starting with
Choose archetype:
1: local -> liferay-portlet-archetype (Liferay portlet archetype)
2: local -> liferay-theme-archetype (Liferay theme archetype)
3: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate, Spring and JSF)
4: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with Hibernate, Spring and Spring MVC)
...
Choose a number: (1/2/3/4/...) :1
Type 1
and press enter to choose liferay-portlet-archetype
. Then provide groupId
, artifactID
, package
and version
. For example:
Define value for groupId: : com.commsen.liferay.examples.portlet.servicebuilder
Define value for artifactId: : service-builder-portlet
Define value for version: 1.0-SNAPSHOT: : 1.0
Define value for package: com.commsen.liferay.examples.portlet.servicebuilder: :
Additionally you may execute mvn eclipse:eclipse
to setup Eclipse IDE if, that is what you are using! At this time your portlet skeleton is ready and you may compile it and even create WAR, but it of course does nothing special.
Let’s now add data model and services. Create file service-builder-portlet/src/main/webapp/WEB-INF/service.xml
:
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_5_2_0.dtd">
<service-builder package-path="com.commsen.liferay.examples.portlet.servicebuilder">
<namespace>SB</namespace>
<entity
name="Player"
local-service="true"
remote-service="true">
<!-- PK fields -->
<column name="playerId" type="long" primary="true" />
<!-- Other fields -->
<column name="name" type="String" />
<column name="active" type="boolean" />
<column name="score" type="int" />
<column name="birthday" type="Date" />
<column name="description" type="String" />
<!-- Order -->
<order by="asc">
<order-column name="name" />
</order>
<!-- Finder methods -->
<finder name="ActivePlayers" return-type="Collection">
<finder-column name="active" />
</finder>
</entity>
</service-builder>
The portlet projects created by liferay-portlet-archetype
contain maven profile with lifray-maven-plugin
’s build-service
goal attached to generate-sources
phase. To run ServiceBuilder
you need to activate the profile:
mvn -P build-service package
If you read carefully the messages you will realize that service and persistence classes were generated in service-builder-portlet/src/main/java-service-api/
folder. Also there should be a few implementation files in service-builder-portlet/src/main/java/
.
Now we’ll add custom methods. Open the following file service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/service/impl/PlayerLocalServiceImpl.java
and paste this code:
public void addPlayer(String name, boolean active, int score, Date birthday, String desc) throws PortalException, SystemException {
long playerId = CounterLocalServiceUtil.increment();
Player player = PlayerUtil.create(playerId);
player.setName(name);
player.setActive(active);
player.setScore(score);
player.setBirthday(birthday);
player.setDescription(desc);
PlayerUtil.update(player, false);
}
public List<Player> getAllPlayers() throws PortalException, SystemException {
return PlayerUtil.findAll();
}
We added methods to the implementation class. The next time we compile the code we need to activate the build-service
profile again in order for Service Builder
to react on the change and regenerate the API and interfaces. If you want to try it now simply execute
mvn -P build-service compile
Now we can start using these services in our portlet. Open service-builder-portlet/src/main/java/com/commsen/liferay/examples/portlet/servicebuilder/JSPPortlet.java
and add this method
@ProcessAction(name = Constants.ADD)
public void addPlayer(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException {
String name = ParamUtil.getString(actionRequest, "name");
boolean active = ParamUtil.getBoolean(actionRequest, "active");
int score = ParamUtil.getInteger(actionRequest, "score");
String description = ParamUtil.getString(actionRequest, "description");
int year = ParamUtil.getInteger(actionRequest, "birthday_year");
int month = ParamUtil.getInteger(actionRequest, "birthday_month");
int day = ParamUtil.getInteger(actionRequest, "birthday_day");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
try {
PlayerLocalServiceUtil.addPlayer(name, active, score, calendar.getTime(), description);
} catch (Exception e) {
throw new PortletException("Failed to add player", e);
}
}
This method handles adding players to database by calling the method we created earlier. To complete the portlet we only need the JSP page which displays the list and render HTML form to add users. The page source code is available here.
That’s all! We can now create WAR file (mvn package
) deploy it and add some players to our database! For more details have a look at portlet’s source code available in examples/service-builder-portlet folder of liferay-maven-sdk
.