/******************************************************************************
* JBoss, a division of Red Hat *
* Copyright 2006, Red Hat Middleware, LLC, and individual *
* contributors as indicated by the @authors tag. See the *
* copyright.txt in the distribution for a full listing of *
* individual contributors. *
* *
* This is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2.1 of *
* the License, or (at your option) any later version. *
* *
* This software is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this software; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
******************************************************************************/
package org.jboss.portletbridge.lifecycle;
import java.util.Iterator;
import javax.faces.FactoryFinder;
import javax.faces.application.ViewExpiredException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author asmirnov
*/
public class RestoreViewPhase extends LifecyclePhase {
private static final Log _log = LogFactory.getLog(RestoreViewPhase.class);
private final LifecyclePhase nextPhase;
/**
* @param lifecycle
*/
public RestoreViewPhase(Lifecycle lifecycle) {
super(lifecycle);
nextPhase = new ApplyValuesPhase(lifecycle);
}
public void execute(FacesContext context) {
context.getApplication().getViewHandler().initView(context);
super.execute(context);
}
/*
* (non-Javadoc)
*
* @see org.jboss.portletbridge.lifecycle.LifecyclePhase#executeNextPhase(javax.faces.context.FacesContext,
* javax.faces.event.PhaseListener[])
*/
protected void executeNextPhase(FacesContext context) {
nextPhase.execute(context);
}
/*
* (non-Javadoc)
*
* @see org.jboss.portletbridge.lifecycle.LifecyclePhase#executePhase(javax.faces.context.FacesContext)
*/
public void executePhase(FacesContext context) {
// Check pre-created ViewRoot.
UIViewRoot viewRoot = context.getViewRoot();
if (null != viewRoot) {
if (_log.isDebugEnabled()) {
_log.debug("Found created UIViewRoot in facesContext");
}
viewRoot.setLocale(context.getExternalContext().getRequestLocale());
processBindings(context, viewRoot);
} else {
// Restore or Create new view.
String viewId = calculateViewId(context);
ViewHandler viewHandler = context.getApplication().getViewHandler();
if (isFacesRequest(context)) {
// TODO - check for a null and throw exception.
viewRoot = viewHandler.restoreView(context, viewId);
if (null != viewRoot) {
processBindings(context, viewRoot);
} else {
// Error restore view. Session Expired ?
throw new ViewExpiredException("Error restore view " + viewId + ", session expired?");
}
} else {
viewRoot = viewHandler.createView(context, viewId);
context.renderResponse();
}
context.setViewRoot(viewRoot);
}
}
private boolean isFacesRequest(FacesContext context) {
// Check request for a "postback"
String renderKitId = context.getApplication().getViewHandler()
.calculateRenderKitId(context);
return getRenderKit(context, renderKitId).getResponseStateManager()
.isPostback(context);
}
private RenderKit getRenderKit(FacesContext context, String renderKitId) {
// TODO - cache renderKitFactory instance.
RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
return renderKitFactory.getRenderKit(context, renderKitId);
}
private String calculateViewId(FacesContext context) {
String viewId;
Object externalRequest = context.getExternalContext().getRequest();
ExternalContext extContext = context.getExternalContext();
viewId = context.getExternalContext().getRequestPathInfo();
if (null == viewId) {
viewId = context.getExternalContext().getRequestServletPath();
}
return viewId;
}
private void processBindings(FacesContext context, UIComponent component) {
ValueBinding binding = component.getValueBinding("binding");
if (null != binding) {
binding.setValue(context, component);
}
for (Iterator iterator = component.getFacetsAndChildren(); iterator
.hasNext();) {
UIComponent child = (UIComponent) iterator.next();
processBindings(context, child);
}
}
/*
* (non-Javadoc)
*
* @see org.jboss.portletbridge.lifecycle.LifecyclePhase#getPhaseId()
*/
protected PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}