org.apache.myfaces.orchestra.conversation.jsf
Class AccessScopePhaseListener

java.lang.Object
  extended by org.apache.myfaces.orchestra.conversation.jsf.AccessScopePhaseListener
All Implemented Interfaces:
java.io.Serializable, java.util.EventListener, javax.faces.event.PhaseListener

public class AccessScopePhaseListener
extends java.lang.Object
implements javax.faces.event.PhaseListener

Handle access-scoped conversations.

At the end of request processing, delete any access-scope conversations for which no bean in that scope has been accessed during the render phase of the request. Therefore if a postback occurs which accesses a specific conversation A, and that conversation then forwards to a different view whose render phase does not refer to any bean in conversation A, then the conversation is discarded. This ensures that conversations are discarded as soon as possible, and in particular that if control returns to the a view that accesses conversation A on the next cycle then a new conversation instance is created.

If a view happens to want its postbacks handled by a bean in conversation A, but the render phase never references anything in that conversation, then the conversation will be effectively request-scoped. This is not expected to be a problem in practice as it would be a pretty odd view that has stateful event handling but either renders nothing or fetches its data from somewhere other than the same conversation. If such a case is necessary, the view can be modified to "ping" the conversation in order to keep it active via something like an h:outputText with rendered="#{backingBean.class is null}" (which always resolves to false, ie not rendered, but does force a method-invocation on the backingBean instance). Alternatively, a manual-scoped conversation can be used.

Note that if FacesContext.responseComplete is called during processing, then no phase-listeners for the RENDER_RESPONSE phase are executed. And any navigation rule that specifies "redirect" causes responseComplete to be invoked. Therefore access-scoped beans are not cleaned up immediately. However the view being redirected to always runs its "render" phase only, no postback. The effect, therefore, is exactly the same as when an internal forward is performed to the same view: in both cases, the access-scoped beans are kept if the next view refers to them, and discarded otherwise.

Note also that if responseComplete is invoked by another PhaseListener in the beforePhase for RENDER_RESPONSE then the beforePhase for all other PhaseListeners is still invoked, but no afterPhase methods are invoked. This means that this phase listener will not discard any access-scoped conversations, as that is only done in the afterPhase method. In particular, this applies to tomahawk PPR requests, where the PPRPhaseListener uses responseComplete(). This behaviour is exactly what is wanted; partial-page-rendering should not cause access-scoped conversations to terminate.

Since:
1.1
See Also:
Serialized Form

Constructor Summary
AccessScopePhaseListener()
           
 
Method Summary
 void afterPhase(javax.faces.event.PhaseEvent event)
           
 void beforePhase(javax.faces.event.PhaseEvent event)
           
 javax.faces.event.PhaseId getPhaseId()
           
protected  void invalidateAccessScopedConversations(java.lang.String viewId)
          Invalidates any conversation with aspect ConversationAccessLifetimeAspect which has not been accessed during a http request
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AccessScopePhaseListener

public AccessScopePhaseListener()
Method Detail

getPhaseId

public javax.faces.event.PhaseId getPhaseId()
Specified by:
getPhaseId in interface javax.faces.event.PhaseListener

beforePhase

public void beforePhase(javax.faces.event.PhaseEvent event)
Specified by:
beforePhase in interface javax.faces.event.PhaseListener

afterPhase

public void afterPhase(javax.faces.event.PhaseEvent event)
Specified by:
afterPhase in interface javax.faces.event.PhaseListener

invalidateAccessScopedConversations

protected void invalidateAccessScopedConversations(java.lang.String viewId)
Invalidates any conversation with aspect ConversationAccessLifetimeAspect which has not been accessed during a http request



Copyright © 2008 The Apache Software Foundation. All Rights Reserved.