private static final Logger log = Logger.getLogger(RenderResponseExecutor.class.getName());
public boolean execute(FacesContext facesContext)
{
Application application = facesContext.getApplication();
ViewHandler viewHandler = application.getViewHandler();
UIViewRoot root;
UIViewRoot previousRoot;
String viewId;
String newViewId;
boolean isNotSameRoot;
int loops = 0;
int maxLoops = 15;
if (facesContext.getViewRoot() == null)
{
throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
}
try
{
// do-while, because the view might change in PreRenderViewEvent-listeners
do
{
root = facesContext.getViewRoot();
previousRoot = root;
viewId = root.getViewId();
ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(
facesContext, viewId);
if (vdl != null)
{
vdl.buildView(facesContext, root);
}
// publish a PreRenderViewEvent: note that the event listeners
// of this event can change the view, so we have to perform the algorithm
// until the viewId does not change when publishing this event.
application.publishEvent(facesContext, PreRenderViewEvent.class, root);
// was the response marked as complete by an event listener?
if (facesContext.getResponseComplete())
{
return false;
}
root = facesContext.getViewRoot();
newViewId = root.getViewId();
isNotSameRoot = !( (newViewId == null ? newViewId == viewId : newViewId.equals(viewId) ) &&
previousRoot.equals(root) );
loops++;
}
while ((newViewId == null && viewId != null)
|| (newViewId != null && (!newViewId.equals(viewId) || isNotSameRoot ) ) && loops < maxLoops);
if (loops == maxLoops)
{
// PreRenderView reach maxLoops - probably a infinitive recursion:
boolean production = facesContext.isProjectStage(ProjectStage.Production);
Level level = production ? Level.FINE : Level.WARNING;
if (log.isLoggable(level))
{
log.log(level, "Cicle over buildView-PreRenderViewEvent on RENDER_RESPONSE phase "
+ "reaches maximal limit, please check listeners for infinite recursion.");
}
}
viewHandler.renderView(facesContext, root);
// log all unhandled FacesMessages, don't swallow them
if (!facesContext.getMessageList().isEmpty())
{
StringBuilder builder = new StringBuilder();