struts-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Tom Schneider (JIRA)" <j...@apache.org>
Subject [jira] Assigned: (WW-1514) Conversation Scope
Date Fri, 02 Nov 2007 13:08:40 GMT

     [ https://issues.apache.org/struts/browse/WW-1514?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Tom Schneider reassigned WW-1514:
---------------------------------

    Assignee: Tom Schneider

> Conversation Scope
> ------------------
>
>                 Key: WW-1514
>                 URL: https://issues.apache.org/struts/browse/WW-1514
>             Project: Struts 2
>          Issue Type: New Feature
>          Components: Core Interceptors
>            Reporter: Mark Menard
>            Assignee: Tom Schneider
>            Priority: Minor
>             Fix For: 2.1.1
>
>         Attachments: ConversationModelDriven.java, ConversationModelInterceptor.java,
ConversationScopeAware.java, ConversationScopeInterceptor.java
>
>
> Problem: A user may need to, or be able to use, multiple tabs on the same work flow process,
 using different data, that would usually be stored in the user's session. The problem is
if you use the Session scope you can only have one version of the users data in memory. This
can result in a "crossing of the streams" between their two (or more) independent work flows.
Ad-hoc solutions on a per action basis could be implemented, but this is awkward at best.
> Example: User opens two processes of the same type, using the same action(s), in separate
tabs in their browser, working on independent data sets. Each data model must be stored separately
in their session.
> Solution: Implement a "Conversation Scope" using an Interceptor and a marker interface
for Actions to implement that will transparently manage multiple independent conversations
of the same type on independent data sets.
> ConversationScopeInterceptor: This interceptor does the hard lifting. It maintains a
conversationMap in each users session that allows for the storage of multiple converstaionModels.
The conversationModels are keyed using an incrementing int, and the current time in milliseconds
when the conversation began. The incrementing of the conversation counter is synchronized.
Additionally the interceptor pushes the conversationModel onto the ValueStack much the same
way as ModelDriven pushes the model onto the ValueStack.
> ConversationScopeAware: This is a marker interface for Actions to implement. It includes
methods to set/get the conersationId, set/get/prepare the conversationModel. prepareConversationModel()
is called at the start of a conversation and allows the action to prepare the data model the
user will be working with over the conversation.
> Motivation: The major motivation for this was work that we did in Struts 1 to work around
the pervasive use of session forms. We realized that users could cross the streams with multiple
forms in memory. To work around this we created a deep Action hierarchy that handled swapping
the "conversation" data into and out of a Map backed form. Although Struts 2 does not suffer
from the same pervasive need to use session forms there are times when a conversation is needed
and with modern browsers and the wide usage of tabs, it is just a matter of time before a
user opens two tabs on the same type of conversation.
> View requirements: In order to track the conversation the HTML form must contain:
> <input type="hidden" name="S2_CONVERSATION_ID" value="<the_current conversation_id">
> The current conversation id is available as a property of any Action that implements
ConversationScopeAware and can be included with the following:
> <s:hidden name="S2_CONVERSATION_ID" value="%{conversationId}" />
> Possible Improvements: Slip stream this right into ModelAware, and just use getModel()
from the ModelAware interface and supplement it with set and prepare methods. I didn't want
to do that initially because I'm not sure it would be appropriate, nor do I like non-explicit
things. It would make moving a model aware action to a conversation model scope easier, but
using coversationModel just means changing getModel() to getConversationModel() in your action.
> Additionally this could be improved by setting the conversatonId onto the ValueStack,
and retrieving it off the stack in the view. This would allow for the removal of the get/setConversationId()
from the ConversationScopeAware interface. I just couldn't figure out how to do that.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message