1 Reply Latest reply on Nov 27, 2007 3:32 PM by richajon

    tag handler ignored by the CDK

      Hi

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