to.etc.domui.state
Class ConversationContext

java.lang.Object
  extended by to.etc.domui.state.ConversationContext
All Implemented Interfaces:
IQContextContainer
Direct Known Subclasses:
SimpleConversationContext

public class ConversationContext
extends java.lang.Object
implements IQContextContainer

A page's conversational context: a base class. Every page is part of a conversation. For simple pages the conversation mostly "is" the page, meaning that when the page ends the conversation ends also. Conversations are mostly useful for pages that must share data. In that case a single, strongly typed, conversation instance must be created which will contain the data maintained by the multiple pages. The pages themselves are also part of the conversation; when the conversation terminates all page instances associated with the conversation also cease to exist.

Overview

A set of pages can share a given "Conversation Context". The context represents the set of data that the pages handle within a single user interaction. The conversation context is maintained mostly by the server, and it's construction, destruction and initialization-before-request gets handled by the server itself, on request. Pages themselves are always part of a conversation. Pages that do not specify any conversation data are part of a single-shot conversation, where the conversation data is cleared as soon as another page gets instantiated. This ensures that pages are not cached "forever" in the HttpSession. A page joins a conversation if the page gets "linked" to with the conversation context specified. A page which specifies a specific Conversation context and which is created anew without an existing context will cause the Conversation context to be created automatically. Conversations can be nested, and child conversations can access their parents. What state is shared between children and parents (Hibernate session?) is defined by the user. A conversation context is strongly typed, derives from ConversationContext, and is defined on each class which participates in the same conversation. A page identifies that it requires a specific conversation type by specifying it in it's constructor. This can also be used to accept multiple types as a conversation context: simply specify multiple constructors. The page constructor will associate new pages with their appropriate context automatically, by looking in the known context list of a session. This means that when a given page starts another page which accepts the same context it will be created using that context by default.

Life cycle of a ConversationContext

Constructing new contexts

When a page is constructed we check it's constructors. We try to use constructors with contexts first by checking if any of the contexts are "current". If so we instantiate the page and associate it with that context. If none of the contexts is active currently we check if a constructor without context is present; if so we create a "single-shot" context which gets destroyed as soon as the page is left and we instantiate the page. If we have context constructors only we abort if there's > 1 constructor with a context - we cannot decide which context to create. If a single constructor is found specifying a context we'll try to instantiate the class using that conversation context. For that we request a Conversation Context instance from the engine, then call the Page constructor adding any other stuff it needs. This creates a "new" context. The new context gets initialized (using IOC or whatever) immediately, and so is usable by the page immediately.

On request start and request end

Conversation contexts can hold data that needs to be cleared between requests, like database connections or large resources. For resources not maintained by the IOC layer this is the responsibility of the application programmer. Each context has the onAttach() and onDetach() methods which are called when the context is made live and before it gets put to sleep again.

Destruction of contexts

When a Conversation gets destroyed it's onClose() handler gets called, which again can be used to discard any long-lived data maintained by the context. Contexts are destroyed by the framework mostly automatically, as follows:

Author:
Frits Jalvingh Created on Jun 23, 2008

Field Summary
static org.slf4j.Logger LOG
           
 
Constructor Summary
ConversationContext()
           
 
Method Summary
 void checkAttached()
           
 void destroy()
          Force this context to destroy itself.
protected  void discardUploadFiles()
           
 void dump()
           
 java.lang.Object getAttribute(java.lang.String name)
          EXPERIMENTAL DO NOT USE.
 java.lang.String getFullId()
           
 java.lang.String getId()
          Return the ID for this conversation.
 WindowSession getWindowSession()
          Experimental interface: get the WindowSession for this page(set).
 boolean hasDelayedActions()
           
 QDataContextFactory internalGetDataContextFactory()
           
 QDataContext internalGetSharedContext()
           
 void internalRegisterPage(Page p, PageParameters papa)
           
 void internalSetDataContextFactory(QDataContextFactory s)
           
 void internalSetSharedContext(QDataContext c)
           
 boolean isValid()
           
 void onAttach()
          Called when a new request which accesses this context is entering the server.
 void onDestroy()
           
 void onDetach()
          Called when the request has terminated, the response has been rendered and the server is about to exit all handling for the request.
 void processDelayedResults(Page pg)
           
