Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Struts Wiki" for change 
notification.

The "RolloverScope" page has been changed by Bill McCarty:
http://wiki.apache.org/struts/RolloverScope?action=diff&rev1=12&rev2=13

  Attention! This page describes a feature that has not been implemented yet!
  
  = Rollover Scope for Struts 1.x =
- 
- Traditionally web applications use to store state information either in in 
the HTTP request or in the HTTP session. 
+ Traditionally web applications use to store state information either in in 
the HTTP request or in the HTTP session.
  
  If request object is used, state is usually serialized to HTML page as part 
of HTML FORM. In this case moving back and forward along page history changes 
the state. Consider implementing an online store checkout service, using 
request object to store state. After a customer payed for goods, he can click 
Back button and pay again. To prevent this kind of error a token or similar 
facility should be used.
  
@@ -17, +16 @@

  {{attachment:rollover.gif}}
  
  == Rollover scope in a nutshell ==
- 
  A rollover scope is essentially a map stored within session scope. One 
session object can store several associated rollover scopes.
  
  Rollover scope can be used in the following ways:
+ 
   * Directly from application code by calling methods of RolloverScope class. 
[not tested]
   * By passing rollover scope to saveXXX() and loadXXX() methods of Action 
class. [not tested]
   * By specifying rollover scope for an action form in struts-config.xml file. 
[implemented]
  
  A rollover scope can be configured for automatic garbage collection. Two 
techniques are possible:
+ 
   * Specifying removal strategy (by timeout or by request count) and a 
limiting value (number of requests or time to live) at scope creation time. 
Scope will be removed when its lifetime counter exceeds limiting value.
   * Specifying a release property in action mapping; when action forwards to a 
release target, the rollover scope is destroyed.
  
  == Using rollover scope explicitly from application code ==
- 
  (Not all statements of this section are backed up by actual code)
  
  To obtain an instance of a rollover scope use {{{RolloverScope.getInstance}}} 
static method. If the scope you are accessing does not exist and "create" flag 
is true, new scope will be created. When a rollover scope is accessed 
explicitly, its content is not copied to request scope.
@@ -40, +39 @@

  To remove rollover scope from the session object use 
{{{RolloverScope.remove}}} method. If "writeThrough" flag was set at scope 
creation time, rollover data is removed from request scope as well.
  
  == Using saveXXX methods of Action class ==
- 
  TBD
  
  == Using rollover scope to store an action form ==
- 
- In a Struts application a rollover scope can be used in action mapping 
definition just as request and session scopes. To declare a rollover scope for 
an action form specify {{{scope="rollover"}}} in action mapping definition. 
Below is example of a typical use case implemented with two action mappings: a 
Log In component. 
+ In a Struts application a rollover scope can be used in action mapping 
definition just as request and session scopes. To declare a rollover scope for 
an action form specify {{{scope="rollover"}}} in action mapping definition. 
Below is example of a typical use case implemented with two action mappings: a 
Log In component.
  
  One mapping is used for submitting login and password from the browser, 
another mapping use used for rendering either "Not logged in"...
  
  {{attachment:login.gif}}
  
- ...or "logged in" page. 
+ ...or "logged in" page.
  
  {{attachment:logout.gif}}
  
- A rollover scope is used to store form bean in between requests. 
+ A rollover scope is used to store form bean in between requests.
  
  === Rollover-scoped action form, example 1 ===
- 
  This is the simplest way of configuring the rollover scope: just declaring 
the scope as "rollover". The input action inherits from !EventDispatchAction 
and is used as event processor. Events are defined in 'parameter' attribute 
(see !EventDispatchAction for details). Notice that 'scope' has 'rollover' 
value. A removal strategy of with lifetime of one request is defined for 
rollover scope - perfect for most redirect-after-post use cases. Render action 
uses login/logout state to render an appropriate view.
  
  By default, removal strategy is by request count, and maximum lifetime is one 
