Apache Pluto & Groovy Integration Tutorial Example

Filed Under: Portal and Portlets

Apache Pluto provides you a vast amount of integration types that you could use when it comes to deal with the Portlet development missions. We’ve previously, introduced you different types of Portlets; Standard Portlet (JSR286), JSP & Servlet, JSF 2.0, Struts 2.0, PHP 5 and now a Portlet of type Groovy.

Groovy is a Java Virtual Language (JVM) that’s working inside a JVM seamlessly like any Java Class you may write. Apache Pluto provides you a Groovy Bridge that enables you exposing a Groovy Portlet into your Portal Page without any need for additional cosmetics.

This tutorial is intended for providing you a full-fledged example for registering employees, in which an initial page will be displayed for employee’s information gathering. Once the user has submitted the form the employee registration will start and the confirmation message will be displayed too.

Project Structure

This figure below should help you recognize one of the best location for putting your Groovy classes as well as showing you the different accompanies files for the project.

Groovy Portlet - Project Structure

Employee Table

As being we have a registration employee form, let’s look at the form of the Employee Table and its relevant columns.

Employee Table

As also, you can use below SQL create statement to get Employee Table created into your Schema.

employee.sql


CREATE TABLE `employee` (
  `EMP_ID` int(11) NOT NULL AUTO_INCREMENT,
  `EMP_NAME` varchar(45) DEFAULT NULL,
  `EMP_JOB` varchar(45) DEFAULT NULL,
  `EMP_SALARY` int(11) DEFAULT NULL,
  PRIMARY KEY (`EMP_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

Employee Model

In the MVC design pattern and according for the concept of Separation of Concern, we must have an Employee Model that it takes the form of:

Employee.java


package com.journaldev.data;

public class Employee {
	private int id;
	private String name;
	private String job;
	private int salary;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}
}

This model will hold the data that’s going back and forth between the different components defined in the application.

Install Groovy Plugin Into Your Eclipse

To make sure you’re able of getting Groovy sources inside your Maven project, you must install Eclipse Groovy Plugin into your Eclipse IDE.

Installing of Eclipse Plugin wouldn’t take much time as you can do that by using the Eclipse install new software facility.

  • From help menu, choose Install New Software.
  • Paste copied link into Work with input and waiting until Eclipse show you the listed supposed updates that plugin contains.
  • Select Groovy-Eclipse (Required) & Click next.
  • Proceed until your eclipse has installed the Groovy Plugin and restart your Eclipse to make sure your installed Plugin takes effect.

Install Groovy Plugin

  • Now, from your Maven Project (That you’ve created before), create a Groovy class normally.

Create Groovy Class

RegisterEmployeePortlet Groovy Portlet

RegisterEmployeePortlet will be built using the same manner that’s happened inside our introduced JSP & Servlet example. One major difference that it’s now a Groovy class, where no need for a package declaration nor for a variable types.

You may write a code analogous for what you’ve written inside your RegisterEmployeePortlet Java class, but for make a distinction we removed those optional constructs that Groovy doesn’t require.

RegisterEmployeePortlet.groovy



import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class RegisterEmployeePortlet extends GenericPortlet{

	public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
		if(request.getParameter("status") == null){
			// Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/registerEmployee.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("initiate")){
			// Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/registerEmployee.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("success")){
			// Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/success.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("failed")){
			// Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/failure.jsp");
			request.setAttribute("exception", request.getParameter("exception"));
			dispatcher.include(request, response);
		}		

	}

	public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException{
		// Create request dispatcher
		def dispatcher =  this.getPortletContext().getNamedDispatcher("RegisterEmployeeServlet");
		try {
			// Include
			dispatcher.include(request, response);
			// Set render parameter
			response.setRenderParameter("status", "success");
		}
		catch(Exception ex){
			// Set render parameter
			response.setRenderParameter("status", "failed");
			response.setRenderParameter("exception", ex.getMessage());
		}

	}
}

Here’s detailed explanation for the code mentioned above:

  • RegisterEmployeePortlet Groovy class doesn’t reference a package, as it’s contained inside your resources in the Project Structure above.
  • Groovy is a dynamic language, and so, it’s applicable for you to miss out in the variable types. Alternatively, you must use a def keyword and the Groovy engine would expect the type of the variable from the context.
  • Groovy class is also able of accessing any defined Servlet inside your application.

RegisterEmployeePortlet Groovy Portlet Descriptor

As you’ve already used a Groovy class for creating a Portlet to be consumed by Apache Pluto, you know that the Portlet must be mentioned in the Portlet deployment descriptor (Portlet.xml).

The definition of Groovy Portlet inside your Portlet descriptor is little bit different as it’s also contained for additional detailes you must be aware of. Let’s first look at the Portlet.xml and see what are the major differences.

portlet.xml


<?xml version="1.0" encoding="UTF-8"?>

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
	version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
	<portlet id="RegisterEmployee">
		<display-name>Register Employee</display-name>
		<portlet-name>RegisterEmployee</portlet-name>
		<portlet-class>org.apache.portals.bridges.groovy.GroovyPortlet</portlet-class>
		<init-param>
			<name>script-source</name>
			<value>classpath:RegisterEmployeePortlet.groovy</value>
		</init-param>
		<init-param>
			<name>auto-refresh</name>
			<value>true</value>
		</init-param>
		<description>Employee Registration</description>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>VIEW</portlet-mode>
		</supports>
		<portlet-info>
			<title>Employee Registration</title>
			<keywords>employee, registration</keywords>
			<short-title>Employee Registration</short-title>
		</portlet-info>
	</portlet>
</portlet-app>

Here’s detailed explanation for the code mentioned above:

  • Your Groovy Portlet should be of org.apache.portals.bridge.groovy.GroovyPortlet class.
  • You must provide the script-source which will be used later on for specifying the Groovy class that’s responsible of handling the initiated Portlet request.
  • You have the ability of providing an optional auto-refresh parameter for enabling applying your modifications instantly. So, just make your modification and refresh the Portlet to get it executed directly.
  • Script-source parameter accepts different types of paths; full physical file, url, uri or by using the reserved keyword classpath as be shown.

Application Deployment Descriptor & Maven Build File

There is no any change on the web deployment descriptor, the same file is used as it’s defined in the JSP & Servlet Tutorial.

web.xml


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Employee Registration</display-name>
  <servlet>
  	<servlet-class>com.journaldev.servlet.RegisterEmployeeServlet</servlet-class>
  	<servlet-name>RegisterEmployeeServlet</servlet-name>
  </servlet>
  <servlet-mapping>
  	<servlet-name>RegisterEmployeeServlet</servlet-name>
  	<url-pattern>/registerEmployeeServlet</url-pattern>
  </servlet-mapping>
  <taglib>
  	<taglib-uri>http://java.sun.com/portlet</taglib-uri>
  	<taglib-location>/WEB-INF/portlet.tld</taglib-location>
  </taglib>
</web-app>

Just note that Apache Pluto assemble plugin will add some fragments into your web.xml while it builds the application for making the Portlet accessible.

At the other hand, the all required dependencies are maintained by the Maven build file, look below at the used pom.xml.

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev</groupId>
	<artifactId>GroovyBridge</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>GroovyBridge</name>
	<url>http://maven.apache.org</url>
	<properties>
		<deployFolder>D:/Apache Pluto/pluto-2.0.3/webapps</deployFolder>
	</properties>
	<dependencies>
		<!-- Java Portlet Specification V2.0 -->
		<dependency>
			<groupId>org.apache.portals</groupId>
			<artifactId>portlet-api_2.0_spec</artifactId>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.4</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>org.apache.pluto</groupId>
			<artifactId>pluto-taglib</artifactId>
			<version>1.1.7</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.groovy</groupId>
			<artifactId>groovy</artifactId>
			<version>1.1-rc-2</version>
		</dependency>
		<dependency>
			<groupId>antlr</groupId>
			<artifactId>antlr</artifactId>
			<version>2.7.6</version>
		</dependency>
		<dependency>
			<groupId>asm</groupId>
			<artifactId>asm</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.portals.bridges</groupId>
			<artifactId>portals-bridges-groovy</artifactId>
			<version>1.0.4</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.portals.jetspeed-2</groupId>
					<artifactId>jetspeed-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
	<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>
			<!-- bind 'pluto2:assemble' goal to 'process-resources' lifecycle -->
			<!-- This plugin will read your portlet.xml and web.xml and injects required
				lines -->
			<plugin>
				<groupId>org.apache.portals.pluto</groupId>
				<artifactId>maven-pluto-plugin</artifactId>
				<version>2.1.0-M3</version>
				<executions>
					<execution>
						<phase>generate-resources</phase>
						<goals>
							<goal>assemble</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<!-- configure maven-war-plugin to use updated web.xml -->
			<!-- This plugin will make sure your WAR will contain the updated web.xml -->
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-antrun-plugin</artifactId>
				<executions>
					<execution>
						<id>copy</id>
						<phase>integration-test</phase>
						<configuration>
							<tasks>
								<copy file="target/${project.artifactId}.war" tofile="${deployFolder}/${project.artifactId}.war" />
							</tasks>
						</configuration>
						<goals>
							<goal>run</goal>
						</goals>
					</execution>
					<execution>
						<id>delete</id>
						<phase>clean</phase>
						<configuration>
							<tasks>
								<delete file="${deployFolder}/${project.artifactId}.war" />
								<delete dir="${deployFolder}/${project.artifactId}" />
							</tasks>
							<detail>true</detail>
						</configuration>
						<goals>
							<goal>run</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

EmployeeDAO & ConnectionUtility – Database Handling

EmployeeDAO.java


package com.journaldev.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.journaldev.dao.utility.ConnectionUtility;
import com.journaldev.data.Employee;

public class EmployeeDAO {

	public static EmployeeDAO employeeDAO = null;

	private EmployeeDAO(){

	}

	public static EmployeeDAO getInstance(){
		synchronized(EmployeeDAO.class){
			if(employeeDAO == null){
				employeeDAO = new EmployeeDAO();
			}

		}
		return employeeDAO;
	}

	public Employee createEmployee(Employee employee) throws SQLException, IllegalAccessException, IOException, ClassNotFoundException{
		// Get connection instance
		Connection connection = ConnectionUtility.getInstance().getConnection();
		// Create Prepared Statement
		PreparedStatement query = connection.prepareStatement("INSERT INTO EMPLOYEE VALUES (?,?,?,?)");
		// Set variables
		query.setInt(1, employee.getId());
		query.setString(2, employee.getName());
		query.setString(3, employee.getJob());
		query.setInt(4, employee.getSalary());

		try {
			// Execute
			query.execute();
			// Return employee instance
			return employee;
		}
		catch(Exception e){
			// Close statement
			query.close();
			// Close connection
			connection.close();
			// Throw another exception for notifying the Servlet
			throw new SQLException(e);
		}
	}

	public boolean deleteEmployee(Employee employee){
		return false;
	}

	public boolean updateEmployee(Employee employee, int employeeId){
		return false;
	}
}

ConnectionUtility.java


package com.journaldev.dao.utility;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class ConnectionUtility {

	private static ConnectionUtility connectionUtiliy = null;

	private Connection connection = null;

	private ConnectionUtility() {
	}

	public static ConnectionUtility getInstance() throws IOException, IllegalAccessException, SQLException, ClassNotFoundException{
		// Synchronized against connectionUtility instance
		synchronized(ConnectionUtility.class){
			// Check whether the connectionUtility is null or not
			if(connectionUtiliy == null){
				// Create a properties instance
				Properties properties = new Properties();
				// Load properties from classpath
				properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("connection.properties"));
				// Set connection with connectionUtility
				connectionUtiliy = new ConnectionUtility();
				// Load driver class
				Class.forName("com.mysql.jdbc.Driver");
				// Create connection
				connectionUtiliy.setConnection(DriverManager.getConnection("jdbc:mysql://localhost:3306/journaldev", properties));
			}
			return connectionUtiliy;
		}
	}

	public Connection getConnection() throws ClassNotFoundException, SQLException, IOException {
		if(connection.isClosed()){
			// Create a properties instance
			Properties properties = new Properties();
			// Load properties from classpath
			properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("connection.properties"));
			// Load driver class
			Class.forName("com.mysql.jdbc.Driver");
			// Create connection
			connectionUtiliy.setConnection(DriverManager.getConnection("jdbc:mysql://localhost:3306/journaldev", properties));
		}
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

}

RegisterEmployeeServlet – Business Handling

If you have noticed that the Groovy class hasn’t provided any code relevant for the registration process, on the contrary, it’s used mainly for handling the required business delegation and the actual work of employee registration got defined inside our RegisterEmployeeServlet, that’s applying the concept of Separation of concern (Soc). Look at below:

RegisterEmployeeServlet.java


package com.journaldev.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.journaldev.dao.EmployeeDAO;
import com.journaldev.data.Employee;

public class RegisterEmployeeServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	Logger logger = Logger.getLogger(RegisterEmployeeServlet.class);

    public RegisterEmployeeServlet() {
        super();
    }

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// Create employee
		Employee employee = new Employee();
		// Fill in required data from the request sent
		employee.setId(Integer.parseInt(request.getParameter("employeeID")));
		employee.setName(request.getParameter("employeeName"));
		employee.setJob(request.getParameter("employeeJob"));
		employee.setSalary(Integer.parseInt(request.getParameter("employeeSalary")));
		try {
			// Asking employeeDAO creating the employee against registered database
			Employee createdEmployee = EmployeeDAO.getInstance().createEmployee(employee);
			// Print out the created employee information
			logger.info("Employee Created"+createdEmployee);
		} catch (Exception e) {
			// Log the exception
			logger.error("Employee Creation Failed", e);
			// Throw another exception for notifying the Portlet
			throw new ServletException(e);
		}
	}

}

JSP Views

As you’ve noticed above, your Groovy Portlet has delegated the control into three different JSP pages:

registerEmployee.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='http://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
<body>
	<portlet:actionURL var="registerLink"/>
	<form action="<%=registerLink%>" method="POST">
		<table width="100%">
			<tr width="60%">
				<td>Enter Employee ID:</td>
				<td><input name="employeeID" /></td>
			</tr>		
			<tr width="60%">
				<td>Enter Employee Name:</td>
				<td><input name="employeeName" /></td>
			</tr>
			<tr width="60%">
				<td>Enter Employee Job:</td>
				<td><input name="employeeJob" /></td>
			</tr>
			<tr width="60%">
				<td>Enter Employee Salary:</td>
				<td><input name="employeeSalary" /></td>
			</tr>
			<tr width="60%" align="center">
				<td colspan="2"><input type="submit" value="Register" /></td>
			</tr>
		</table>
	</form>
</body>
</html>

success.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='http://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
	<portlet:renderURL var="registerAnother">
		<portlet:param name="status" value="initiate"/>
	</portlet:renderURL>
	<img src="<%=request.getContextPath()%>/images/success.jpg" name="<portlet:namespace/>Success"/>
	<body>
		<span>Congratulations ! you've just add a new employee</span><br/><a href="<%=registerAnother%>">Register Another</a>
	</body>
</html>

failure.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='http://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
	<portlet:defineObjects/>
	<portlet:renderURL var="registerAnother">
		<portlet:param name="status" value="initiate"/>
	</portlet:renderURL>
	<body>
		<span>Unfortunately ! you may not be able of registering a new employee cause the reason below</span>
		<br/>
		<br/>
		<img src="<%=request.getContextPath()%>/images/failed.jpg" name="<portlet:namespace/>Failed"/>
		<span style="font-size:small ;font-style: italic;color: red;font-weight: bold;">
			<%=renderRequest.getAttribute("exception")%>
		</span>
		<br/>
		<br/>
		<a href="<%=registerAnother%>">Try Again</a>
	</body>
</html>

Employee Registration Demo

Before getting started demonstrate the employee registration sample, you must have an installed instance of Apache Pluto as well as a JournalDev Portal page. If you didn’t create it before, you need to return back into Apache Pluto Introduction for getting everything done.

Groovy Portlet - Fill In Employee InfoGroovy Portlet - Success Registration

And you should be able of seeing a new Employee saved against your database:

Groovy Portlet - Database Record

And if you’ve tried to register the user with the same used ID, you should be able of seeing a message tells you the actual cause of error.

Groovy Portlet - Failed Registration

Summary

Groovy is a dynamic JVM language, it’s amazing as you don’t need to be aware of a lot of things you must be aware of when you’re going to use Java language. If you want a Portlet that provides you the maximum gauge of Dynamicity, choose the Groovy as you can change your classes while your JVM is running.

Contribute us by commenting below and find below downloaded source code for your practice.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages