Laliwala IT Services

Laliwala IT Services
Website Development

Saturday, May 28, 2011

liferay portlet development

Deploying portlet
liferay portlet development
 liferay portal development
liferay portal assessment services

There are 2 main ways to deploy a portlet on Liferay.

1ST, but you need to allow autodeploy, you can use /liferay/deploy this is very simple: just drop in that directory your portlet (as a war file) and watch it beeing deployed on the portal.
This is the way plugins available on Liferay's SVN are deployed.

I concider it very reliable and fast. Very efficient when developing and testing your own (liferay) portlets in the field.

The second method is to use Liferay User Interface (UI). Simply log in with a user allowed to install new portlets and go to Admin > Plugins
You will find there a "Install More Portlets" button. Click on it.
There you have several options:

one is to use a local file and upload it this way to the server,
an other is download file, when you know where the porlet war file lies on the net,
and the default is to use Liferay repository, which means you are going to install a portlet part of one of the suggested online repositories.


Friday, April 1, 2011

liferay bigbluebutton

integration liferay bigbluebutton


Liferay Enterprise Edition (EE)

Liferay Community Edition (CE)

version 4.1.0.

Liferay Portal 6

Liferay5.2 EE

Liferay 6

Liferay Community Edition Version6.1

Liferay Portal 6.0.5 Community Edition

Liferay 6.0.6

Liferay Portal development platform for versions 6.0

liferay 5.3

Liferay Portal 5.2.x

Liferay version 5.1.2

Liferay Portal Community Edition 6.0.6

Thursday, March 31, 2011

liferay tutorial custom sql - liferay database configuration training

Liferay tutorial 

Liferay custom sql 
Liferay portal tables
Liferay Mysql
Liferay database
 
In this liferay tutorial, we will learn about Custom-sql.

  • custom sql query in liferay portal
  • custom SQL configurations
  • default database
  • how to build custom sql
  • portal database
  • custom SQL in liferay
  • How to configure Liferay Database
  • MySQL, Oracle, MS SQL Server
  • custom SQL statements
  • database SQL script
  • Liferay Database Document
  • How to Make Database connection in Liferay
  • SQL Database tables

How to work with Custom-sql in liferay portal?


Step-1: liferay portal custom sql Create ext.xml file


Create the file default-ext.xml under ext-impl/src/custom-sql (You need to first create this folder)

<?xml version="1.0"?>

<custom-sql>
<sql file="custom-sql/book.xml" />
</custom-sql>

(This file will list all the custom sql files developed for a specific application.
Also refer default.xml under portal source)

Step-2: liferay portal custom sql Create book.xml file
------

Create the file book.xml, under the same folder, which will contain all the application specific queries as name / value pairs.

<?xml version="1.0"?>
<custom-sql>
<sql id="com.ext.portlet.library.service.persistence.BookFinderImpl.getBooks">
<![CDATA[
SELECT
{Book.*}
FROM
Book
WHERE
(Book.title like ?)
]]>
</sql>
</custom-sql>

(The beauty is the queries are separated from the code, so that we can change them any time without touching the code)




Step-3: liferay portal custom sql Over ride portal-ext.properties
------

Over-ride the property in portal-ext.properties

custom.sql.configs=\
custom-sql/default.xml, \
custom-sql/default-ext.xml

So far we have seen the configuration part.

Now we'll move on to the implementation part.

Step-4: liferay portal custom sql create bookfinderimpl.java
------

Create the file "BookFinderImpl.java" under service/persistence

package com.ext.portlet.library.service.persistence;

import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;

public class BookFinderImpl extends BasePersistenceImpl implements
BookFinder{

}

Step-5: liferay portal custom sql ant build service
------

Do ant build-service, so that the necessary interface is generated.
Refresh the workspace in eclipse to see everything compiled properly.

Step-6: liferay portal custom sql update bookfinderimpl
------

Now write the actual logic to access the custom SQL. You need to update the BookFinderImpl
we developed in the previous step.