request. This means, that when you navigate from this action, the "loginform" 
action form will mature, and on a next request it will be removed from session.
  
  {{{<action path = "/logininputaction"
-         type = "org.apache.struts.samples.login.LoginInputAction"
-         name = "loginform"
-         scope = "rollover"
-         validate = "false"
-         parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
  
-         <forward name = "render" path = "/loginrenderaction.do" redirect = 
"true"/>
-         <forward name = "userhome" path = "/userhome.do" redirect = "true"/>
-         <forward name = "cancel" path = "/main.do" redirect = "true"/>
+  . type = "org.apache.struts.samples.login.LoginInputAction" name = 
"loginform" scope = "rollover" validate = "false" parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
+  <forward name = "render" path = "/loginrenderaction.do" redirect = "true"/> 
<forward name = "userhome" path = "/userhome.do" redirect = "true"/> <forward 
name = "cancel" path = "/main.do" redirect = "true"/>
+ 
  </action>
  
  <action path = "/loginrenderaction"
-         type = "org.apache.struts.samples.login.LoginRenderAction"
-         name = "loginform"
-         scope = "rollover"
-         validate  = "false">
  
-         <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/>
-         <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
+  . type = "org.apache.struts.samples.login.LoginRenderAction" name = 
"loginform" scope = "rollover" validate  = "false">
+  <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/> <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
+ 
  </action>}}}
  
  === Rollover-scoped action form, example 2 ===
- 
  This is more complex example which defines the removal strategy and limit 
explicitly using action mapping properties. Properly "rolloverStrategy" 
specifies strategy by timout, and property "rolloverLimit" specifies maximum 
lifetime of the idle rollover scope - 3 minutes.
  
  {{{<action path = "/logininputaction"
-         type = "org.apache.struts.samples.login.LoginInputAction"
-         name = "loginform"
-         scope = "rollover"
-         validate = "false"
-         parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
  
-         <set-property key="rolloverStrategy" value="timeout" />
-         <set-property key="rolloverLimit" value="3" />
+  . type = "org.apache.struts.samples.login.LoginInputAction" name = 
"loginform" scope = "rollover" validate = "false" parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
+  <set-property key="rolloverStrategy" value="timeout" /> <set-property 
key="rolloverLimit" value="3" />
+  <forward name = "render" path = "/loginrenderaction.do" redirect = "true"/> 
<forward name = "userhome" path = "/userhome.do" redirect = "true"/> <forward 
name = "cancel" path = "/main.do" redirect = "true"/>
  
-         <forward name = "render" path = "/loginrenderaction.do" redirect = 
"true"/>
-         <forward name = "userhome" path = "/userhome.do" redirect = "true"/>
-         <forward name = "cancel" path = "/main.do" redirect = "true"/>
  </action>
  
  <action path = "/loginrenderaction"
-         type = "org.apache.struts.samples.login.LoginRenderAction"
-         name = "loginform"
-         scope = "rollover"
-         validate  = "false">
  
-         <set-property key="rolloverStrategy" value="rcount" />
-         <set-property key="rolloverLimit" value="1" />
+  . type = "org.apache.struts.samples.login.LoginRenderAction" name = 
"loginform" scope = "rollover" validate  = "false">
+  <set-property key="rolloverStrategy" value="rcount" /> <set-property 
key="rolloverLimit" value="1" />
+  <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/> <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  
-         <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/>
-         <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  </action>}}}
  
  === Rollover-scoped action form, example 3 ===
