package com.joe.utilities.core.jsf.listeners;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class FacesMessagesMultiPageSupport implements PhaseListener {
private static final long serialVersionUID = 1250469273857785274L;
private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";
public PhaseId getPhaseId()
{
return PhaseId.ANY_PHASE;
}
/*
* Check to see if we are "naturally" in the RENDER_RESPONSE phase. If we
* have arrived here and the response is already complete, then the page is
* not going to show up: don't display messages yet.
*/
public void beforePhase(final PhaseEvent event)
{
FacesContext facesContext = event.getFacesContext();
this.saveMessages(facesContext);
if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
{
if (!facesContext.getResponseComplete())
{
this.restoreMessages(facesContext);
}
}
}
/*
* Save messages into the session after every phase.
*/
public void afterPhase(final PhaseEvent event)
{
if (!PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
{
FacesContext facesContext = event.getFacesContext();
this.saveMessages(facesContext);
}
}
@SuppressWarnings("unchecked")
private int saveMessages(final FacesContext facesContext)
{
List<FacesMessage> newMessageList = new ArrayList<FacesMessage>();
for (Iterator<FacesMessage> iter = facesContext.getMessages(null); iter.hasNext();)
{
newMessageList.add(iter.next());
iter.remove();
}
if (newMessageList.size() == 0)
{
return 0;
}
Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
List<FacesMessage> existingMessages = (List<FacesMessage>) sessionMap.get(sessionToken);
if (existingMessages != null)
{
// only add messages that don't already exist
for (FacesMessage facesMessage : newMessageList) {
if (!existingMessages.contains(facesMessage)) {
existingMessages.add(facesMessage);
}
}
}
else
{
sessionMap.put(sessionToken, newMessageList);
}
return newMessageList.size();
}
@SuppressWarnings("unchecked")
private int restoreMessages(final FacesContext facesContext)
{
Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
List<FacesMessage> messagesFromSession = (List<FacesMessage>) sessionMap.remove(sessionToken);
if (messagesFromSession == null)
{
return 0;
}
int restoredCount = messagesFromSession.size();
// loop through messages on session and only add message back to context if not present
for (FacesMessage facesMessage : messagesFromSession) {
boolean found = false;
for(Iterator<FacesMessage> iter = facesContext.getMessages(null); iter.hasNext();) {
if (iter.next().equals(facesMessage)) {
found=true;
break;
}
}
if (!found) {
facesContext.addMessage(null, facesMessage);
}
}
// update the messages managed bean with all faces messages
//TODO
//MessagesSupportView msv = (MessagesSupportView)ManagedBeanUtility.getBindingObject("#{MessagesSupportBean}");
//msv.updateFacesMessages(facesContext.getMessages());
return restoredCount;
}
}