You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Ali Ok <al...@aliok.com.tr> on 2010/05/18 00:41:20 UTC
Tag handler for custom Behavior (not ClientBehavior)
Hi,
I was playing with JSF2 behaviors and I wrote a new behavior (not
ClientBehavior). Problem I described here doesn't seem like a impl bug,
instead it seems like a missing thing in the spec to me.
Let me explain my structure first. I have two abstract stuff in
Behavior-side:
- "ByPassAttributeBehavior"
@FacesBehavior(value = "org.apache.myfaces.html5.ByPassAttributeBehavior")
public class ByPassAttributeBehavior extends *BehaviorBase*
....
- "ByPassAttributeBehaviorHolder" (which does not extend anything. it
would extend "BehaviorHolder", if it was existed)
public interface ByPassAttributeBehaviorHolder
....
And implementing component side (please note that I am using MyFaces builder
plugin):
- "AbstractByPassTestComponent"
@JSFComponent(name = "hx:bypassTest",
clazz = "tr.com.aliok.html5.bypassbehavior.BypassTestComponent",
tagClass = "tr.com.aliok.html5.component.ByPassTestTag")
public abstract class AbstractByPassTestComponent extends UIComponentBase
implements *ByPassAttributeBehaviorHolder*
{...
- "ByPassTestRenderer"
@JSFRenderer(
renderKitId = "HTML_BASIC",
family = "tr.com.aliok.html5.ByPassTest",
type = "tr.com.aliok.html5.ByPassTest")
public class ByPassTestRenderer extends Renderer
{...
Registration in ...taglib.xml:
<tag>
<tag-name>byPassAttributeBehavior</tag-name>
<behavior>
<behavior-id>org.apache.myfaces.html5.ByPassAttributeBehavior</behavior-id>
</behavior>
</tag>
At last, my usage:
<hx:bypassTest ...>
<hx:byPassAttributeBehavior .../>
</hx:bypassTest>
In this case, at
org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate#apply,
an exception is thrown if the parent is not a ClientBehaviorHolder or a
composite component.
...
I think I can solve this problem by writing a tag handler, but why not
supporting this feature without a tag handler just like ClientBehaviors?
We don't have to write tag handlers for "ClientBehavior"s, but this is not
the case for "Behavior"s. Seems like the problem is: there is no interface
like "BehaviorHolder". Thus the delegate BehaviorTagHandlerDelegate cannot
determine whether the parent is Behavior 'attachable', so it cannot attach
Behaviors to parent.
However, I couldn't understand why there is no interface like BehaviorHolder
and why we need to write a tag handler for a "Behavior" that doesn't extend
"ClientBehavior"? If something similar is discussed before, what was the
purpose of this decision?
I see that, we have "addClientBehavior" method in "ClientBehaviorHolder"
class. Behaviors are here to get attached, right? So, why this attaching
logic only pushed for 'ClientBehavior's?
Regards,
Ali
--
My Blog: http://blog.aliok.com.tr
Twitter: http://twitter.com/aliok_tr
Re: Tag handler for custom Behavior (not ClientBehavior)
Posted by Leonardo Uribe <lu...@gmail.com>.
Hi
In theory, If you create a new Behavior, it is expected to override
BehaviorTagHandlerDelegate. I think the current behavior is safe, because
you can write a custom wrapper for this tag and on apply method check if
your component implements your expected XXXBehaviorHolder interface, and if
so, apply, otherwise call to parent.
It could be good to think about how to extends myfaces builder plugin to
handle custom behavior holder interfaces. Right now, it has @JSFBehavior,
but it could be good to allow generation of XXXBehaviorHolder stuff from
annotations.
regards,
Leonardo Uribe
2010/5/17 Ali Ok <al...@aliok.com.tr>
> Hi,
> I was playing with JSF2 behaviors and I wrote a new behavior (not
> ClientBehavior). Problem I described here doesn't seem like a impl bug,
> instead it seems like a missing thing in the spec to me.
>
> Let me explain my structure first. I have two abstract stuff in
> Behavior-side:
>
> - "ByPassAttributeBehavior"
>
> @FacesBehavior(value = "org.apache.myfaces.html5.ByPassAttributeBehavior")
> public class ByPassAttributeBehavior extends *BehaviorBase*
> ....
>
> - "ByPassAttributeBehaviorHolder" (which does not extend anything. it
> would extend "BehaviorHolder", if it was existed)
>
> public interface ByPassAttributeBehaviorHolder
> ....
>
> And implementing component side (please note that I am using MyFaces
> builder plugin):
>
> - "AbstractByPassTestComponent"
>
> @JSFComponent(name = "hx:bypassTest",
> clazz = "tr.com.aliok.html5.bypassbehavior.BypassTestComponent",
> tagClass = "tr.com.aliok.html5.component.ByPassTestTag")
> public abstract class AbstractByPassTestComponent extends UIComponentBase
> implements *ByPassAttributeBehaviorHolder*
> {...
>
>
> - "ByPassTestRenderer"
>
> @JSFRenderer(
> renderKitId = "HTML_BASIC",
> family = "tr.com.aliok.html5.ByPassTest",
> type = "tr.com.aliok.html5.ByPassTest")
> public class ByPassTestRenderer extends Renderer
> {...
>
> Registration in ...taglib.xml:
> <tag>
> <tag-name>byPassAttributeBehavior</tag-name>
> <behavior>
>
> <behavior-id>org.apache.myfaces.html5.ByPassAttributeBehavior</behavior-id>
> </behavior>
> </tag>
>
> At last, my usage:
> <hx:bypassTest ...>
> <hx:byPassAttributeBehavior .../>
> </hx:bypassTest>
>
> In this case, at
> org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate#apply,
> an exception is thrown if the parent is not a ClientBehaviorHolder or a
> composite component.
> ...
>
> I think I can solve this problem by writing a tag handler, but why not
> supporting this feature without a tag handler just like ClientBehaviors?
>
> We don't have to write tag handlers for "ClientBehavior"s, but this is not
> the case for "Behavior"s. Seems like the problem is: there is no interface
> like "BehaviorHolder". Thus the delegate BehaviorTagHandlerDelegate cannot
> determine whether the parent is Behavior 'attachable', so it cannot attach
> Behaviors to parent.
>
> However, I couldn't understand why there is no interface like
> BehaviorHolder and why we need to write a tag handler for a "Behavior" that
> doesn't extend "ClientBehavior"? If something similar is discussed before,
> what was the purpose of this decision?
>
> I see that, we have "addClientBehavior" method in "ClientBehaviorHolder"
> class. Behaviors are here to get attached, right? So, why this attaching
> logic only pushed for 'ClientBehavior's?
>
> Regards,
> Ali
>
> --
> My Blog: http://blog.aliok.com.tr
> Twitter: http://twitter.com/aliok_tr
>
>