As Matt Ho explained on the mailing list:
A value stack is essentially a List. Calling \ [1] on the stack,
Wiki Markup
returns a substack beginning with the element at index 1. It's only
when you call methods on the stack that your actual objects will be
called.
Said another way, let's say I have a value stack that consists of a
model and an action as follows:unmigrated-wiki-markup
\ [ WW: model, action \ ]
here's how the following ognl would resolve:unmigrated-wiki-markup
\ [WW:0\] - a CompoundRoot object that contains our stack, \ [WW:model, action\] Wiki Markup
\ [WW:1\] - another CompoundRoot that contains only \ [WW:action\]
\ [WW:0\].toString() - calls toString() on the first object in the value
Wiki Markup
stack (excluding the CompoundRoot) that supports the toString() methodunmigrated-wiki-markup
\ [WW:1\].foo - call getFoo() on the first object in the value stack
starting from \ [OS:action] and excluding the CompoundRoot that supports a
getFoo() method
I hope this doesn't sound too confusing :\
If you're using Velocity, this can most easily be written as:unmigrated-wiki-markup
$stack.findValue("\[WW:0\]").peek()unmigrated-wiki-markup
Unfortunately, <ww:property value="\[WW:0\].peek()"/> won't work as this
would translate into "starting at the top of the value stack (and
excluding the CompoundRoot), find the first object that has a method
called peek()"
--------thanks Matt!
here is the com.opensymphony.xwork.util.CompoundRoot class which Matt mentions:
...