import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Observer; import org.jboss.seam.annotations.Scope; import org.jboss.seam.log.Log; @Scope(ScopeType.EVENT) @Name("conversationTimeoutWorkaround") public class ConversationTimeoutWorkaround { private List timeoutIds = new ArrayList(); @Logger private Log log; @In(required=false) private FacesContext facesContext; @Observer("org.jboss.seam.conversationTimeout") public void conversationTimeout(String id) { if (log.isDebugEnabled()) { log.debug("conversationTimeout(): id: " + id + ", this: " + this); } timeoutIds.add(id); } @Observer("org.jboss.seam.preDestroyContext.EVENT") public void cleanOrphan() { if (facesContext == null || timeoutIds.isEmpty()) { return; } for (Iterator it = timeoutIds.iterator(); it.hasNext(); ) { String id = it.next(); Map sessionMap = facesContext.getExternalContext().getSessionMap(); removeIfExists(sessionMap, ScopeType.CONVERSATION.getPrefix() + '#' + id + "$org.jboss.seam.persistence.persistenceContexts"); removeIfExists(sessionMap, ScopeType.CONVERSATION.getPrefix() + '#' + id + "$org.jboss.seam.bpm.businessProcess"); } timeoutIds.clear(); } private void removeIfExists(Map sessionMap, String key) { if (log.isDebugEnabled()) { log.debug("cleanOrphan(): key: " + key + ", this: " + this); log.debug("sessionMap: " + sessionMap); } if (sessionMap.containsKey(key)) { sessionMap.remove(key); if (log.isDebugEnabled()) { log.debug("removed, key: " + key); } } } }