// the name of the query
public static String GET_BOOKS = BookFinderImpl.class.getName()
+ ".getBooks";

// the method which will be called from the ServiceImpl class
public List<Book> getBooks(String pattern) throws SystemException {

Session session = null;
try {
// open a new hibernate session
session = openSession();

// pull out our query from book.xml, created earlier
String sql = CustomSQLUtil.get(GET_BOOKS);

// create a SQLQuery object
SQLQuery q = session.createSQLQuery(sql);

// replace the "Book" in the query string with the fully qualified java class
// this has to be the hibernate table name
q.addEntity("Book", BookImpl.class);


// Get query position instance
QueryPos qPos = QueryPos.getInstance(q);

// fill in the "?" value of the custom query
// this is same like forming a prepared statement
qPos.add(pattern);

// execute the query and return a list from the db
return (List<Book>)q.list();

/*
// use this block if you want to return the no. of rows (count)

int rows = 0;

Iterator<Long> itr = q.list().iterator();

if (itr.hasNext()) { Long count = itr.next();

if (count != null) { rows = count.intValue(); } }

return rows;
*/
} catch (Exception e) {
throw new SystemException(e);
} finally {
closeSession(session);
}
}

Make the necessary additional imports.

import java.util.List;

import com.ext.portlet.library.model.Book;
import com.ext.portlet.library.model.impl.BookImpl;
import com.liferay.portal.SystemException;
import com.liferay.portal.kernel.dao.orm.QueryPos;
import com.liferay.portal.kernel.dao.orm.SQLQuery;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.util.dao.orm.CustomSQLUtil;

Note:

To get the result between a start and end index, you have to use,

QueryUtil.list(q, getDialect(), begin, end);

in the place of

q.list();

where, you will pass the parameters (begin and end) from your ServiceImpl class.

Step-7: liferay portal custom sql write method booklacalserviceimpl.java
------

write the method in BookLocalServiceImpl.java

public List<Book> searchBook(String title) throws PortalException,
SystemException, RemoteException {

// return bookPersistence.findByTitle(title);
return BookFinderUtil.getBooks("%" + title + "%");
}


Step-8: liferay portal custom sql and build service
------

run "ant build-service" again passing the service.xml file as parameter.

This will update the corresponding interface with the new method defined.


Step 9: liferay portal custom sql add search2 button
-------

in view.jsp

Add for 'search2' button

<input type="button" value="Search2" onClick="<portlet:namespace />findBook('search2');" />

Note: the findBook JS function is now accepting a parameter, do changes to this function and also to the "Find Book" button.


Step 10: liferay portal custom sql write code addbookaction.java
-------


Write code in AddBookAction.java to invoke the new finder API thru the BookFinderUtil.

if (Validator.isNull(cmd)) {
BookLocalServiceUtil.create(bookTitle);
} else {
List<Book> results = null;
if (cmd.equals("find")) {
results = BookLocalServiceUtil.findBooks(bookTitle);
} else if (cmd.equals("search")) {
DetachedCriteria dCriteria = DetachedCriteria.forClass(Book.class);
dCriteria.add(Restrictions.like("title", "%" + bookTitle + "%"));
DynamicQuery dynamicQuery = new DynamicQueryImpl(dCriteria);
results = (List)BookLocalServiceUtil.dynamicQuery(dynamicQuery);
} else {
results = (List)BookLocalServiceUtil.searchBook(bookTitle);
}
req.setAttribute("results", results);
req.setAttribute("cmd", cmd);
}

Step 11 : liferay portal custom sql deploy
========
deploy :

verify we've done all the steps properly
ant deploy from ext-impl,
ant deploy-fast from ext-web,
restart tomcat

Congratulations !!!

Glossary:
--------

1. Look at the custom-sql xml files written for some liferay portlets.

2. How to replace strings in the sql statements using StringUtil.replace.




Liferay tutorial Dynamic Query - hibernate api

Liferay tutorial Dynamic Query

 Liferay action
