Access ViewRoot before render response in a PhaseListener

Hi,

I'm trying to access UIComponents just before the render response phase to change some attributes of the UIComponents. Therefor I have created a PhaseListener, which is called before the render response phase. My idea was, to get the ViewRoot and iterate over it to access all UIComponents, but in the beforePhase, the ViewRoot has no children. How can I solve this problem?

Here is my PhaseListener:

publicclass SecurityPhaseListenerimplements PhaseListener{

privatestatic Log log = LogFactory.getLog(SecurityPhaseListener.class);

publicvoid afterPhase(PhaseEvent pe){

}

public PhaseId getPhaseId(){

return PhaseId.RENDER_RESPONSE;

}

publicvoid beforePhase(PhaseEvent pe){

UIViewRoot viewRoot = pe.getFacesContext().getViewRoot();

System.out.println("before render response " + viewRoot.getChildCount());// returns 0

// the following is just sample code for you to get an idea of what i want to do

// change attributes according permissions

for (Iterator iter = viewRoot.getChildren().iterator(); iter.hasNext();){

UIComponent comp = (UIComponent) iter.next();

if(compinstanceof HtmlInputText){

HtmlInputText htmlInputText = (HtmlInputText) comp;

htmlInputText.setRendered(false);

}

}

}

}

[2277 byte] By [henrik_niehausa] at [2007-11-26 21:03:03]
# 1
Then just do it after the render response.
BalusCa at 2007-7-10 2:35:26 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2
I have tried that, but that does not have any effect on the components, which appears to be logical to me, because after render response, all components are rendered already and setting any attribute is useless at this point in time.But maybe I am wrong with that...
henrik_niehausa at 2007-7-10 2:35:26 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

Oh well, I see. You want to set the rendered attribute to false while it is already rendered =)

I'd rather to put it in the JSF itself:<h:inputText rendered="#{myBean.userAuthenticated}" />

MyBeanpublic boolean isUserAuthenticated() {

return ((User) getSessionMap().get("loggedInUser")).isAuthenticated();

}

Or so.

BalusCa at 2007-7-10 2:35:26 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

That would be possible, but I don't want to do that ;-)

The goal is to create a security extension for JSF, which can be plugged in a standard JSF implementation through something like a PhaseListener. We want to change as few as possible -> no custom components, no custom viewhandler or things like that. (If that is possible). I hope you get a clue of what we want to do...

henrik_niehausa at 2007-7-10 2:35:26 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

What kind of security do you mean?

I'am using a PhaseListener, which is called in before RESTORE_VIEW and in after RENDER_RESPONSE and

- checks user dependend permissions

- identifies the client window which has submitted the request

- replaces the page scope with a process scope

- checks if the user has submitted form data twice

Due to the way, how navigation works in JSF, the target of a navigation action is checked in an action method outside the PhaseListener.

Ingmara at 2007-7-10 2:35:26 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...