In my last post I showed you how to combine the composite component
collapsiblePanel with a classic component to make it really self-contained and reusable. As a next step, it would be nice to have this component in a jar file. In this post I will take reusability to the next level and show you how to build a custom component library with JSF 2.
Basically, all we have to do is put the artefacts of our component in a jar file. In our case this would be the folder of the resource library
jsflive and the component class
First, we put class
CollapsiblePanel into the jar file. As the component is registered with
@FacesComponent no xml configuration is necessary. However, we still need an empty
faces-config.xml in the jar. JSF only scans for annotations in jar files having a
faces-config.xml. This file must be placed in the
META-INF folder with the name
faces-config.xml or a name ending with
.faces-config.xml. The following listing shows the empty config file.
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> </faces-config>
Second, we move the resource library
jsflive into the folder
/META-INF/resources in the jar file. With this step finished, the composite component can already be used. Put the jar in the classpath of your application and declare a prefix for namespace
http://java.sun.com/jsf/composite/jsflive. The following listing shows an example view.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:jl="http://java.sun.com/jsf/composite/jsflive"> <h:head> <title>JSFlive test page</title> </h:head> <h:body> <h:form id="form"> <jl:collapsiblePanel id="panel"> <f:facet name="header">Header</f:facet> <h:outputText value="Just some text."/> </jl:collapsiblePanel> </h:form> </h:body> </html>
As I talked about a custom component library in the beginning, our jar might one day be extended with classic components, converters or validators. For this case we need a taglib config file to define tags for those artefacts. With JSF 2 it is possible to import a composite component resource library into a taglib. All composite components in the library are then available under the namespace of the taglib.
For our example we simply create a taglib config with a namespace and the element
composite-library-name with the name of our resource library folder. The following listing shows the complete taglib configuration file.
<facelet-taglib version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"> <namespace>http://jsflive.at/taglib</namespace> <composite-library-name>jsflive</composite-library-name> </facelet-taglib>
JSF automatically loads taglib config files from jar files in the classpath on startup. All we have to do is give the file a name ending with
.taglib.xml and place it in the
With the above taglib config file we can change the namespace in the above example view to
The following figure shows the structure of the jar file for our component library.
Now that the jar file is finished you probably want to use the component library in your applications. All you have to do is put the jar file in the classpath and declare a prefix for the namespace.
The source code for the presented example can be found in the Github repository collapsible03.
Update: JSF 2.2 will provide a new and more flexible way to add tags for composite components to custom tag libraries. It will be possible to define tags for specific composite components coming from different resource libraries. See my post on composite components in taglibs with JSF 2.2 for further information.