About Martin Mois

Martin is a Java EE enthusiast and works for an international operating company. He is interested in clean code and the software craftsmanship approach. He also strongly believes in automated testing and continuous integration.

Implementing a custom JSF 2.0 component with maven

Some time ago, I have written my own custom JSF component. But at that point in time, JSF 1.0 was still up to date and the project didn’t use maven as build system. Thus, I always wanted to write a custom JSF2 component with maven. So let’s start:

First of all we setup a maven project with two modules. Here is the pom.xml file of the parent project:
 
 
 
 
 

<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>martins-developer-world</groupId>
	<artifactId>jsf-component</artifactId>
	<packaging>pom</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>jsf-component Maven Webapp</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>jsf-component</finalName>
	</build>
	<modules>
		<module>jsf-component-webapp</module>
		<module>jsf-component-impl</module>
	</modules>
</project>

As you can see, we have added the JSF dependencies in the top level pom.xml, so that we inherit them in the child modules. As we will use the JBoss Application Server to test our web application, we have to set the scope for the maven dependencies to provided, so that our war file and our component jar won’t deploy them. The implementation of our component will reside in jsf-component-impl, thus we chose jar as packaging type for this module:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>martins-developer-world</groupId>
		<artifactId>jsf-component</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>jsf-component-impl</artifactId>
	<name>jsf-component-impl</name>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
	</dependencies>
</project>

Now let’s implement a Java class that extends UIOutput. I have chosen UIOutput because as a first step I just want to implement a simple helloWorld tag, that prints the first and last name given as attribute within a span element. As this component doesn’t receive any input, UIOutput it appropriate:

package martins.developer.world.jsf.component.impl;

import java.io.IOException;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

@ResourceDependencies({ @ResourceDependency(name = "css/jsf-component.css", target = "head") })
@FacesComponent("HelloWorld")
public class HelloWorldComponent extends UIOutput {
	private static final String COMPONENT_FAMILY = "martins.developer.world.jsf.component.helloWorld";

	private enum PropertyKeys {
		firstName, lastName
	};

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}

	@Override
	public void encodeBegin(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement("span", this);
		writer.writeAttribute("class", "helloWorldClass", "");
		writer.writeText(String.format("Hello %s %s!", getFirstName(), getLastName()), "");
		writer.endElement("span");
	}

	public String getFirstName() {
		return (String) getStateHelper().eval(PropertyKeys.firstName, "???firstName???");
	}

	public void setFirstName(String firstName) {
		getStateHelper().put(PropertyKeys.firstName, firstName);
	}

	public String getLastName() {
		return (String) getStateHelper().eval(PropertyKeys.lastName, "???lastName???");
	}

	public void setLastName(String lastName) {
		getStateHelper().put(PropertyKeys.lastName, lastName);
	}
}

The getFamily() method is the only method that we are enforced to implement. Interesting is here the method encodeBegin(). This is the place where we implement our span tag. As it should have a CSS class attribute, we add it with the writeAttribute() method of the Writer. The two attributes of the resulting JSF tag are modelled as simple properties with getter and setter methods. The implementation of these getters and setters uses the StateHelper available in JSF 2.0. In encodeBegin() we use the getters to retrieve the value given by the user.

Interesting is also the annotation @ResourceDependencies. With this annotation we can tell the JSF framework that we have some files we depend on. In this case it is a CSS file that resides with the folder src/main/resources/META-INF/resources/css.
The annotation @FacesComponent registers this component in the boot process at the JSF framework. The given name is used in the taglib file to reference this class:

<?xml version="1.0"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee">
	<namespace>http://martinsdeveloperworld.wordpress.com</namespace>
	<tag>
		<tag-name>helloWorld</tag-name>
		<component>
			<component-type>HelloWorld</component-type>
		</component>
	</tag>
</facelet-taglib>

In this taglib file under src/main/resources/META-INF we define the available components, here only our helloWorld tag. The attributes of the tag are derived from the properties of the Java class.

Finally we want to test our newly created component. To be able to do this, we setup a simple JSF2 webapp project and add the following snippet to the web.xml, in order to declare that we want to use our custom component:

<context-param>
		<param-name>facelets.FACELETS_LIBRARIES</param-name>
		<param-value>/META-INF/jsf-component.taglib.xml</param-value>
	</context-param>

Now we can write a simple JSF page that references our new tag:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:mdw="http://martinsdeveloperworld.wordpress.com">
<h:head>
<title>Hello JSF 2!</title>
</h:head>
<h:body>
	<h2>Hello World!</h2>
	<mdw:helloWorld firstName="Martin" lastName="Developer"/>
</h:body>
</html>

When we deploy this application to the JBoss Application Server and call the corresponding URL, we get the following HTML output:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Hello JSF 2!</title>
	<link type="text/css" rel="stylesheet" href="/jsf-component-webapp/faces/javax.faces.resource/css/jsf-component.css" />
</head>
<body>
	<h2>Hello World!</h2>
	<span class="helloWorldClass">Hello Martin Developer!</span>
</body>
</html>

Clearly we can see the span tag with the CSS class and the output. The CSS file is referenced in the head of the HTML document.

 

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


nine × = 54



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books
Get tutored by the Geeks! JCG Academy is a fact... Join Now
Hello. Add your message here.