Liferay services
Liferay tomcat

===============================================================
Writing Dynamic Query using Hibernate API's


http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Queries+2%3A+DynamicQuery+API

http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/How+to+create+a+custom+query+in+liferay

http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/How+to+create+a+custom+query+in+ext+for+Liferay+models


Forming a Dynamic Query :
=========================
Step 1:

in AddBookAction.java:

if (Validator.isNull(cmd)) {
BookLocalServiceUtil.create(bookTitle);
} else {
List<Book> results = null;
if (cmd.equals(" find" )) {
results = BookLocalServiceUtil.findBooks(bookTitle);
} else {
DetachedCriteria dCriteria = DetachedCriteria.forClass(Book.class);
dCriteria.add(Restrictions.like(" title" , " %" + bookTitle + " %" ));
DynamicQuery dynamicQuery = new DynamicQueryImpl(dCriteria);
results = (List)BookLocalServiceUtil.dynamicQuery(dynamicQuery);
}
req.setAttribute(" results" , results);
req.setAttribute(" cmd" , cmd);
}

Make following imports

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.liferay.portal.kernel.dao.orm.*;
import com.liferay.portal.dao.orm.hibernate.DynamicQueryImpl;


Step 2:
=======
in view.jsp

Add for 'search' button

<input type=" button" value=" Search" onClick=" <portlet:namespace />findBook('search');" />

Note: the findBook JS function is now accepting a parameter, do changes to this function and also to the " Find Book" button.

Step 3:
=======

in Success.jsp update this

if (Validator.isNotNull(cmd)) {
books = (List)request.getAttribute(" results" );
} else {
books = BookLocalServiceUtil.getAllBooks();
}

Step4 :
========
verify we've done all the steps properly
ant deploy from ext-impl,
ant deploy-fast from ext-web,
restart tomcat

Congratulations Liferay developers!!!


Liferay example tutorial : finder tag in service.xml file

Liferay update services.xml file
Liferay example


===============================================================
Generating finder methods using finder tags in service.xml file
===============================================================

1. update the service.xml file with order by clause

< !-- order by -->
< order by=" asc" >
< order-column name=" title" />
< /order>


More on order by (sorting). Taken from DTD file.

< !--
The attributes of the order-column element allows you to fine tune the ordering
of the entity.

For example:

< order by=" asc" >
< order-column name=" parentLayoutId" />
< order-column name=" priority" />
< /order>

The above settings will order by parentLayoutId and then by priority in an
ascending manner.

For example:

< order by=" asc" >
< order-column name=" name" case-sensitive=" false" />
< /order>

The above settings will order by name and will not be case sensitive.

For example:

< order>
< order-column name=" articleId" order-by=" asc" />
< order-column name=" version" order-by=" desc" />
< /order>

The above settings will order by articleId in an ascending manner and then by
version in a descending manner.
-->


2. update the service layer with new finder methods.

< !-- Finder methods -->

< finder name=" BookId" return-type=" Book" >
< finder-column name=" bookId" />
< /finder>

< finder name=" Title" return-type=" Collection" >
< finder-column name=" title" />
< /finder>

< finder name=" Title_Author" return-type=" Collection" >
< finder-column name=" title" />
< finder-column name=" author" />
< /finder>

2. Run " ant build-service" to re-generate the service layer.

You'll find the new finder methods generated.

difference fetchBy and findBy methods.

3. Writing a new method in BookLocalServiceImpl.java to invoke a finder method.

public List< Book> findBooks(String title)
throws PortalException, SystemException, RemoteException {

//return bookPersistence.findByTitle(title);
return BookUtil.findByTitle(title);
}

When to use the persistence object and the interface.

4. update view.jsp

Add a new button " Find Book" and a hidden variable 'cmd'

< input type=" hidden" name=" < portlet:namespace /> cmd" />
< input type=" button" value=" Find Book" onClick=" < portlet:namespace /> findBook();" />


Write new JS function,

