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)));
}
}
}