- 
  In addition to explicit removal strategy (by request, maximum lifetime is 5 
requests to a session), this configuration specifies conditions for immediate 
removal of the rollover scope. They are defined with "rolloverRelease" 
property, which contains action outcomes for which the rollover scope should be 
deallocated. In the sample below, if the input action chooses 'cancel' or 
'userhome' outcomes, then rollover scope is removed when action finishes. If 
the render action displays user info page a.k.a. logout page, then rollover 
scope is not needed either.
  
  {{{<action path = "/logininputaction"
-         type = "org.apache.struts.samples.login.LoginInputAction"
-         name = "loginform"
-         scope = "rollover"
-         validate = "false"
-         parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
  
-         <set-property key="rolloverStrategy" value="rcount" />
-         <set-property key="rolloverLimit" value="5" />
-         <set-property key="rolloverRelease" value="cancel,userhome" />
+  . type = "org.apache.struts.samples.login.LoginInputAction" name = 
"loginform" scope = "rollover" validate = "false" parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
+  <set-property key="rolloverStrategy" value="rcount" /> <set-property 
key="rolloverLimit" value="5" /> <set-property key="rolloverRelease" 
value="cancel,userhome" />
+  <forward name = "render" path = "/loginrenderaction.do" redirect = "true"/> 
<forward name = "userhome" path = "/userhome.do" redirect = "true"/> <forward 
name = "cancel" path = "/main.do" redirect = "true"/>
  
-         <forward name = "render" path = "/loginrenderaction.do" redirect = 
"true"/>
-         <forward name = "userhome" path = "/userhome.do" redirect = "true"/>
-         <forward name = "cancel" path = "/main.do" redirect = "true"/>
  </action>
  
  <action path = "/loginrenderaction"
-         type = "org.apache.struts.samples.login.LoginRenderAction"
-         name = "loginform"
-         scope = "rollover"
-         validate  = "false">
  
-         <set-property key="rolloverStrategy" value="rcount" />
-         <set-property key="rolloverLimit" value="5" />
-         <set-property key="rolloverRelease" value="loggedin" />
+  . type = "org.apache.struts.samples.login.LoginRenderAction" name = 
"loginform" scope = "rollover" validate  = "false">
+  <set-property key="rolloverStrategy" value="rcount" /> <set-property 
key="rolloverLimit" value="5" /> <set-property key="rolloverRelease" 
value="loggedin" />
+  <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/> <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  
-         <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/>
-         <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  </action>}}}
  
  === Rollover-scoped action form, example 4 ===
- 
  In previous samples the rollover scope was not given name explicitly, so 
action form name was used as rollover scope name: "loginform". It is possible 
to give an explicit name to the rollover scope, using "rolloverId" property, 
for example:
  
  {{{<action path = "/logininputaction"
-         type = "org.apache.struts.samples.login.LoginInputAction"
-         name = "loginform"
-         scope = "rollover"
-         validate = "false"
-         parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
  
+  . type = "org.apache.struts.samples.login.LoginInputAction" name = 
"loginform" scope = "rollover" validate = "false" parameter = 
"initEvent=init,loginEvent=login,cancelEvent=cancel,logoutEvent=logout">
-         <set-property key="rolloverId" value="MyLoginRollover" />
+  <set-property key="rolloverId" value="MyLoginRollover" />
+  <forward name = "render" path = "/loginrenderaction.do" redirect = "true"/> 
<forward name = "userhome" path = "/userhome.do" redirect = "true"/> <forward 
name = "cancel" path = "/main.do" redirect = "true"/>
  
-         <forward name = "render" path = "/loginrenderaction.do" redirect = 
"true"/>
-         <forward name = "userhome" path = "/userhome.do" redirect = "true"/>
-         <forward name = "cancel" path = "/main.do" redirect = "true"/>
  </action>
  
  <action path = "/loginrenderaction"
-         type = "org.apache.struts.samples.login.LoginRenderAction"
-         name = "loginform"
-         scope = "rollover"
-         validate  = "false">
  
+  . type = "org.apache.struts.samples.login.LoginRenderAction" name = 
"loginform" scope = "rollover" validate  = "false">
-         <set-property key="rolloverId" value="MyLoginRollover" />
+  <set-property key="rolloverId" value="MyLoginRollover" />
+  <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/> <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  
-         <forward name = "notloggedin" path = 
"/logindialog/logincomponent-login.jsp"/>
-         <forward name = "loggedin" path = 
"/logindialog/logincomponent-logout.jsp"/>
  </action>}}}
  
  === Rollover-scoped action form, example 5 ===
- 
  It is possible to have several instances of rollover scope per action. 
Consider a typical CRUD application, it displays a list of customer orders. 
Every order line contains !View and !Edit links. If you click on !Edit link, 
then an order edit form is displayed. To select a specific order, an order id 
is passed to the server as HTTP parameter. Say, you want to open several order 
forms in different windows. You would like to right-click the !Edit link and 
select "Open in separate browser window". This would be hard to do with saving 
state in the session, but is easy with rollover scope.
  
