Sunday, September 1, 2013

Connecting Liferay with Another Database

In the following post we will connect liferay with some third party database (legacy database):

Method 1:

1. Create Service.xml

2. Create ext-spring.xml file as /WEB-INF/src/META-INF/ext-spring.xml

You wont believe but yes we are done!!


Method 2:

1. Make an entry in portal-ext.properties file for another database:

2. create service.xml:

3. create ext-spring.xml file:


done!


NOTE: In both the above methods, we have to create the table manually in the database.

Liferay Permission on Custom Portlet

As mentioned on Liferay Dcoumentation we can add permissions to your custom portlets using four easy steps (also known as DRAC):

1. Define all resources and their permissions.
2. Register all defined resources in the permissions system. This is also known as adding resources.
3. Associate the necessary permissions with resources.
4. Check permission before returning resources.

Here we are implementing Liferay Permission for custom portlet named StudentMaster.

1. The first step is to define your resources and the actions that can be defined on them. Create a file named default.xml in /src/resource-actions folder -


2. After defining resource permissions for our custom portlet, we need to refer Liferay to the resource-actions XML file that contains definitions. Create a properties file named portlet.properties that references the the file default.xml. In this portlet properties file, create a property named resource.actions.configs with the relative path to portlet’s resource-action mapping file (e.g.default.xml) as its value. Here’s what this property specification might look like:


3. Adding a Resource

After defining resources and actions, it’s time to add resources into the permissions system. Resources are added at the same time entities are added to the database. Each Entity that requires access permission must be added as a resource every time it is stored.

4. Adding Permission:

On the portlet level, no code needs to be written in order to have the permission system work for custom portlet. If we have defined any custom permissions (supported actions) in configuration file’s portlet-resource tag, they’re automatically added to a list of permissions in Liferay’s permissions UI. What good, however, are permissions that are available but can’t be set by users?
To let a user set permissions on model resources, we must expose the permission interface to the user. Just add these two Liferay UI tags to JSP:
1. : Returns a URL to the permission settings configuration page.
2. : Shows an icon to the user. These are defined in the theme, and one of them (see below) is used for permissions.

5. Checking Permission:


Thursday, May 23, 2013

Spring MVC Portlet Validations

In the previous post we have implemented spring mvc portlet using Liferay Portal. In the following post we are going to implement input validation for adding new student form. We will use Spring’s Validator framework for validating data entered during adding new student.

1. First of all we will create StudentValidator class which implements Spring’s Validator interface.


[code language="java"]
@Component("studentValidator")
public class StudentValidator implements Validator{

@Override
public boolean supports(Class clazz) {
return Student.class.isAssignableFrom(clazz);
}

@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name", "Field name is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "subject", "required.subject", "Field subject is required.");
}
}
[/code]

2. Now we will make changes in StudentController class

a. The @Autowired annotation is used to instruct the Spring container to inject the dependency. We will use this to inject StudentValidator in our StudentController class:

[code language="java"]
@Autowired
StudentValidator studentValidator;
[/code]

b. Modify the addStudent method to insert validation code -

[code language="java"]
@ActionMapping(params = "myaction=addStudent")
public void addStudent(@ModelAttribute("student") StudentImpl student, BindingResult result, ActionResponse actionResponse)
{
studentValidator.validate(student, result);
if(result.hasErrors())
{
actionResponse.setRenderParameter("myaction", "addStudentForm");
}
else
{
try {
long studentId = CounterLocalServiceUtil.increment(Student.class.getName());
student.setPrimaryKey(studentId);
StudentLocalServiceUtil.addStudent(student);
} catch (SystemException e) {
e.printStackTrace();
}
}
}
[/code]

c. modify the showAddStudentForm method -

[code language="java"]
@RenderMapping(params = "myaction=addStudentForm")
public String showAddStudentForm(Model model) throws SystemException
{
System.out.println("showAddStudentForm Called !!!!!!!!!!!");
return "addStudent";
}
[/code]

d. Add the following new method -

