/******************************************************************************
* 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.seam.jsf;
import static javax.faces.event.PhaseId.INVOKE_APPLICATION;
import static javax.faces.event.PhaseId.PROCESS_VALIDATIONS;
import static javax.faces.event.PhaseId.RENDER_RESPONSE;
import static javax.faces.event.PhaseId.RESTORE_VIEW;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.portlet.faces.Bridge;
import javax.portlet.faces.Bridge.PortletPhase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.portletbridge.application.PortletWindowState;
import org.jboss.portletbridge.context.PortletBridgeContext;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.FacesLifecycle;
import org.jboss.seam.core.Manager;
import org.jboss.seam.exception.Exceptions;
import org.jboss.seam.faces.FacesMessages;
/**
* @author asmirnov
*
*/
public class SeamPhaseListenerWrapper implements PhaseListener {
private final SeamPhaseListener _defaultListener;
private static final Log log = LogFactory
.getLog(SeamPhaseListenerWrapper.class);
/**
* @param defaultListener
*/
public SeamPhaseListenerWrapper(PhaseListener defaultListener) {
_defaultListener = (SeamPhaseListener) defaultListener;
}
/**
*
*/
private static final long serialVersionUID = -8465467659533393697L;
/*
* (non-Javadoc)
*
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
*/
public void afterPhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
ExternalContext externalContext = facesContext.getExternalContext();
Bridge.PortletPhase portletPhase = (PortletPhase) externalContext
.getRequestMap().get(Bridge.PORTLET_LIFECYCLE_PHASE);
if (null != portletPhase) {
try {
_defaultListener.raiseEventsAfterPhase(event);
afterPortletPhase(event, facesContext, portletPhase);
} catch (Exception e) {
log.debug("uncaught exception, try to recovery", e);
try {
Exceptions.instance().handle(e);
// A redirect occurred inside the error handler, and we are
// in after
// phase, so we need to clean up now as there are no more
// after
// phases to be run
if (facesContext.getResponseComplete()) {
_defaultListener.afterResponseComplete(facesContext);
}
} catch (Exception ehe) {
log.error("swallowing exception", e);
}
}
FacesLifecycle.clearPhaseId();
} else {
_defaultListener.afterPhase(event);
}
}
private void afterPortletPhase(PhaseEvent event, FacesContext facesContext,
PortletPhase portletPhase) {
PhaseId phaseId = event.getPhaseId();
if (phaseId == RESTORE_VIEW) {
_defaultListener.afterRestoreView(facesContext);
} else if (phaseId == INVOKE_APPLICATION) {
_defaultListener.afterInvokeApplication();
} else if (phaseId == PROCESS_VALIDATIONS) {
_defaultListener.afterProcessValidations(facesContext);
}
FacesMessages.afterPhase();
// delegate to subclass:
_defaultListener.handleTransactionsAfterPhase(event);
if (phaseId == RENDER_RESPONSE) {
// writeConversationIdToResponse(
// facesContext.getExternalContext().getResponse() );
_defaultListener.afterRenderResponse(facesContext);
} else if (Bridge.PortletPhase.ActionPhase.equals(portletPhase)
&& (phaseId == INVOKE_APPLICATION
|| facesContext.getRenderResponse() || facesContext
.getResponseComplete())) {
// Manager manager = Manager.instance();
// manager.beforeRedirect();
// save Seam conversation Id.
PortletBridgeContext bridgeContext = (PortletBridgeContext) facesContext
.getExternalContext().getRequestMap().get(
PortletBridgeContext.REQUEST_PARAMETER_NAME);
if (null != bridgeContext) {
PortletWindowState windowState = bridgeContext.getWindowState();
windowState.saveSeamConversationId(facesContext);
}
_defaultListener.afterResponseComplete(facesContext);
}
}
/*
* (non-Javadoc)
*
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
*/
public void beforePhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
ExternalContext externalContext = facesContext.getExternalContext();
Bridge.PortletPhase portletPhase = (PortletPhase) externalContext
.getRequestMap().get(Bridge.PORTLET_LIFECYCLE_PHASE);
if (null != portletPhase) {
log.trace("before phase: " + event.getPhaseId());
FacesLifecycle.setPhaseId(event.getPhaseId());
try {
beforePortletPhase(event, facesContext, portletPhase);
_defaultListener.raiseEventsBeforePhase(event);
} catch (Exception e) {
log.debug("uncaught exception, try to recovery", e);
try {
Exceptions.instance().handle(e);
} catch (Exception ehe) {
log.error("swallowing exception", e);
}
}
} else {
_defaultListener.beforePhase(event);
}
}
private void beforePortletPhase(PhaseEvent event,
FacesContext facesContext, PortletPhase portletPhase) {
boolean notInitialised = false;
if (event.getPhaseId() == RESTORE_VIEW) {
_defaultListener.beforeRestoreView(facesContext);
}
if (event.getPhaseId() == RENDER_RESPONSE
&& !Contexts.isApplicationContextActive()) {
_defaultListener.beforeRestoreView(facesContext);
//restore conversation context, pages
_defaultListener.afterRestoreView(facesContext);
notInitialised = true;
}
// delegate to subclass:
_defaultListener.handleTransactionsBeforePhase(event);
if (event.getPhaseId() == RENDER_RESPONSE) {
if (notInitialised) {
// TODO: restore pages?
// _defaultListener.afterRestoreView(facesContext);
}
_defaultListener.beforeRenderResponse(facesContext);
}
}
/*
* (non-Javadoc)
*
* @see javax.faces.event.PhaseListener#getPhaseId()
*/
public PhaseId getPhaseId() {
return _defaultListener.getPhaseId();
}
}