Creating a custom JSF 2.
0 taglib
Jonas Freiknecht, 2012 Karlsruhe
www.jofre.de
Abstract To create custom JSF components is pretty easy but it definitely lac s documentation. $e be"in with a simple introduction tion to the two inds of components) 1. Composite Components are assembled from existin" JSF components and consist to a hu"e extend of XHTML code. 2. Classic Components are written in Ja!a and supported by the stron" JSF annotation framewor . Their ad!anta"e is that + once they are compiled + their source code is i hidden. Focusin" on classic components# this tutorial will show how to write and pac a"e them th into a J,- so that they can be used in any other JSF project.
1. Project setup
$e need a %ynamic $eb &roject roject to test the component and a basic Ja!a &roject to create the ta"lib. 'n illustration ( VisualFaces is the Ja!a &roject and VisualFacesImpl is our test project.
Illustration 1: Project setup
' already added the three necessary components) (. 'n the source folder ' created a component component that is discussed in the followin" chapter. *. The META-INF directory that contains two essential e files) a. The faces-config.xml config.xml shows that the J,- has to be re"arded ded as bein" interestin" for the JSF runtime.
b. The visualfaces.taglib.xml exports all components that are offered by the ta"lib(. &lease create the META-INF directory as well as the file faces-config.xml and copy . paste the code from listin" (.
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/ !"#chema-$nstance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee% http://java.sun.com/xml/ns/javaee/we&-'acescon'$g(2(0.xs)" version="2.0"> </faces-config>
Listing 1: faces-config.xml
2. Writing a component in Java
/reate a pac a"e i.e. de.jofre.visual.diagrams.test# add a class called TestComp and paste the followin" code.
@FacesComponent( !estComp " public class !estComp extends #$Component%ase & @'verride public (tring getFamil)(" & return *ofre+vis,al+diagrams .
@'verride public void encode%egin(FacesContext context" throws $'/xception & if (context == null" & throw new 0,ll1ointer/xception(". (tring str2sg = ((tring"get3ttri4,tes("+get( msg "5esponse6riter 7riter = context+get5esponse6riter("7riter+start/lement( p 8 this"7riter+7rite!ext( !his is a test: 9str2sg8 null". @'verride public void encode/nd(FacesContext context" throws $'/xception & if (context == null" & throw new 0,ll1ointer/xception(". 5esponse6riter 7riter = context+get5esponse6riter("7riter+end/lement( p ". .
Listing : T!e component TestComp
(
To ma e the JSF runtime reco"ni0e a ta"lib as such the file name has to end with 1.ta"lib.xml1. The be"innin" does not matter.
To be able to use the annotation FacesContext you will ha!e to add a JSF Library. Therefore# simply enable the JSF facet for your %ynamic $eb &roject VisualFacesImpl. 2clipse will automatically as you to download the necessary libraries 3if you ha!e not done it so far4. The let 2clipse fix your project imports 3by clic in" on the lamp next to the FacesContext error4 and add the downloaded library. ,ccordin" to the faces-confix.xml in listin" (# you should choose a JSF *.5 implementation. The source code is simple. $e create a component called TestComp which extends the !ery basic component "IComponent#ase. 6ou now ha!e to implement the get$amil% method which returns a strin" containin" the name of the component family. 'n this case it is called jofre.visual.diagrams because the component is supposed to be a part of a !isuali0ation framewor . The two methods encode#egin and encode&nd are called while the JSF component is rendered. 'n this case# we re7uest the content of an attribute called msg and write it to the strin" str'sg. The response(riter is responsible for writin" the finished HTML8code. He opens a ta" p and adds the content of the msg attribute includin" a dumb prefix to see if the messa"e is drawn e!en if str'sg is empty. encode&nd simply closes the opened p ta" and we are done here.
3. Registering the component in the visualfaces.taglib.xml
9ow# we create the file visualfaces.taglib.xml in the '&TA-I)$ directory.
<facelet-tagli4 version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/ !"#chema-$nstance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee% http://java.sun.com/xml/ns/javaee/we&-'acelettagl$&rar*(2(0.xs)"> <namespace>http://777+*ofre+de/vis,alfaces</namespace> <composite-li4rar)-name>vis,alfaces</composite-li4rar)-name> <tag> <tag-name>testcomp</tag-name> <component> <component-t)pe>!estComp</component-t)pe> </component> </tag> </facelet-tagli4>
Listing *: visualfaces.taglib.xml
The final content is shown in listin" :. The namespace is important because it is used later on to reference the ta"lib. 2!erytin" embraced by the tag ta" defines a new component. 'n this case its name is testcomp. This name is used to reference it at the end in the XHTML pa"es. The component-t%pe ta" tells which ja!a class should be ta en to construct the component. The name TestComp is the name that is used in the @FacesContext annotation.
4. Exporting an using the component
9ow that the component is written it has to be pac a"ed as a J,-. -i"ht clic the project and select &xport+ ,ar file and sa!e it locally 3i.e. as visualfaces.jar4. Then dra" . drop the J,- to the (&#I)$-lib folder in the %ynamic $eb &roject. The taglib should be identified as such and the components inside can now be used.
/reate an index.x!tml in the (ebContent folder and add a namespace reference and a ta" to test the component as shown in listin" ;.
<:;'C!<1/ html 1#%L$C -//6=C//;!; //6=C//;!; >?!2L @+A !ransitional///0 http://777+7=+org/!5/xhtml@/;!;/xhtml@ http://777+7=+org/!5/xhtml@/;!;/xhtml@-transitional+dtd > <html xmlns="http://www.w3.org/1+++/xhtml" xmlns:,i="http://java.sun.com/js'/'acelets" xmlns:h="http://java.sun.com/js'/html" xmlns:*="http://www.jo're.)e/v$sual'aces" xmlns:f="http://java.sun.com/js'/core"> <4od)> <*:testcomp msg="as)" /> </4od)> </html>
Listing .: : Adding t!e component to index.x!tml
The namespace http)<<www.jofre.de<!isualfaces as defined in the visualfaces.taglib.xml taglib.xml is now used and mapped to the prefix j. =ia this th reference you can now add the testcomp and furthermore add the attribute msg. The hi"hly interestin" output can be seen in illustration *.
Illustration : T!e rendered output of t!e testcomp
'f you are uncertain about the structure of the %ynamic $eb &roject you can ha!e a loo at illustration :. visualfaces.jar is the export of the library we just created.
Illustration *: : /tructure of t!e 0%namic (eb Project to test t!e component