- All you need to do is to define your !Edit link so that it contained 
parameter with the same name as value of "rolloverId" parameter. The value of 
this HTTP parameter will be concatenated with base rollover id to form a 
complete name. This is easier to show with code sample. 
+ All you need to do is to define your !Edit link so that it contained 
parameter with the same name as value of "rolloverId" parameter. The value of 
this HTTP parameter will be concatenated with base rollover id to form a 
complete name. This is easier to show with code sample.
  
  {{{<action path = "/orderinputaction"
-         type = "org.apache.struts.samples.OrderInputAction"
-         name = "orderform"
-         scope = "rollover"
-         validate = "false"
-         parameter = "editEvent=edit,viewEvent=view>
  
+  . type = "org.apache.struts.samples.OrderInputAction" name = "orderform" 
scope = "rollover" validate = "false" parameter = 
"editEvent=edit,viewEvent=view>
-         <set-property key="rolloverId" value="orderId" />
+  <set-property key="rolloverId" value="orderId" />
+  <forward name = "render" path = "/orderrenderaction.do" redirect = "true"/> 
<forward name = "cancel" path = "/orderlist.do" redirect = "true"/>
  
-         <forward name = "render" path = "/orderrenderaction.do" redirect = 
"true"/>
-         <forward name = "cancel" path = "/orderlist.do" redirect = "true"/>
  </action>
  
  {{{<action path = "/orderrenderaction"
-         type = "org.apache.struts.samples.OrderRenderAction"
-         name = "orderform"
-         scope = "rollover"
-         validate  = "false">
  
+  . type = "org.apache.struts.samples.OrderRenderAction" name = "orderform" 
scope = "rollover" validate  = "false">
-         <set-property key="rolloverId" value="orderId" />
+  <set-property key="rolloverId" value="orderId" />
+  <forward name = "edit" path = "/order/editorder.jsp"/>
  
-         <forward name = "edit" path = "/order/editorder.jsp"/>
  </action>}}}
  
- The mapping above is similar to mapping in Example 4. Now the crucial part: 
the Edit links. They may look like this: 
+ The mapping above is similar to mapping in Example 4. Now the crucial part: 
the Edit links. They may look like this:
  
  {{{
  orderrenderaction?itemId=1701
  }}}
- 
  When this request is submitted, rollover scope manager will look up 
"rolloverId" property in the action mapping, it has value "orderId". Then it 
will look up "orderId" request parameter and read its value, it is "1701". Then 
it will concatenate parameter name and value, producing "orderId1701", this 
will be the name of rollover scope for order 1701.
  
  As you see, for this particular use case the natural ID makes a perfect 
rollover scope name. For other use cases you may need to create artificial IDs.
@@ -225, +164 @@

  Several core classes have been updated to accommodate usage of rollover 
scope. Two new commands have been added to default chain.
  
  === New: org.apache.struts.scope.RolloverScope ===
- Instances of this class store rollover-scoped data; the class implements Map. 
Static methods of this class obtain/create /remove a rollover scope instance. 
+ Instances of this class store rollover-scoped data; the class implements Map. 
Static methods of this class obtain/create /remove a rollover scope instance.
  
  === New: org.apache.struts.chain.commands.LoadRolloverData ===
  This command must be specified in chain config file before !CreateActionForm 
command; it matures all rollover scopes corresponding to current session, 
removes aged scopes, looks up for a rollover scope corresponding to an action 
mapping and loads rollover data into request scope to ensure that JSP tags 
perform properly.
@@ -237, +176 @@

  Added {{{getRolloverScope}}} method along with "rollover" literal to be used 
in action mapping definition.
  
  === Updated: org.apache.struts.chain.contexts.ActionContextBase ===
- Method {{{getScope}}} now looks up for rollover scope along with standard 
J2EE scopes. 
+ Method {{{getScope}}} now looks up for rollover scope along with standard 
J2EE scopes.
  
  === Updated: org.apache.struts.chain.contexts.WebActionContext ===
  Defines getRolloverScope method, which obtains/creates rollover scope based 
on current webcontext and request scope. This method is used by 
{{{ActionContextBase.getScope}}} method.

Reply via email to