/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.ajax4jsf.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKitFactory;
import javax.servlet.ServletException;
import org.ajax4jsf.resource.InternetResource;
import org.ajax4jsf.resource.ResourceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Lifecycle for simulate faces request processing for resource.
*
* @author shura (latest modification by $Author: alexsmirnov $)
* @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:56:56 $
*
*/
public class ResourceLifecycle extends Lifecycle {
private Lifecycle lifecycle;
private static final Log _log = LogFactory.getLog(ResourceLifecycle.class);
/*
* (non-Javadoc)
*
* @see javax.faces.lifecycle.Lifecycle#addPhaseListener(javax.faces.event.PhaseListener)
*/
public void addPhaseListener(PhaseListener arg0) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see javax.faces.lifecycle.Lifecycle#execute(javax.faces.context.FacesContext)
*/
public void execute(FacesContext arg0) throws FacesException {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see javax.faces.lifecycle.Lifecycle#getPhaseListeners()
*/
public PhaseListener[] getPhaseListeners() {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
*
* @see javax.faces.lifecycle.Lifecycle#removePhaseListener(javax.faces.event.PhaseListener)
*/
public void removePhaseListener(PhaseListener arg0) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see javax.faces.lifecycle.Lifecycle#render(javax.faces.context.FacesContext)
*/
public void render(FacesContext arg0) throws FacesException {
// TODO Auto-generated method stub
}
/**
* @param context
* @param resource
* @throws IOException
*/
public void send(ResourceContext resourceContext, InternetResource resource)
throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
PhaseListener[] phaseListeners = null;
PhaseEvent renderViewEvent = null;
if (null != facesContext) {
Lifecycle facesLifecycle = getFacesLifecycle();
phaseListeners = facesLifecycle.getPhaseListeners();
PhaseEvent restoreViewEvent = new PhaseEvent(facesContext,
PhaseId.RESTORE_VIEW, this);
processPhaseListeners(phaseListeners, restoreViewEvent, true);
// Fix for a http://jira.jboss.org/jira/browse/RF-1056
if (facesContext.getResponseComplete())
return;
// fix for a http://jira.jboss.com/jira/browse/RF-1064 .
// viewRoot can be created outside.
UIViewRoot savedViewRoot = facesContext.getViewRoot();
try {
// create "dummy" viewRoot, to avoid problems in phase
// listeners.
UIViewRoot root = new UIViewRoot();
root.setViewId(resource.getKey());
root.setLocale(Locale.getDefault());
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
facesContext.setViewRoot(root);
// Invoke after restore view phase listeners
processPhaseListeners(phaseListeners, restoreViewEvent, false);
// Fix for a http://jira.jboss.org/jira/browse/RF-1056
if (!facesContext.getResponseComplete()) {
// Invoke before render view phase listeners
renderViewEvent = new PhaseEvent(facesContext,
PhaseId.RENDER_RESPONSE, this);
processPhaseListeners(phaseListeners, renderViewEvent, true);
sendResource(resourceContext, resource);
processPhaseListeners(phaseListeners, renderViewEvent,
false);
}
} finally {
if (null != savedViewRoot) {
facesContext.setViewRoot(savedViewRoot);
}
}
} else {
sendResource(resourceContext, resource);
}
}
/**
* Send phase event to all apropriate PhaseListener's
*
* @param phaseListeners
* @param phaseEvent
* @param beforePhase
* TODO
*/
private void processPhaseListeners(PhaseListener[] phaseListeners,
PhaseEvent phaseEvent, boolean beforePhase) {
if (beforePhase) {
// Invoke before phase listeners
for (int i = 0; i < phaseListeners.length; i++) {
PhaseListener phaseListener = phaseListeners[i];
invokePhaseListener(phaseListener, phaseEvent, beforePhase);
}
} else {
// Invoke after phase listeners, in reverse order.
for (int i = phaseListeners.length - 1; i >= 0; i--) {
PhaseListener phaseListener = phaseListeners[i];
invokePhaseListener(phaseListener, phaseEvent, beforePhase);
}
}
}
/**
* @param phaseListener
* @param phaseEvent
* @param beforePhase
*/
private void invokePhaseListener(PhaseListener phaseListener,
PhaseEvent phaseEvent, boolean beforePhase) {
if (phaseEvent.getPhaseId().equals(phaseListener.getPhaseId())
|| PhaseId.ANY_PHASE.equals(phaseListener.getPhaseId())) {
try {
if (beforePhase) {
phaseListener.beforePhase(phaseEvent);
} else {
phaseListener.afterPhase(phaseEvent);
}
} catch (Exception e) {
_log
.error("Exception in PhaseListener, phase :"
+ phaseEvent.getPhaseId().toString()
+ (beforePhase ? " : beforePhase"
: " : afterPhase"), e);
}
}
}
/**
* @param resourceContext
* @param resource
* @throws IOException
*/
private void sendResource(ResourceContext resourceContext,
InternetResource resource) throws IOException {
resource.sendHeaders(resourceContext);
resource.send(resourceContext);
}
protected synchronized Lifecycle getFacesLifecycle() {
if (lifecycle == null) {
// Acquire our Lifecycle instance
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
lifecycle = lifecycleFactory
.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
}
return lifecycle;
}
}