You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
This article deals with taking a jar with static utility methods and adding those methods to be available for use in EL. I will use commons-lang as an example, but any utility library will work here.
In the WebContent/META-INF/ (JBDS) or view/META-INF/ (seam-gen) create a file called elfunctions.taglib.xml. If the META-INF/ dir does not exist, create it also. The content of elfunctions.taglib.xml should be:
<?xml version="1.0"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd"> <facelet-taglib> <library-class>org.el.func.FnLibrary</library-class> </facelet-taglib>
Download Apache Commons - Lang from http://commons.apache.org/downloads/download_lang.cgi and add commons-lang-<version>.jar to the WEB-INF/lib in JBDS (just drag it in, everything else is automatic) or with seam-gen add it to the PROJECT_HOME/lib dir and define it in the deployed-jars-war.list file.
Create another src package src/facelets with the packagename: org.el.func and add
package org.el.func; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.commons.lang.StringUtils; import com.sun.facelets.tag.AbstractTagLibrary; public class FnLibrary extends AbstractTagLibrary { public final static String Namespace = "http://org.el.func/SeamFunc"; public static final FnLibrary INSTANCE = new FnLibrary(); public FnLibrary() { super(Namespace); try { Method[] methods = StringUtils.class.getMethods(); for (int i = 0; i < methods.length; i++) { if (Modifier.isStatic(methods[i].getModifiers())) { this.addFunction(methods[i].getName(), methods[i]); } } } catch (Exception e) { throw new RuntimeException(e); } } }
The above will dynamically add all of the static methods in StringUtils to Facelets which are all available now via EL.
Now the last piece is to define the location of the elfunctions.taglib.xml in web.xml:
<context-param> <param-name>facelets.LIBRARIES</param-name> <param-value> /META-INF/elfunctions.taglib.xml </param-value> </context-param>
Create a test.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:e="http://org.el.func/SeamFunc" template="layout/template.xhtml"> <ui:define name="body"> #{e:capitalize('capitalize me')} / #{e:contains('dog', 'd')} / #{e:contains('dog', 'z')} </ui:define> </ui:composition>
Which results in the output:
Capitalize me / true / false
Now lets add more methods from the commons-lang, we'll do RandomUtils next. All we need to do is modify the FnLibrary to add the methods, everything else at this point happens behind the scenes.
package org.el.func; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.commons.lang.StringUtils; import com.sun.facelets.tag.AbstractTagLibrary; public class FnLibrary extends AbstractTagLibrary { public final static String Namespace = "http://org.el.func/SeamFunc"; public static final FnLibrary INSTANCE = new FnLibrary(); public FnLibrary() { super(Namespace); try { Method[] methods = StringUtils.class.getMethods(); for (int i = 0; i < methods.length; i++) { if (Modifier.isStatic(methods[i].getModifiers())) { this.addFunction(methods[i].getName(), methods[i]); } } methods = RandomUtils.class.getMethods(); for (int i = 0; i < methods.length; i++) { if (Modifier.isStatic(methods[i].getModifiers())) { this.addFunction(methods[i].getName(), methods[i]); } } } catch (Exception e) { throw new RuntimeException(e); } } }
test.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:e="http://org.el.func/SeamFunc" template="layout/template.xhtml"> <ui:define name="body"> #{e:isNumber('100')} / #{e:min(99, 33, 98)} </ui:define> </ui:composition>
Produces the output:
true / 33.0