Andy,
In general, +1. I wonder, however, if ClienyBehaviorHolder shouldn't
be BehaviorHolder<? extends Behavior>.
Sent from my iPhone
On Mar 12, 2009, at 11:58 AM, Andy Schwartz <andy.schwartz(a)ORACLE.COM>
wrote:
One more update...
Just in case we do decide to roll these changes out, I have opened
up a Mojarra issue and uploaded my patch here:
https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1032
Martin, Kito -
Can you guys confirm whether you are happy with this solution,
preferably soon if you are checking email?
Oh, and, of course, if anyone else wants to either support or object
to this change, now would be a good time. :-)
Andy
Andy Schwartz wrote On 3/12/2009 8:07 AM ET:
>
> Gang -
>
> Last night I re-factored our code as described in my previous
> email, ie:
>
> - Behavior class -> ClientBehavior interface
> - BehaviorHolder->ClientBehaviorHolder
> - BehaviorContext->ClientBehaviorContext
> - BehaviorRenderer->ClientBehaviorRenderer
> - BehaviorBase->ClientBehaviorBase
> - BehaviorHint->ClientBehaviorHint
>
> I also introduced a new javax.component.behavior.Behavior
> interface, which is empty. While an empty interface is a bit
> unusual, it serves three purposes:
>
> 1. It allows us to return something generic from
> Application.createBehavior() (ie. return Behavior instead of
> ClientBehavior).
> 2. It provides us with a generic super-type for the new
> ClientBehavior interface.
> 3. It provides us with a a generic super-type for future Behavior
> contracts.
>
> Regarding #3, in order to address Martin's use case, we would add a
> new "PhaseBehavior" interface (extends Behavior) and a possibly a
> PhaseBehaviorHolder interface in 2.1. This would allow us to
> define a new aspect/phase-listening type of Behavior in 2.1.
>
> Martin -
>
> While the code re-factoring was fairly straightforward (though
> touched a number of places), if we are going get this in we still
> have a log of spec edits to make. So before we move forward, I
> would very much like to hear whether you are happy with the
> approach that I have proposed/implemented. Given the schedule
> dates that Ed sent out yesterday, we don't have much time to get
> this in, so please respond soon if at all possible.
>
> Kito -
>
> When you said:
>
>> Andy, your proposal seems like the simplest way to handle this for
>> now.
>
> I assume that means that you support this proposal (ie. renaming
> Behavior->ClientBehavior, introduce generic Behavior interface).
> Can you confirm?
>
>> However, if we assume that a behavior has a single purpose,
>> couldn't we just rename "getScript" to "getContent" or
something?
>
> Hrm... I am on the fence on this one... While getScript() is not
> the greatest name, it does seem relatively descriptive/
> informative. Not sure that moving to getContent() is a big
> improvement. And to be honest, since I am already pushing my luck
> with getting last minute changes in, I think I would prefer to
> stick with our current method name - one less spec edit to worry
> about. :-)
>
> Andy
>
> Andy Schwartz wrote On 3/11/2009 4:27 PM ET:
>>
>> Hey Martin,
>>
>> Okay, I see where you are coming from. So one option (leaving
>> schedule issues aside for a moment) would be to go back to our old
>> names:
>>
>> - Behavior->ClientBehavior
>> - BehaviorHolder->ClientBehaviorHolder
>>
>> And I guess also for the new APIs:
>>
>> - BehaviorContext->ClientBehaviorContext
>> - BehaviorRenderer->ClientBehaviorRenderer
>> - BehaviorBase->ClientBehaviorBase
>> - BehaviorHint->ClientBehaviorHint (or give up on the enum and
>> just use a boolean).
>>
>> And, as you suggest, we would need to define a new base Behavior
>> contract that ClientBehavior extends. Or, at least, I think we
>> need this, since we would want to keep the behavior-related
>> configuration stuff generic. That is, I assume that we would
>> still want this method in Application:
>>
>> public abstract Behavior createBehavior(String behaviorId)
>>
>> As opposed to this:
>>
>> public abstract ClientBehavior createClientBehavior(String
>> behaviorId)
>>
>> (And similarly, still want <behavior> elements in faces-config.xml
>> and Facelets taglib.)
>>
>> While I think we would need to introduce a new Behavior contract
>> (so that we have something generic to return from
>> Application.createBehavior()), I am not sure that we need a base
>> BehaviorHolder contract. Just doesn't seem like this would be
>> useful.
>>
>> If we do this, then in 2.1 we could introduce a PhaseBehavior
>> interface that extends Behavior. This would allow us to implement
>> phase-listening/apsect-like behaviors in 2.1 without requiring
>> that they implement the getScript() method. We may also add a
>> PhaseBehaviorHolder contract for components that allow
>> PhaseBehaviors to be attached independently of any event attach
>> point. (The ClientBehaviorHolder contract is all about attaching
>> to "events" - whereas a PhaseBehavior may not care at all about
>> attaching to a particular event.)
>>
>> Note that if we decide to add support for behaviors that do
>> component-level/aspect-like phase listening in 2.1, I would prefer
>> that we do this by introducing a new sub-interface of the generic
>> Behavior interface, rather than add phase listening capabilities
>> directly into the base, since phase listening capabilities may not
>> be generic to all Behaviors (just like script generation may not
>> be generic to all Behaviors - for example, AjaxBehavior doesn't
>> want to be a PhaseBehavior)
>>
>> So, I think this could work, but two problems:
>>
>> 1. I am not sure what the base Behavior contract should be.
>>
>> Would it be okay for this to just be a marker interface? This
>> would certainly be easier than trying to design a more meaningful/
>> generic base Behavior contract now.
>>
>> 2. Time
>>
>> The re-factoring shouldn't be all that hard, but it will require
>> some work, both on the implementation and in the specification,
>> and as we all know, we are definitely running out of time.
>>
>> Andy
>>
>> Martin Marinschek wrote On 3/11/2009 11:06 AM ET:
>>>
>>> Hi Andy,
>>>
>>> ok, I see. Well, I just wanted to make sure that we don't pollute
>>> the
>>> namespace: again, behavior seems to generic a name to me to have a
>>> method providing a script. Should we have a behavior interface, an
>>> extending script-behavior interface, and then we can make behavior
>>> (the base-interface) more powerful in 2.1?
>>>
>>>
>>> regards,
>>>
>>> Martin
>>>
>>> On 3/10/09, Andy Schwartz <andy.schwartz(a)oracle.com> wrote:
>>>
>>>> Hey Martin -
>>>>
>>>> Thanks for reading through my long email and for the comments!
>>>>
>>>> We ended up with the getScript() and decode() methods out of
>>>> necessity -
>>>> these were the minimal APIs that we needed to encapsulate our
>>>> Ajax-related functionality into a Behavior object. As currently
>>>> designed, our Behavior solution is definitely focused on
>>>> creating and
>>>> attaching scripts to components - thus we ended up with
>>>> getScript() as
>>>> the centerpiece of the Behavior contract.
>>>>
>>>> I find your idea of Behaviors as component aspects very
>>>> interesting, and
>>>> can see how this would add another degree of flexibility.
>>>> However, I am
>>>> a little uncomfortable expanding the scope at this point in the
>>>> 2.0
>>>> release. For 2.1, I do think it would be worth considering
>>>> whether we
>>>> can address this, perhaps by adding a new "PhaseBehavior"
>>>> interface.
>>>> The idea is that this would identify Behaviors that want to be
>>>> notified
>>>> before/after each phase, similar to a PhaseListener, but at the
>>>> component instance-level rather than at the view-level.
>>>>
>>>> Do you feel that this is something that we can evaluate for
>>>> 2.1? Or do
>>>> you feel that it is critical to address this in 2.0?
>>>>
>>>> Andy
>>>>
>>>> Martin Marinschek wrote On 3/10/2009 3:02 PM ET:
>>>>
>>>>> Hi Andy,
>>>>>
>>>>> I think this all reads very well - however, I was wondering why
>>>>> you
>>>>> stopped at providing decode and renderScript (especially the
>>>>> get-script method feels a little awkward in something which
>>>>> sounds as
>>>>> generic as a behaviour class).
>>>>>
>>>>> For me, this whole behavior thing sounds like a component aspect:
>>>>> something which is called before/after/around component lifecycle
>>>>> methods are executed... at least before/after/around decode and
>>>>> before/after/around rendering.
>>>>>
>>>>> regards,
>>>>>
>>>>> Martin
>>>>>
>>>>> On 3/10/09, Andy Schwartz <andy.schwartz(a)oracle.com> wrote:
>>>>>
>>>>>
>>>>>> Gang -
>>>>>>
>>>>>> I wanted to send one last email on the new Behavior API to
>>>>>> help folks
>>>>>> who were not able to keep up with the progress on this API as it
>>>>>> evolved. Much of this information has been covered in
>>>>>> previous emails,
>>>>>> but some of the API details are new, so please read on if you
>>>>>> are
>>>>>> interested.
>>>>>>
>>>>>> * Core APIs
>>>>>>
>>>>>> Just to remind everyone why we started down this path... As
>>>>>> of the
>>>>>> public review draft, we had a single non-generic
"behavior" -
>>>>>> the
>>>>>> AjaxBeahvior - which could only be attached to
>>>>>> EditableValueHolders and
>>>>>> ActionSource components, and even then, only for valueChange/
>>>>>> action
>>>>>> events. So, two obvious limitations that we decided to address:
>>>>>>
>>>>>> 1. We wanted to allow other types of "behaviors" to be
>>>>>> provided - not
>>>>>> limit the solution to AjaxBehavior.
>>>>>> 2. We wanted to allow components other than
>>>>>> EditableValueHolders/ActionSources to host
"behaviors".
>>>>>>
>>>>>> In order to address #1, we introduced the generic
>>>>>> javax.faces.component.behavior.Behavior class. The class
>>>>>> provides the
>>>>>> base contract for all behavior implementations. Note that
>>>>>> early on we
>>>>>> decided that a "behavior" was something distinct from
a
>>>>>> "component".
>>>>>> Behaviors, like converters/validators, are objects that are
>>>>>> attached to
>>>>>> existing components in order to enhance the component with
>>>>>> functionality
>>>>>> that is not provided by the component itself.
>>>>>>
>>>>>> The main responsibility of a Behavior implementation is to
>>>>>> cough up a
>>>>>> script - ie. a bit of JavaScript code that can be attached to
>>>>>> one of the
>>>>>> component's client-side event handlers (eg. attach to
>>>>>> "onclick"). This
>>>>>> responsibility is implemented via the Behavior.getScript()
>>>>>> method.
>>>>>>
>>>>>> In order to address #2, we introduced the
>>>>>> javax.faces.component.behavior.BehaviorHolder interface.
>>>>>> Components
>>>>>> that want to allow behaviors to be attached implement this
>>>>>> interface.
>>>>>> This allows the component to communicate the valid attach points
>>>>>> (getEventNames()) and the default attach point
>>>>>> (getDefaultEventName()),
>>>>>> provides a mechanism for registering behaviors
>>>>>> (addBehavior()), and also
>>>>>> provides access to any registered behaviors (getBehaviors()).
>>>>>>
>>>>>> While UIComponentBase does not implement the BehaviorHolder
>>>>>> interface
>>>>>> itself, it provides default implementations of the
>>>>>> BehaviorHolder
>>>>>> methods in order to make it easier for subclasses to implement
>>>>>> BehaviorHolder. The minimal requirement for a UIComponentBase
>>>>>> subclass
>>>>>> to implement BehaviorHolder is to provide an implementation of
>>>>>> getEventNames() that returns a non-empty set of the event names
>>>>>> supported by the component.
>>>>>>
>>>>>> These two contracts, Behavior and BehaviorHolder, form the
>>>>>> foundation of
>>>>>> our new component behavior solution. Hopefully the above
>>>>>> should be
>>>>>> familiar since it has been discussed the number of times on
>>>>>> the EG list
>>>>>> and was also covered in Appendix C of the recent spec
>>>>>> drafts. The
>>>>>> actual set of APIs that we need has grown over the last few
>>>>>> months, so I
>>>>>> wanted to also discuss some of the more recent additions...
>>>>>>
>>>>>> * BehaviorRenderer
>>>>>>
>>>>>> Once we got the core Behavior/BehaviorHolder contract in
>>>>>> place, we
>>>>>> (Roger, Ted, Alex and I) quickly realized that additional
>>>>>> flexibility
>>>>>> was needed. In particular, we felt that the scripts that are
>>>>>> produced
>>>>>> by Behaivor implementations may need to vary based on the
>>>>>> RenderKit. In
>>>>>> order to support RenderKit-specific Behavior script
>>>>>> generation, we
>>>>>> followed the existing UIComonent/Renderer pattern and
>>>>>> introduced a
>>>>>> BehaviorRenderer API. BehaviorRenderers are similar in spirit
>>>>>> to
>>>>>> component Renderers, but provide a contract that is geared
>>>>>> towards
>>>>>> Behaviors. So, while component Renderers are designed for
>>>>>> HTML content
>>>>>> generation and write directly to the ResponseWriter,
>>>>>> BehaviorRenderers
>>>>>> simply cough up a script - ie. the main API on
>>>>>> BehaviorRenderer is
>>>>>> getScript() (mirrors Behavior.getScript()).
>>>>>>
>>>>>> Of course, as with component Renderers, BehaviorRenderers are
>>>>>> entirely
>>>>>> optional. A Behavior implementation does not need to use a
>>>>>> BehaviorRenderer at all - it can simply override
>>>>>> Behavior.getScript()
>>>>>> and produce the script locally.
>>>>>>
>>>>>> * Behavior Event Handling
>>>>>>
>>>>>> The next enhancement that we tackled was the ability for
>>>>>> Behaviors to
>>>>>> participate in decoding. This was necessary in order to
>>>>>> support a very
>>>>>> important use case: the ability for Behavior implementations
>>>>>> to deliver
>>>>>> events to registered listeners. The main case that we had in
>>>>>> mind was
>>>>>> AjaxBehavior, ie. we wanted to make it possible to do this:
>>>>>>
>>>>>> <h:commandButton>
>>>>>> <f:ajax event="mouseover"
>>>>>>
listener="#{bean.doSomethingInResponseToMouseOver}"/>
>>>>>> </h:commandButton>
>>>>>>
>>>>>> In order to support this we added the following APIs:
>>>>>>
>>>>>> - Behavior.decode()
>>>>>> - BehaviorRenderer.decode()
>>>>>> - Behavior.broadcast()
>>>>>> - BehaviorEvent (extends FacesEvent)
>>>>>> - BehaviorListener (extends FacesListener)
>>>>>>
>>>>>> We also specified the mechanism/conditions under which
>>>>>> BehaviorHolder
>>>>>> components must give attached Behaviors the opportunity to
>>>>>> decode.
>>>>>>
>>>>>> * BehaviorBase
>>>>>>
>>>>>> Around this time we also introduced a BehaviorBase base class
>>>>>> that
>>>>>> provides base functionality for Behavior implementations (such
>>>>>> as
>>>>>> listener registration, event broadcast support, BehaviorRenderer
>>>>>> delegation wiring). BehaviorBase is to Behavior what
>>>>>> UIComponentBase is
>>>>>> to UIComponent.
>>>>>>
>>>>>> * Behavior.Parameter
>>>>>>
>>>>>> As we started integrating the new behavior contract with our
>>>>>> existing
>>>>>> renderers, we realized that Behavior/BehaviorRenderer
>>>>>> getScript()
>>>>>> implementations may need access to various pieces of
>>>>>> information to help
>>>>>> them generate the correct scripts. For example, in the
>>>>>> h:commandButton
>>>>>> case, the component may have f:params attached. These f:param
>>>>>> names/values must be included in the request, whether the
>>>>>> request is a
>>>>>> full page postback provided by the component, or an Ajax
>>>>>> postback
>>>>>> provided by the AjaxBehavior. In order to support this case,
>>>>>> we added a
>>>>>> trivial static inner Parameter class to Behavior. This allows
>>>>>> components/renderers to pass (resolved) parameter name/values
>>>>>> into
>>>>>> Behavior.getScript().
>>>>>>
>>>>>> * BehaviorContext
>>>>>>
>>>>>> At this point we realized that there is danger in adding more
>>>>>> arguments
>>>>>> to the Behavior.BehaviorRenderer.getScript() methods. The
>>>>>> problem is
>>>>>> that we may not be able to foresee all of the possible
>>>>>> information that
>>>>>> getScript() implementations may need access to. Rather than
>>>>>> risk having
>>>>>> to later define new overrides of getScript(), we decided to
>>>>>> introduce a
>>>>>> BehaviorContext class. The BehaviorContext is used to pass
>>>>>> information
>>>>>> (FacesContext, component, parameters, source id) into
>>>>>> Behavior.getScript(). If we find that we need to pass
>>>>>> additional
>>>>>> information into getScript() in a later release, we can do so
>>>>>> by adding
>>>>>> new methods to the BehaviorContext.
>>>>>>
>>>>>> BehaviorContext is defined as an abstract class, but provides
>>>>>> access to
>>>>>> a implementation via the
>>>>>> BehaviorContext.createBehaviorContext() factory
>>>>>> method. Note that we explicitly avoid going through the
>>>>>> FactoryFinder
>>>>>> mechanism here since this is a trivial data transfer object -
>>>>>> and one
>>>>>> which may need to be instantiated many times during a typical
>>>>>> request -
>>>>>> so we want to keep the overhead low.
>>>>>>
>>>>>> I keep going back and forth as to whether Behavior.decode()
>>>>>> should also
>>>>>> take a BehaviorContext. Currently it just takes a
>>>>>> FacesContext and the
>>>>>> UIComponent. I am tempted to pass in the BehaviorContext
>>>>>> instead,
>>>>>> though certain information on the BehaviorContext (like the
>>>>>> parameters)
>>>>>> are clearly specific to script generation.
>>>>>>
>>>>>> * BehaviorHint
>>>>>>
>>>>>> Another issue that arose while integrating Behavior support into
>>>>>> h:commandButton is that the component renderer may itself need
>>>>>> to vary
>>>>>> its content depending on whether or not it has a Behavior
>>>>>> attached, and
>>>>>> in particular depending on whether that Behavior provides a
>>>>>> script that
>>>>>> performs a postback. The issue here is that certain renderers
>>>>>> - eg.
>>>>>> commandButton/Link renderers - may generate their own postback
>>>>>> scripts
>>>>>> (in Mojarra these renderers generate calls to
>>>>>> mojarra.jsfcljs()).
>>>>>> However, when an AjaxBehavior is attached, it provides its own
>>>>>> postback
>>>>>> script that should replace/suppress the postback script that the
>>>>>> component renderer normally produces. Since not all Behavior
>>>>>> implementations actually perform postbacks (AjaxBehavior does,
>>>>>> but most
>>>>>> won't), the component renderer needs some way to determine
>>>>>> whether or
>>>>>> not an attached Behavior is going to perform a postback.
>>>>>>
>>>>>> In order to solve this problem, we added a new enum,
>>>>>> BehaviorHint, and a
>>>>>> new method to Behavior: Behavior.getHints(). getHints()
>>>>>> returns a
>>>>>> Set<BehaviorHint> (implemented under the covers as an
EnumSet
>>>>>> of course)
>>>>>> that provides information about the Behavior that the consuming
>>>>>> component/renderer may be interested in.
>>>>>>
>>>>>> At the moment, the BehaviorHint enum only defines a single
>>>>>> value -
>>>>>> BehaviorHint.SUBMITTING. However, we chose to use an enum
>>>>>> rather than a
>>>>>> boolean (ie. rather than a Behavior.isSubmitting() method) to
>>>>>> allow for
>>>>>> additional hints in the future. If people feel that it is too
>>>>>> awkward
>>>>>> to have a single-valued enum in our API, please let me know.
>>>>>> We can
>>>>>> consider reverting to a boolean method, though an enum is more
>>>>>> future
>>>>>> proof.
>>>>>>
>>>>>> * Behavior configuration
>>>>>>
>>>>>> In order to provide complete support for configuring Behavior
>>>>>> and
>>>>>> BehaviorRenderer implementations, we had to touch a number of
>>>>>> places,
>>>>>> including:
>>>>>>
>>>>>> - javax.faces.application.Application now supports methods for
>>>>>> adding
>>>>>> and creating Behavior instances
>>>>>> - faces-config.xml now supports <behavior> and
<behavior-
>>>>>> renderer>
>>>>>> elements
>>>>>> - We have added annotations for identifying Behavior and
>>>>>> BehaviorRenderer implementations so that faces-config entries
>>>>>> are not
>>>>>> required
>>>>>> - The Facelets taglib file now supports <behavior> tags.
>>>>>>
>>>>>> In all cases we followed the precedents already set by
>>>>>> converter/validator.
>>>>>>
>>>>>> * Standard HTML component BehaviorHolders
>>>>>>
>>>>>> Finally, once we had agreement our generic Behavior solution,
>>>>>> we also
>>>>>> decided that it was silly not to enhance the standard HTML
>>>>>> component set
>>>>>> to take advantage of this. Most of the standard HTML
>>>>>> components now
>>>>>> implement BehaviorHolder and thus allow Behaviors to be
>>>>>> attached. The
>>>>>> attach points for the standard HTML components correspond to the
>>>>>> standard "on<Event>" attributes. So, whereas
before it was only
>>>>>> possible to attach behaviors to EditableValueHolder/ActionSource
>>>>>> components, it is now possible to attach Behaviors to other
>>>>>> standard
>>>>>> components, eg. <h:panelGroup>:
>>>>>>
>>>>>> <h:panelGroup>
>>>>>> <f:ajax event="mouseover"
listener="#{bean.foo}"/>
>>>>>> </h:panelGroup>
>>>>>>
>>>>>> This gives us significantly more flexibility - and a much more
>>>>>> powerful
>>>>>> solution than we had outlined in our original plans.
>>>>>>
>>>>>> One quick note on event names... The event names/attach points
>>>>>> do not
>>>>>> include the "on" prefix that is used in the component
>>>>>> attribute names.
>>>>>> So:
>>>>>>
>>>>>> <f:ajax event="mouseover"/>
>>>>>>
>>>>>> Not:
>>>>>>
>>>>>> <f:ajax event="onMouseover"/>
>>>>>>
>>>>>> The standard ActionSource components still support a logical
>>>>>> "action"
>>>>>> event/attach point. And the standard EditableValueHolder
>>>>>> components
>>>>>> still support a logical "valueChange" event/attach
point.
>>>>>> This allows
>>>>>> page authors to attach Behaviors to these components without
>>>>>> having to
>>>>>> be aware of the unerlying DOM event that triggers the action/
>>>>>> value
>>>>>> change. Also note that the "action" and
"valueChange" events
>>>>>> are
>>>>>> defined as default events for these components, which makes it
>>>>>> possible
>>>>>> to do omit the event attribute, eg:
>>>>>>
>>>>>> <!-- Fires Ajax requests in response to actions -->
>>>>>> <h:commandButton>
>>>>>> <f:ajax/>
>>>>>> </h:commandButton>
>>>>>>
>>>>>> <!-- Fires Ajax requests in response to value changes
-->
>>>>>> <h:inputText>
>>>>>> <f:ajax/>
>>>>>> </h:inputText>
>>>>>>
>>>>>> BTW, Jeffrey Stephenson (JSR-276) and I have been having some
>>>>>> offline
>>>>>> discussions on the possibility of getting event name/default
>>>>>> event name
>>>>>> metadata in place. This would clearly help the development tool
>>>>>> experience.
>>>>>>
>>>>>> * Limitations
>>>>>>
>>>>>> While I think that the Behavior API is a great addition to
>>>>>> JSF, there
>>>>>> are a few limitations that we have not been able to address
>>>>>> for 2.0.
>>>>>> These include:
>>>>>>
>>>>>> 1. Custom renderer wiring
>>>>>>
>>>>>> Implementing the BehaviorHolder contract is trivial. However,
>>>>>> actually
>>>>>> rendering the Behavior scripts - possibly multiple scripts
>>>>>> which may
>>>>>> need to be chained with other component/renderer-defined
>>>>>> scripts - can
>>>>>> be tedious. To help simplify this, we have introduced a new
>>>>>> utility
>>>>>> method into our JavaScript API: jsf.util.chain(). This method
>>>>>> takes an
>>>>>> arbitrary number of script arguments and executes each one
>>>>>> until it
>>>>>> finds one that returns false, at which point it short-
>>>>>> circuits. While
>>>>>> this simplifies things somewhat, it is still nontrivial for a
>>>>>> Renderer
>>>>>> author to produce the proper call to jsf.util.chain().
>>>>>>
>>>>>> If we had more time, I would recommend trying to get some
>>>>>> utility
>>>>>> methods into the JSF API so that we can make it easier for
>>>>>> custom
>>>>>> Renderer authors to produce the properly chained scripts.
>>>>>> However,
>>>>>> given how little have time we have left, I do not think that
>>>>>> we have
>>>>>> time to get this right. My current plan is to try to provide
>>>>>> some open
>>>>>> source utilities to help Renderer authors solve this problem.
>>>>>> Once
>>>>>> we've worked out the right APIs in open source, I am hoping
>>>>>> that we can
>>>>>> incorporate these back into the 2.1 spec.
>>>>>>
>>>>>> 2. Behavior attribute-property transparency
>>>>>>
>>>>>> I have been thinking that, like components, Behaviors should
>>>>>> expose an
>>>>>> attribute map that provides attribute-property transparency.
>>>>>> That way,
>>>>>> BehaviorRenderers do not have to worry about the actual
>>>>>> Behavior type -
>>>>>> they can simply grab attributes out of the attribute map.
>>>>>>
>>>>>> I briefly considered implementing this functionality, but
>>>>>> after a quick
>>>>>> look at UIComponentBase.AttributeMap I got scared away. I
>>>>>> think the
>>>>>> right solution is to:
>>>>>>
>>>>>> - Break UIComponentBase.AttributeMap out into its own top-
>>>>>> level public
>>>>>> class.
>>>>>> - Introduce an AttributeHolder contract
>>>>>> - Have UIComponentBase and BehaviorBase implement
>>>>>> AttributeHolder and
>>>>>> use AttributeMap to hold their attributes.
>>>>>>
>>>>>> However, for obvious reasons I decided not to push this for 2.0.
>>>>>> Perhaps we can think about this for 2.1.
>>>>>>
>>>>>> Since we do not have a Behavior.getAttributes() API, at the
>>>>>> moment,
>>>>>> BehaviorRenderer implementations are forced to cast to the
>>>>>> actual
>>>>>> Behaivor type (eg. AjaxBehaviorRenderer casts the Behavior to
>>>>>> AjaxBehavior). I am not happy about this, but willing to live
>>>>>> with it
>>>>>> for now.
>>>>>>
>>>>>> 3. Behavior resources
>>>>>>
>>>>>> Behavior implementations clearly are going to want to pull in
>>>>>> JavaScript
>>>>>> libraries so that these do not need to be pulled in explicitly
>>>>>> by the
>>>>>> application developer. However, at the moment we do not have a
>>>>>> solution/recommendation for this. (Well, there might be some
>>>>>> solution -
>>>>>> just haven't identified what it is yet.)
>>>>>>
>>>>>> This is another one that will need to wait for 2.1.
>>>>>>
>>>>>> I think that's it! If you have any questions/comments on
this
>>>>>> new API,
>>>>>> please follow up here.
>>>>>>
>>>>>> I am hoping to do some blogging on all of this if I can ever
>>>>>> find the
>>>>>> time. :-)
>>>>>>
>>>>>> Andy
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
aven't identified what it is yet.) This is another one that will
need to wait for 2.1. I think that's it! If you have any questions/
comments on this new API, please follow up here. I am hoping to do
some blogging on all of this if I can ever find the time. :-) Andy
uote>