<T extends NodeContainer & IPolledForUpdate>
void
registerPoller(T nc)
          Registers a node as a thingy which needs to be called every polltime seconds to update the screen.
 void registerUploadTempFile(java.io.File f)
          Register a file that was uploaded and that needs to be deleted at end of conversation time.
 DelayedActivityInfo scheduleDelayed(AsyncContainer container, IActivity a)
           
 void setAttribute(java.lang.String name, java.lang.Object val)
          EXPERIMENTAL DO NOT USE.
 void startDelayedExecution()
           
 java.lang.String toString()
           
<T extends NodeContainer & IPolledForUpdate>
void
unregisterPoller(T nc)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

LOG

public static final org.slf4j.Logger LOG
Constructor Detail

ConversationContext

public ConversationContext()
Method Detail

getId

public final java.lang.String getId()
Return the ID for this conversation.

Returns:

getFullId

public java.lang.String getFullId()

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

onAttach

public void onAttach()
              throws java.lang.Exception
Called when a new request which accesses this context is entering the server. This should restore the context to a usable state.

Throws:
java.lang.Exception

onDetach

public void onDetach()
              throws java.lang.Exception
Called when the request has terminated, the response has been rendered and the server is about to exit all handling for the request. This must discard any data that should not be stored between requests, and it must discard any resource like database connections and the like.

Throws:
java.lang.Exception

onDestroy

public void onDestroy()
               throws java.lang.Exception
Throws:
java.lang.Exception

checkAttached

public void checkAttached()

destroy

public void destroy()
Force this context to destroy itself.


internalRegisterPage

public void internalRegisterPage(Page p,
                                 PageParameters papa)

getWindowSession

public WindowSession getWindowSession()
Experimental interface: get the WindowSession for this page(set).

Returns:

setAttribute

public void setAttribute(java.lang.String name,
                         java.lang.Object val)
EXPERIMENTAL DO NOT USE.

Parameters:
name -
val -

getAttribute

public java.lang.Object getAttribute(java.lang.String name)
EXPERIMENTAL DO NOT USE.

Parameters:
name -
Returns:

scheduleDelayed

public DelayedActivityInfo scheduleDelayed(AsyncContainer container,
                                           IActivity a)

startDelayedExecution

public void startDelayedExecution()

processDelayedResults

public void processDelayedResults(Page pg)
                           throws java.lang.Exception
Throws:
java.lang.Exception

hasDelayedActions

public boolean hasDelayedActions()

registerPoller

public <T extends NodeContainer & IPolledForUpdate> void registerPoller(T nc)
Registers a node as a thingy which needs to be called every polltime seconds to update the screen. This is not an asy action by itself (it starts no threads) but it will cause the poll handler to start, and will use the same response mechanism as the asy callback code.

Parameters:
nc -

unregisterPoller

public <T extends NodeContainer & IPolledForUpdate> void unregisterPoller(T nc)

registerUploadTempFile

public void registerUploadTempFile(java.io.File f)
Register a file that was uploaded and that needs to be deleted at end of conversation time.

Parameters:
f -

discardUploadFiles

protected void discardUploadFiles()

dump

public void dump()

isValid

public boolean isValid()

internalGetSharedContext

public QDataContext internalGetSharedContext()
Specified by:
internalGetSharedContext in interface IQContextContainer

internalSetSharedContext

public void internalSetSharedContext(QDataContext c)
Specified by:
internalSetSharedContext in interface IQContextContainer
See Also:
IQContextContainer.internalSetSharedContext(to.etc.webapp.query.QDataContext)

internalGetDataContextFactory

public QDataContextFactory internalGetDataContextFactory()
Specified by:
internalGetDataContextFactory in interface IQContextContainer

internalSetDataContextFactory

public void internalSetDataContextFactory(QDataContextFactory s)
Specified by:
internalSetDataContextFactory in interface IQContextContainer