[code language="java"]
@ModelAttribute("student")
public Student getCommandObject() {
return new StudentImpl();
}
[/code]

3. make changes in addStudent.jsp file to display error messages-

[code language="html"]
<form:form action="<%=AddStudentURL.toString()%>" method="post" commandName="student">
<table>
<form:errors path="*" />
<tr><td>Name :</td> <td><form:input path="name" /></td></tr>
<tr><td colspan="2"><form:errors path="name"></form:errors></td></tr>
<tr><td>Subject:</td> <td><form:input path="subject" /></td></tr>
<tr><td colspan="2"><form:errors path="subject"></form:errors></td></tr>
<tr><td colspan="2"><input type="submit" value="Save" /></td></tr>
</table>
</form:form>
[/code]

4. Add the following snippet to myContext.xml file

[code language="xml"]
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>content.Language_en</value>
</list>
</property>
</bean>
[/code]

5. Add an entry to portlet.xml file -

[code language="xml"]
<resource-bundle>content.Language_en</resource-bundle>
[/code]

6. create new file named Language_en.properties with following content in src/content folder -

[code language="java"]
required.name = name is required!
required.subject = subject is required!
[/code]

We are done with all the changes required!

Saturday, August 25, 2012

Thursday, August 23, 2012

Liferay Custom JSON Web Service Development



Following is the step by step description of generating a custom liferay plugin service and exposing it as JSON Web Service.



STEP:1 Create a liferay plugin project and create new service


Here is the sample service.xml



Make sure remote-service=”true” in entity tag declaration.



STEP:2  Build the service.



STEP:3  Add your custom method in SampleLocalServiceImpl class



STEP:4  Build the service.



STEP:5  Add the method definition to SampleServiceImpl class



STEP:6  build the service.



STEP:7  Add the following <servlet> and <servlet-mapping> Entries to portlet's web.xml file -



STEP:8  deploy the portlet.


STEP:9  To access your json web services enter the following url -

http://localhost:8080/<<portlet-context>>/api/jsonws





and Its Done!!!





Friday, July 27, 2012

Spring MVC Portlet - Liferay

In this post we are going are develop a multi page portlet using Spring 3.0 Portlet MVC using annotations.

Following are screen shots of various pages -

  1. Home Page: Displays a lists of student with action button to perform edit and delete action on particular student. Add New Student link n the top opens up a new form where we can provide the details for new student and save.

    Home Page



  2. Add New Student: On clicking Add New Student following page will open.


add new student

3. Edit Student Form: Clicking edit from the action menu will display the edit student form.

edit form

  1. Delete Student: Clicking delete from the action menu will display a confirmation alert box and based on your choice will perform.delete studentFollowing are the code listings:


- StudentController.java

[sourcecode language="java"]

