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

<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.