I aim to setup the jsf thread to a specific state that I derive from the fact if a given tag is in the subtree of my custom component. This custom component declares a custom cdi scope.
<my:scope area="info">
<rich:tree selectionChangeListener="#{taskTreeManager.selectionChanged}"
<my:scope>
<my:scope area="work">
<rich:tree selectionChangeListener="#{taskTreeManager.selectionChanged}"
<my:scope>
HERE is my idea: the cdi bean 'taskTreeManager' is different for the two rich:trees, since it comes from a custom cdi scope:
@TaskScoped
public TaskTreeManager { .... }
Now I created the jsf tag .
What is missing is a way that this tag has impact on its children, i a generic way (ie. without making assupmtions and without having to change the children).
The needs to activate the cdi scope on each action happening on any tag in its subtree.
I also failed to find a listener for that, especially since Ajax calls go quite directly into the listeners defined on the very component ( the rich:tree). The hierarchy of the component as can be seen in the xhtml is not so relevant, so it seem: when taskTreeManager.selectionChanged gets called, my:scope tag does not know and thus cannot switch the cdi scope properly.
Then I tried to setup listeners programmatically on each component that resides in the subtree.
In the meantime I turned around: what I am trying to achieve is that each java callback finds the right scope active. This can be reduced to: each EL expression evaluation finds its cdi beans in the right scope. So my way was to introduce a new ELResolver with the sole purpose of discovering if the current component resides within tag.
Fortunately that is possible:
private String computeViewArea(UIComponent cc) {
String retval = EMPTY;
while (null != cc) {
// attention: cc.toString() causes stackoverflow !! so don't log cc!
if (cc instanceof TaskScopedComponent) {
TaskScopedComponent c = (TaskScopedComponent) cc;
retval = (String) c.getAttributes().get("viewArea");
break;
}
cc = cc.getParent();
}
return retval;
}