Вы находитесь на странице: 1из 13

JSF Custom Tags

Mehmet Nacar

Custom Tags
There should be two classes implemented. The one is end with Tag suffix by convention
That process tag attributes eg. OGCECommandButtonTag Inherited from UIComponentTag

The other starts with UI prefix.

eg. IUOgceCommand A component class maintain state Renders a user interface Processes input values.

Command Button
You need to set up JSTL taglib to support new tags. These jar files needed below.
jsf-api.jar jsf-impl.jar jstl.jar standard.jar

There should be a custom .tld file on the path

Such as WEB-INF/tld/command.tld

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>o</short-name> <uri>http://www.ogce.org/</uri> <tag> <name>MyCommandButton</name> <tag-class>ogce.OGCECommandButtonTag</tag-class> <body-content>JSP</body-content> <attribute> <name>id</name> </attribute> <attribute> <name>value</name> </attribute> <attribute> <name>action</name> </attribute> </tag> <tag> <name>MyActionSet</name> <tag-class>ogce.OGCEActionSetTag</tag-class> <body-content>JSP</body-content> <attribute> <name>id</name> </attribute> <attribute> <name>processor</name> </attribute> </tag> </taglib>

You need to modify web.xml to provide new taglib <web-app> <taglib> <taglib-uri>http://www.ogce.org/</taglib-uri> <taglib-location> /WEB-INF/tld/command.tld</taglib-location> </taglib>


You need to specify new components in faces-config.xml <component> <component-type>MyCommandButton</component-type> <component-class>ogce.OGCECommandButton</componentclass> </component> <component> <component-type>MyActionSet</component-type> <component-class>ogce.OGCEActionSet</component-class> </component>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://www.ogce.org/" prefix="o" %> <html> <head> <title>Show Custom Component</title> </head> <body> <f:view> <o:MyCommandButton id="my" value="Run" action="#{OGCEBean.nextPage}" > <o:MyActionSet id="act" processor="karajan" /> </o:MyCommandButton> </f:view> </body> </html>

OGCE command button tag has two attributes correspond to properties in tag class. public class OGCECommandButtonTag extends UIComponentTag { String value; String action; These properties has setter/getter methods (getter methods if needed) release() method set these properties as null setProperties() method loads properties to components map or bind the values.

protected void setProperties(UIComponent component) { super.setProperties(component); if (value != null) component.getAttributes().put("value", value); UICommand command = null; try { command = (UICommand)component; } catch(ClassCastException cce) { throw new IllegalStateException("Component " + component.toString() + " not expected type. Expected: UICommand. Perhaps you're missing a tag?"); } if(action != null) if(isValueReference(action)) { javax.faces.el.MethodBinding vb = FacesContext.getCurrentInstance().getApplication().createMethodBinding(action, null); command.setAction(vb); } else { String outcome = action; javax.faces.el.MethodBinding vb = Util.createConstantMethodBinding(action); command.setAction(vb); } }

package ogce; import java.io.IOException; import javax.faces.component.*; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; public class OGCECommandButton extends UICommand { public OGCECommandButton() { setRendererType("javax.faces.Button"); }

public void encodeBegin(FacesContext context) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement("input", button); writer.writeAttribute("name", getClientId(context), "id"); writer.writeAttribute("type", "submit", "type"); String value = (String) getAttributes().get("value"); if (value != null) writer.writeAttribute("value", (Object) value, null); }
public void encodeEnd(FacesContext context) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.endElement("input"); } }

Binding Karajan
Binding can be performed by using Method binding. A backing bean method can take care of instantiating Karajan processor Also passing the child elements of the engine that is an arbitrary XML.

<ogce:commandButton id="Submit"> <ogce:actionSet processor="karajan"> <karajan:task id="task1"> .... </karajan:task> <karajan:task id="task2" depends="task1"> .... </karajan:task> </ogce:actionSet> </ogce:commandButton>

There is an online tutorial to develop custom tags
http://www.exadel.com/tutorial/jsf/HowToWrite YourOwnJSFComponents.pdf

J2EE Online tutorial is also helpful.

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/i ndex.html