Using Facelets TagHandlers and Adding multiple listeners

ComponentHandler, HtmlComponentHandler, or TagHandler. So I think I finally have a handle on what each of these are used for. Okay the first 2 are easy, HtmlComponentHandler extends ComponentHandler. But what is a MetaRuleset and what can it do for my components? It looks to mee like it is just a method binding passthrough for the component when you call MetaRuleset.addRule(typeTagRule);?

TagHandler ended up saving the day for me, and after spending hours/days trying to get the first 2 to do what I was wanting, this one took me like 5 minutes. I was trying to add a handler to a component which turned out to be the wrong thing to do in facelets. Now, All one has to do is declare a tag in the *taglib.xml file and point it to the new handler class (as explained on Facelets docs).

    <tag> 
        <tag-name>sliderListener</tag-name> 
        <handler-class>com.halesconsulting.web.jsf.handler.SliderTagHandler</handler-class> 
    </tag> 

Next is defining the required and not-required attributes for your tag in the class.

  private final TagAttribute test; 
  private final TagAttribute var; 
  public SliderTagHandler(TagConfig config) { 
      super(config); 
 
      // helper method for getting a required attribute 
      this.test = this.getRequiredAttribute("type"); 

 
      // helper method 
      this.var = this.getAttribute("var"); 
  } 

Next, in the apply method, I was able to get this tags parent component instance (just like in JSP component development where you call UIComponentTag tag = UIComponentTag.getParentUIComponentTag(pageContext); It took me a while to figure out where I needed to do this, but after this worked, you should have seen the excitement! Nothing like figuring shit out on your own when no documentation could be found on what you are trying to do!

I had to add a HashMap to keep track of what listeners had already been added. Otherwise, each render added a new listener...

  /** 

   * Threadsafe Method for controlling evaluation of 
   * its child tags, represented by "nextHandler" 
   */ 
  public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, ELException { 
 
      boolean b = this.test.getBoolean(ctx); 

 
      if (!addedMap.containsKey(test.getValue())){ 
          SliderSource sliderSource = (SliderSource)parent; 
          SliderListener listener = createSliderListener(test.getValue()); 
          addedMap.put(test.getValue(),true); 
          sliderSource.addSliderListener(listener); 
      } 
       

      if (this.var != null) { 
          ctx.setAttribute(var.getValue(ctx), new Boolean(b)); 
      } 
      if (b) { 
          this.nextHandler.apply(ctx, parent); 

      } 
  } 

I still need to do a little more digging on the details of the nextHandler stuff. But I was happy to get it working the "right way"