@Controller(value="studentController")
@RequestMapping(value = "VIEW")
public class StudentController {

@RenderMapping
public String showStudents(RenderResponse response,Model model) {
System.out.println("Render Called");
List students = null;
try {
students = StudentLocalServiceUtil.getStudents(-1, -1);
} catch (SystemException e) {
System.out.println("Error in getting student list");
e.printStackTrace();
}
model.addAttribute("students", students) ;
return "myView";
}

@RenderMapping(params = "myaction=addStudentForm")
public String showAddStudentForm(Model model) throws SystemException
{
System.out.println("showAddStudentForm Called !!!!!!!!!!!");
Student student = new StudentImpl();
model.addAttribute("student", student);
return "addStudent";
}

@ActionMapping(params = "myaction=addStudent")
public void addStudent(@ModelAttribute("student") StudentImpl student,BindingResult bindingResult, ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {

student.setPrimaryKey(CounterLocalServiceUtil.increment(Student.class.getName()));
Student newStudent = StudentLocalServiceUtil.addStudent(student);
System.out.println("Student added : " + newStudent.getName());
}

@RenderMapping(params = "myaction=editStudentForm")
public String editStudentForm(@RequestParam Long resourcePrimKey,Model model) throws PortalException, SystemException
{
System.out.println("Edit Student Form Called !!" + resourcePrimKey);
Student student = StudentLocalServiceUtil.getStudent(resourcePrimKey);
model.addAttribute("student", student);
return "editStudent";
}

@ActionMapping(params = "myaction=editStudent")
public void editStudent(@ModelAttribute StudentImpl student,@RequestParam Long resourcePrimKey,ActionResponse response) throws IOException
{
student.setId(resourcePrimKey);
System.out.println("Edit Student Called!!" + student.getId());
try {
StudentLocalServiceUtil.updateStudent(student);
} catch (SystemException e) {
System.out.println("Error Occured while updating!! ");
e.printStackTrace();
}
}

@ActionMapping(params = "myaction=deleteStudent")
public void deleteStudent(ActionRequest request,ActionResponse response){
long primKey = ParamUtil.getLong(request, "resourcePrimKey");
System.out.println("Delete Called for : " + primKey);
try {
StudentLocalServiceUtil.deleteStudent(primKey);
} catch (PortalException e) {
System.out.println("Error Occured while deleting");
e.printStackTrace();
} catch (SystemException e) {
System.out.println("Error Occured whlile deleting");
e.printStackTrace();
}
}
}

[/sourcecode]

- myView.jsp

[sourcecode language="java"]

<portlet:renderURL var="addStudentJSP">
<portlet:param name="myaction" value="addStudentForm"></portlet:param>
</portlet:renderURL>
<% PortletURL iteratorURL = renderResponse.createRenderURL(); %>

<a href="<%=addStudentJSP%>">Add New Student</a>

<br/><br/>

<liferay-ui:search-container delta="5" emptyResultsMessage="No Students were found!!" iteratorURL="<%=iteratorURL%>">
<liferay-ui:search-container-results results="<%=ListUtil.subList((List<Student>)request.getAttribute(\"students\"), searchContainer.getStart(), searchContainer.getEnd())%>" total="${students.size()}" />
<liferay-ui:search-container-row className="com.test.model.Student" keyProperty="id" modelVar="student">
<liferay-ui:search-container-column-text name="name" value="${student.name}" />
<liferay-ui:search-container-column-text name="subject" value="${student.subject}" />
<liferay-ui:search-container-column-jsp path="/WEB-INF/jsp/studentActions.jsp" align="right" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>

[/sourcecode]

- addStudent.jsp

[sourcecode language="java"]

<portlet:actionURL var="AddStudentURL">
<portlet:param name="myaction" value="addStudent"></portlet:param>
</portlet:actionURL>

<form:form action="<%=AddStudentURL.toString()%>" method="post" commandName="student">
<table>
<tr><td>Name :</td> <td><form:input path="name" /></td></tr>
<tr><td>Subject:</td> <td><form:input path="subject" /></td></tr>
<tr><td colspan="2"><input type="submit" value="Save" /></td></tr>
</table>
</form:form>

[/sourcecode]


- editStudent.jsp
[sourcecode language="java"]

<h2>Edit Student</h2>

<portlet:actionURL var="EditStudentURL">
<portlet:param name="myaction" value="editStudent" />
<portlet:param name="resourcePrimKey" value="${student.primaryKey}" />
</portlet:actionURL>

<form:form action="<%=EditStudentURL.toString()%>" method="post" commandName="student">
<table>
<tr><td>Name :</td> <td><form:input path="name" /></td></tr>
<tr><td>Subject:</td> <td><form:input path="subject" /></td></tr>
<tr><td colspan="2"><input type="submit" value="Save" /></td></tr>
</table>
</form:form>
[/sourcecode]

- studentActions.jsp

[sourcecode language="java"]

<%
ResultRow row = (ResultRow) request.getAttribute(WebKeys.SEARCH_CONTAINER_RESULT_ROW);
Student myStudent = (Student) row.getObject();
String primKey = String.valueOf(myStudent.getPrimaryKey());
%>

<liferay-ui:icon-menu>
<liferay-portlet:renderURL var="editURL">
<portlet:param name="myaction" value="editStudentForm" />
<portlet:param name="resourcePrimKey" value="<%= primKey %>" />
</liferay-portlet:renderURL>
<liferay-ui:icon image="edit" message="Edit" url="<%= editURL.toString() %>" />

<portlet:actionURL var="deleteURL">
<portlet:param name="myaction" value="deleteStudent" />
<portlet:param name="resourcePrimKey" value="<%= primKey %>" />
</portlet:actionURL>
<liferay-ui:icon-delete url="<%= deleteURL.toString() %>" />
</liferay-ui:icon-menu>
[/sourcecode]

- Portlet Deployment Descriptor (portlet.xml)

[sourcecode language="java"]

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0">

<portlet>
<portlet-name>springdemo</portlet-name>
<display-name>SpringDemo</display-name>
<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
<init-param>
<name>contextConfigLocation</name>
<value>/WEB-INF/context/portlet/myContext.xml</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>Spring Demo</title>
<short-title>Spring Demo</short-title>
<keywords></keywords>
</portlet-info>
<security-role-ref>
<role-name>administrator</role-name>
</security-role-ref>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
</portlet-app>
[/sourcecode]

- Portlet Web Application Context (myContext.xml)

[sourcecode language="java"]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="com.test" />

<!-- <bean id="studentController"
class="com.test.controller.StudentController"/>

<bean id="portletModeHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="portletModeMap">
<map>
<entry key="view">
<ref bean="studentController" />
</entry>
</map>
</property>
</bean>
-->

</beans>

[/sourcecode]

- Root Web Application Context (applicationContext.xml)

[sourcecode language="java"]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

</beans>

[/sourcecode]

- Project Structure

project-structure

 

Build and Deploy it like any other liferay portlet.

Please comment if you have any questions or suggestions !!!

 

 

Tuesday, July 24, 2012

Liferay Custom Portlet Mode

 

The PortletMode class defines three constants—VIEW, EDIT, and HELP—corresponding
to the VIEW, EDIT, and HELP portlet modes. A portal may define support for additional portlet modes supported by the portal server or by the portlet.

 

Portal Managed Mode - If the portal server is responsible for managing the portlet mode, the portlet mode is referred to as portal-managed. Liferay provides config, about, print, preview and edit_defaults custom portlet modes.

Portlet Managed Mode - If the portlet is responsible for managing the portlet mode, it’s referred to as portlet-managed..

 

Implementing the Portal-managed Custom Portlet mode:

 

Here are the steps to implement print custom portlet mode provided by liferay

 

1. Define support in the portlet.xml -

We must specify the custom portlet mode in the portlet deployment descriptor using the <portlet-mode> subelement of the <supports> element

<portlet-mode>print</portlet-mode>

 

2. A custom portlet mode must also be defined at the portlet application level. The <custom-portlet-mode> subelement of <portlet-app> specifies the custom portlet modes that are available to portlets in the portlet application

<custom-portlet-mode>

<portlet-mode>print</portlet-mode>


</custom-portlet-mode>

 

3. Setting portlet mode in the URL

PortletURL printModeUrl = renderResponse.createRenderURL();
if(renderRequest.isPortletModeAllowed(new PortletMode("print"))) {
printModeUrl.setPortletMode(new PortletMode("print"));
}
request.setAttribute("printModeUrl", printModeUrl);

 

NOTE: if(renderRequest.isPortletModeAllowed(new PortletMode("print")))

above condition checks whether liferay provides support for print custom portlet mode. The PortalContext’s getSupportedPortletModes() method returns the list of portal-managed portlet modes.

 

4. Add link to switch to print mode

<a href="<%=printModeUrl.toString() %>">Print Mode</a>


 

5. Implementing the custom portlet mode behavior -

In the portlet class override the doPrint method:

@Override
public void doPrint(RenderRequest renderRequest,
RenderResponse renderResponse) throws IOException, PortletException {
System.out.println("Print Mode Called");
super.doPrint(renderRequest, renderResponse);
}

 

**Liferay doesnt provide support for portlet-managed custom portlet modes.