tag handler ignored by the CDK
richajon Nov 27, 2007 12:05 PMHi
I am trying to wrap the suggestionBox into my own component that I create with the CDK.
I would like to be able to pass the suggestionAction="#{something.method()}" from my wrapper to the wrapped suggestionBox.
I looked at how the suggestionbox was created and replicated the TagHandler class and adapted it to use it with my own component. I added the "taghandler" tag in my xml configuration but the CDK seem to ignore it.
Therefore, the suggestionAction attribute of my component is not considered as a MethodBinding expression but a ValueExpression which is wrong.
Is there any other switch/configuration to change so it generates the proper taglib definition so my TagHandler is called?
Here's my xml configuration file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" "https://ajax4jsf.dev.java.net/nonav/dtds/component-config.dtd" > <components> <component> <name>org.mcgill.moxxi.ui.DropDownBox</name> <family>org.mcgill.moxxi.ui.DropDownBox</family> <classname>org.mcgill.moxxi.ui.component.html.HtmlDropDownBox</classname> <superclass>org.mcgill.moxxi.ui.component.UIDropDownBox</superclass> <description> <![CDATA[]]> </description> <renderer generate="false" override="false"> <name>org.mcgill.moxxi.ui.DropDownBox</name> <classname>org.mcgill.moxxi.ui.renderkit.html.DropDownBoxRenderer</classname> </renderer> <tag> <name>dropDownBox</name> <classname>org.mcgill.moxxi.ui.taglib.DropDownBoxTag</classname> <superclass> org.ajax4jsf.webapp.taglib.HtmlComponentTagBase </superclass> </tag> <taghandler> <classname> org.mcgill.moxxi.ui.taglib.DropDownBoxTagHandler </classname> </taghandler> &ui_component_attributes; <property> <name>var</name> <classname>java.lang.String</classname> <description> A request-scope attribute under which the data object for the current row is exposed when iterating </description> </property> <property elonly="true"> <name>suggestionAction</name> <classname>javax.faces.el.MethodBinding</classname> <methodargs> java.lang.Object.class </methodargs> <description> <![CDATA[Method calls an expression to get a collection of suggestion data on request. It must have one parameter with a type of Object with content of input component and must return any type allowed for <h:datatable> ]]> </description> </property> </component> </components>
And the generated facelet taglib descriptor looks like this:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> <facelet-taglib xmlns="http://java.sun.com/JSF/Facelet"> <namespace>http://moxxi.mcgill.org/moxxi-ui</namespace> <tag> <tag-name>defaultAction</tag-name> <component> <component-type>org.mcgill.moxxi.ui.DefaultAction</component-type> <renderer-type>org.mcgill.moxxi.ui.DefaultActionRenderer</renderer-type> </component> </tag> <tag> <tag-name>dropDownBox</tag-name> <component> <component-type>org.mcgill.moxxi.ui.DropDownBox</component-type> <renderer-type>org.mcgill.moxxi.ui.DropDownBox</renderer-type> </component> </tag> </facelet-taglib>
It should be something like this (suggestionbox):
... <tag-name>suggestionbox</tag-name> <component> <component-type>org.richfaces.SuggestionBox</component-type> <renderer-type> org.richfaces.SuggestionBox </renderer-type> <handler-class> org.richfaces.taglib.SuggestionBoxTagHandler </handler-class> </component> ...
And finally, my TagHandler class:
public class DropDownBoxTagHandler extends com.sun.facelets.tag.jsf.ComponentHandler { /** * Meta rule for tag handler. */ private static final DropDownBoxTagHandlerMetaRule metaRule = new DropDownBoxTagHandlerMetaRule(); /** * Constructor. * * @param config {@link com.sun.facelets.tag.jsf.ComponentConfig} */ public DropDownBoxTagHandler(final ComponentConfig config) { super(config); } /** * Creates metarules. * * @param type Class * @return {@link com.sun.facelets.tag.MetaRuleset} */ protected final MetaRuleset createMetaRuleset(final Class type) { MetaRuleset m = super.createMetaRuleset(type); m.addRule(metaRule); return m; } /** * Meta rule implementation. * * @author shura (latest modification by $Author: ishabalov $) * @version $Revision: 1.1.2.4 $ $Date: 2007/02/20 20:58:03 $ */ static class DropDownBoxTagHandlerMetaRule extends MetaRule { /** * Apply rule. * * @param name rule name * @param attribute {@link com.sun.facelets.tag.TagAttribute} * @param meta {@link com.sun.facelets.tag.TagAttribute} * @return metadata {@link com.sun.facelets.tag.Metadata} * * @see {@link com.sun.facelets.tag.MetaRule#applyRule(String, * com.sun.facelets.tag.TagAttribute, * com.sun.facelets.tag.MetadataTarget)} */ public Metadata applyRule(final String name, final TagAttribute attribute, final MetadataTarget meta) { if (meta.isTargetInstanceOf(UIDropDownBox.class)) { if ("suggestionAction".equals(name)) { return new DropDownBoxActionMapper(attribute); } } return null; } } /** * Meta data implementation. */ static class DropDownBoxActionMapper extends Metadata { /** * Signature. */ private static final Class[] SIGNATURE = new Class[]{java.lang.Object.class}; /** * Action attribute. */ private final TagAttribute action; /** * Sets attribute. * * @param attribute {@link com.sun.facelets.tag.TagAttribute} */ public DropDownBoxActionMapper(final TagAttribute attribute) { action = attribute; } /** * Apply metadata. * @param context {@link javax.faces.context.FacesContext} * @param instance {@link java.lang.Object} * * @see {@link com.sun.facelets.tag.Metadata#applyMetadata( * com.sun.facelets.FaceletContext, Object)} */ public void applyMetadata(final FaceletContext context, final Object instance) { ((UIDropDownBox) instance) .setSuggestionAction(new LegacyMethodBinding(this.action .getMethodExpression(context, null, SIGNATURE))); } } }