function < portlet:namespace /> findBook() {
var frm = document.< portlet:namespace /> fm;

frm.< portlet:namespace /> cmd.value = 'find';

frm.submit();
}

5. updating the AddBookAction.java to invoke the new API.


Add the line,

String cmd = ParamUtil.getString(req, " cmd" );

replace,

BookLocalServiceUtil.create(bookTitle);

with,

if (Validator.isNull(cmd)) {
BookLocalServiceUtil.create(bookTitle);
} else {
List< Book> results = BookLocalServiceUtil.findBooks(bookTitle);
req.setAttribute(" results" , results);
req.setAttribute(" cmd" , cmd);
}

un-comment setForward and comment out res.sendRedirect

6. updating the success.jsp

replace,

List< Book> books = BookLocalServiceUtil.getAllBooks();

with,

List< Book> books = null;

String cmd = ParamUtil.getString(request, " cmd" );

if (Validator.isNotNull(cmd)) {
books = (List)request.getAttribute(" results" );
} else {
books = BookLocalServiceUtil.getAllBooks();
}


7. deploy

verify we've done all the steps properly
ant deploy-fast from ext-web (we ve only modified files view.jsp and success.jsp)
ant deploy from ext-impl
restart the server and confirm the find feature is working perfectely fine.

Congratulations !!!

8. Advantages and dis-advantages of using finder tags.

a. it generated the indices for the database.
b. can only do " EQ" finds
c. " where" attribute can be used.

eg. where=" dateAdded is not NULL"

Liferay tutorial json : call service api "Liferay tutorial version 5.2"

 Liferay JSON tutorial
Liferay services layer
Liferay version 5.2.x
Liferay remote method


===============================================================
Invokining service layer thru JSON.
===============================================================

pre-requisite for JSON to work, we should have a remote method.

1. look into the following file

ext-web/docroot/html/js/liferay/ext_service_unpacked.js

Note: In liferay version 5.2.x onwards this file is "ext_service.js"

Note: in the earlier versions the file name is ext_service_unpacked.js

2. define a new java script function in view.jsp

< script src="/html/js/liferay/ext_service.js">< /script>

< script>
function < portlet:namespace />addBookThruJSON() {

var frm = document.< portlet:namespace />fm;
var title = frm.< portlet:namespace />book_title.value;
var params = {
title:title
};
Liferay.Service.Library.Book.create(params);
alert('Book successfully added');
frm.< portlet:namespace />book_title.value = "";
}
< /script>

3. Update the form,

Add another button to the form which when clicked will invoke addBookThruJSON() javascript method.

< input type="button" value="Add thru JSON" onClick="< portlet:namespace />addBookThruJSON();">

Now do "ant deploy-fast" from ext-web and see adding of the book thru json is working perfectly fine.

in the next example we'll see how to write a call back.





Liferay tutorial web service


 Liferay tutorial web service
Liferay update service 
Liferay book



===============================================================
7. Exposing the method as a web service
===============================================================
7.1 update service.xml
----------------------
specify remote-service="true" (default)
difference between local service and remote service.
Needless to say, once you do any modifications to service.xml file, please run "ant build-service"
7.2 updating service layer class - 2
------------------------------------
(file location - ext\ext-impl\src\com\ext\portlet\library\service\impl\BookServiceImpl.java)
public Book create(String title)
throws PortalException, SystemException, RemoteException {
return bookLocalService.create(title, "abcd");
}
(insert the additional import statements required to compile this class,)
import com.ext.portlet.library.model.Book;
import java.rmi.RemoteException;
import com.liferay.portal.PortalException;
import com.liferay.portal.SystemException;
Important: Dont forget to re-generate the service layer after inserting this method into BookServiceImpl.java
7.3 steps to expose as a web-service
------------------------------------
a. go to "/ext/ext-impl"
b. execute "ant build-wsdd -Dservice.file=src/com/ext/portlet/library/service.xml"
c. make sure the build is successful
d. from ext level run "ant deploy"
e. re-start the server
g. make sure our new web-service is listed out and hence exposed.
h. in subsequent sessions we'll see how to consume this web-service from any other application.
Excercise:
Expose the getAllBooks method as a web service.

