Hello everyone, I am currently in the process of fixing the SystemEvent
parts of myfaces so far I am along pretty well and some parts worked out
of the box and some parts needed fixing.
The Application Startup and Shutdowns for instance were not implemented
the Exception Queue events were implemented and worked out of the box.
But now I have run into an issue which is not entirely clear to me.
While walking over the globally registered ComponentSystemEvents
I noticed that listeners registered via faces-config are not notified
properly.
After digging into the codebase I noticed that
<system-event-listener>
<system-event-listener-class>org.apache.myfaces.scripting.startup.ComponentListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderComponentEvent</system-event-class>
</system-event-listener>
Is registered to UIComponent as source class, which is correct (well I
have rewritten the code so it should do it like that, if it is
incorrect, then correct me please ;-) )
Anyway it is the only possibility to register it since at registration
stage there is no additional meta informatin as long as
system-event-source is not set.
Well to make things complicated, at dispatch level we have a code similar to
//The main issue we have here is that the listeners are
normally just registered to UIComponent, how do we deal with inherited ones?
//We have to ask the EG
context.getApplication().publishEvent(context,
PreRenderComponentEvent.class,this /*component*/);
which means in case of the CommandButton we get as source HTMLCommandButton
There are two was to resolve this.
First if we cannot find the source class we can walk over the entire
inheritance hierarchy to find a match, which is slow it would introduce
a loop for every event dispatch on any component.
The second one would be
//We have to ask the EG
context.getApplication().publishEvent(context,
PreRenderComponentEvent.class, UIComponent.class,this /*component*/);
Which means we would precast to UIComponent, and we would ignore the
<system-source> parameter in this case.
I blackbox tested this behavior against the RI and it looks to me that
they opted for the second option. Which makes sense because
this part is very speed critical.
<system-event-listener>
<system-event-listener-class>org.apache.myfaces.scripting.startup.ComponentListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderComponentEvent</system-event-class>
<source-class>javax.faces.component.UIComponentBase</source-class>
</system-event-listener>
Never is called, while leaving out <source-class> triggers the listener
several times.
So how do we go on from here?
My personal opinion is we should opt for the same route as the RI
Werner