struts portlet tutorial, struts portlet, Irshad Mansuri

Prepared by Aasif and Ahmed under the guidance of Irshad Mansuri

Attune Infocom
----------------------------------------------------------------------------------
===============================================================
6. Struts Portlet - Adding Redirect to avoid duplicate insertion
===============================================================

6.1 update struts-config.xml
----------------------------

add /ext/library/success so that we have a landing path

(location "ext/ext-web/docroot/WEB-INF")

<action path="/ext/library/success" forward="portlet.ext.library.success" />

run "ant deploy" from "ext-web"


6.2 update AddBookAction.java
-----------------------------

* We are going to modify our java to use a redirect instead of a forward
* A forward still submits to the page that it lands on. But a redirect will no longer retain the submit state on the landing page

Comment out the forward line
//setForward(req, "portlet.ext.library.success");

replace with these lines

PortletURL redirectURL = ((ActionResponseImpl) res).createRenderURL();
redirectURL.setParameter("struts_action", "/ext/library/success");
res.sendRedirect(redirectURL + "&title=" + bookTitle);

Make necessary imports


6.3 ant deploy
--------------

ant deploy from "ext-impl", re-start server and check the previous problem is not happening anymore.

6.4 Exercise
------------

What changes are required if we dont want to display the book title in the success.jsp file.

Adding database interaction, Retrieving records

Prepared by Aasif and Ahmed under the guidance of Irshad Mansuri

Attune Infocom
----------------------------------------------------------------------------------
===============================================================
5. Adding database interaction - Retrieving records

5.1 Update BookLocalServicImpl.java
------------------------------------

add the new method

public List<Book> getAllBooks()
throws PortalException, SystemException, RemoteException {
return bookPersistence.findAll();
}

append the new import,

import java.util.List;

5.2 run ant build-service again to re-generate the corresponding Util classes
-----------------------------------------------------------------------------

a. execute "ant build-service -Dservice.file=src/com/ext/portlet/library/service.xml"

b. execute "ant deploy" from ext-impl to compile and deploy all the generated file and make sure the build is SUCCESSFUL.


5.3 update "init.jsp"
---------------------

Make additional imports. The intent is to get access to generated service layer classes inside any of the jsp's of this portlet.

(location "ext/ext-web/docroot/html/portlet/ext/library")

<%@ page import="java.util.List" %>
<%@ page import="com.ext.portlet.library.model.Book" %>
<%@ page import="com.ext.portlet.library.service.BookLocalServiceUtil" %>








5.4 update "success.jsp" (append the below code)
------------------------------------------------

(location "ext/ext-web/docroot/html/portlet/ext/library")

<%
String bookTitle = request.getParameter("title");

// new line inserted.
List<Book> books = BookLocalServiceUtil.getAllBooks();
%>

<table align="center" cellspacing="10" cellpadding="3">
<tr>
<td style="font-weight:bold">Book Title: </td>
<td><%= bookTitle %></td>
</tr>
</table>

<!-- new code added -->
<table border="1">
<%
for (Book book : books) {
%>
<tr>
<td>Book Id: <%= book.getBookId()%></td>
<td>Title: <%= book.getTitle() %></td>
</tr>
<%
}
%>
</table>

5.5 ant deploy to tomcat
------------------------

a. run "ant deploy-fast" from "ext-web"

b. re-start the tomcat server

c. see the updates to the library portlet (the records are retrieved properly)

Exercise:

display the dateAdded column in the table where all the books are listed.


5.6 the problem with page re-fresh
----------------------------------

everything is working fine. try to refresh the page and see what happens.

duplicate record is getting added to the database. In the next section, we'll see how to handle this
















See that after refreshing duplicate record is added.

Check the table contents which shows duplicate recors.