类 LoopTool
A convenience tool to use with #foreach loops. It wraps a list with a custom iterator to provide additional controls and feedback for managing loops.
This tool was originally inspired the now-deprecated IteratorTool, which provided similar base functionality but was somewhat more difficult to understand and use. Rather than try to migrate that implementation via deprecation and new methods, it was simplest to just create an entirely new tool that simplified the original API and was easy to augment with useful new features like support for nested (and nameable) loops, skipping ahead in loops, synchronizing multiple iterators, getting the iteration count of loops, identifying if a loop is on its first or last iteration, and so on.
Most functions of this tool will be obsolete with the release of Velocity 1.7, which will provide $foreach.hasNext, $foreach.isFirst, $foreach.isLast, $foreach.index and $foreach.count automatically. However, this will still be useful for the more advanced sync and skip features. Also, for very complicated nested loops, the loop naming feature may be easier than doing things like $foreach.parent.parent.
Example of use:
Template --- #set( $list = [1..7] ) #set( $others = [3..10] ) #foreach( $item in $loop.watch($list).sync($others, 'other') ) $item -> $loop.other #if( $item >= 5 )$loop.stop()#end #end Output ------ 1 -> 3 2 -> 4 3 -> 5 4 -> 6 5 -> 7 Example tools.xml config (if you want to use this with VelocityView): <tools> <toolbox scope="request"> <tool class="org.apache.velocity.tools.generic.LoopTool"/> </toolbox> </tools>
- 版本:
- $Id: LoopTool.java 590893 2007-11-01 04:40:21Z nbubna $
- 作者:
- Nathan Bubna
-
嵌套类概要
嵌套类修饰符和类型类说明static enum
Represents an automatic action taken by aLoopTool.ManagedIterator
when aLoopTool.Condition
is satisfied by the subsequent element.static class
Composition class which associates anLoopTool.Action
andLoopTool.Condition
for aLoopTool.ManagedIterator
.static class
Base condition class for conditions (assumption here is that conditions are all comparative.static interface
Represents a function into which aLoopTool.ManagedIterator
can pass it's next element to see if anLoopTool.Action
should be taken.static class
Simple condition that checks elements in the iterator for equality to a specified Object.static class
Iterator implementation that wraps a standardIterator
and allows it to be prematurely stopped, skipped ahead, and associated with a name for advanced nested loop control.static class
Simple wrapper to make it easy to keep an arbitray Iterator in sync with aLoopTool.ManagedIterator
. -
字段概要
字段 -
构造器概要
构造器 -
方法概要
修饰符和类型方法说明protected LoopTool.ManagedIterator
findIterator
(String name) Finds theLoopTool.ManagedIterator
with the specified name if it is in this instance's iterator stack.This serves two purposes: Getting the current value of a sync'ed iterator Abbreviate syntax for properties of outer loopsAsks the loop with the specified name for the current value of the specified sync'ed iterator, if any.getCount()
Returns the number of items the current loop has handled.Returns the number of items the specified loop has handled.int
getDepth()
Returns the number of loops currently on the stack.getFirst()
Returns the result ofisFirst()
.getIndex()
Returns the 0-based index of the item the current loop is handling.Returns the 0-based index of the item the specified loop is handling.protected static Iterator
getIterator
(Object obj) Wraps access toClassUtils.getIterator(java.lang.Object)
is a nice little try/catch block to prevent exceptions from escaping into the template.getLast()
Returns the result ofisLast()
.getThis()
Returns the most recentLoopTool.ManagedIterator
for this instance.isFirst()
Returnstrue
if the current loop is on its first iteration.Returnstrue
if the loop with the specified name is on its first iteration.isLast()
Returnstrue
if the current loop is on its last iteration.Returnstrue
if the loop with the specified name is on its last iteration.protected LoopTool.ManagedIterator
protected LoopTool.ManagedIterator
pop()
Don't let templates call this, but allow subclasses and ManagedIterator to have access.void
skip
(int number) Skips ahead the specified number of iterations (if possible).void
This tells the specified loop to skip ahead the specified number of iterations.private void
skip
(int number, LoopTool.ManagedIterator iterator) void
stop()
This tells the current loop to stop after the current iteration.void
This is just likestop()
except that the stop command is issued only to the loop/iterator with the specified name.void
stopAll()
This is just likestop()
except that the stop command is issued all the loops being watched by this tool.void
This is just likestop(String)
except that the stop command is issued both to the loop/iterator with the specified name and all loops nested within it.Tells the LoopTool to watch the specified Array, Collection, Map, Iterator, Iterable, Enumeration or POJO with an iterator() method while the template iterates over the values within it.This is just likewatch(Object)
except that it also takes a name which is given to theLoopTool.ManagedIterator
that is returned.
-
字段详细资料
-
iterators
-
last
-
-
构造器详细资料
-
LoopTool
public LoopTool()
-
-
方法详细资料
-
watch
Tells the LoopTool to watch the specified Array, Collection, Map, Iterator, Iterable, Enumeration or POJO with an iterator() method while the template iterates over the values within it.
Under the covers, this is returning an iterable wrapper that is also pushed onto this tool's stack. That allows this tool to know which iterator to give later commands (i.e. stop() or skip()).
- 参数:
obj
- an object that Velocity's #foreach directive can iterate over- 返回:
- a
LoopTool.ManagedIterator
that this tool instance will track
-
watch
This is just likewatch(Object)
except that it also takes a name which is given to theLoopTool.ManagedIterator
that is returned. This allows the user to send stop or skip commands to that specific iterator even when there are nested iterators within it that are being watched. If the given name isnull
, then this will returnnull
even if the object can be watched. Provided names cannot benull
.- 另请参阅:
-
sync
-
manage
-
stop
public void stop()This tells the current loop to stop after the current iteration. This is different from "break" common to most programming languages, in that it does not immediately cease activity in the current iteration. Instead, it merely tells the #foreach loop that this is the last time around. -
stop
This is just likestop()
except that the stop command is issued only to the loop/iterator with the specified name. If no such loop is found with that name, then no stop command is issued.- 另请参阅:
-
stopTo
This is just likestop(String)
except that the stop command is issued both to the loop/iterator with the specified name and all loops nested within it. If no such loop is found with that name, then no stop commands are issued.- 另请参阅:
-
stopAll
public void stopAll()This is just likestop()
except that the stop command is issued all the loops being watched by this tool.- 另请参阅:
-
skip
public void skip(int number) Skips ahead the specified number of iterations (if possible). Since this is manual skipping (unlike the automatic skipping provided by the likes ofLoopTool.ManagedIterator.exclude(Object)
, any elements skipped are still considered in the results returned bygetCount()
andisFirst()
. -
skip
This tells the specified loop to skip ahead the specified number of iterations.- 另请参阅:
-
skip
-
isFirst
Returnstrue
if the current loop is on its first iteration. -
isFirst
Returnstrue
if the loop with the specified name is on its first iteration. -
getFirst
Returns the result ofisFirst()
. Exists to allow $loop.first syntax. -
isLast
Returnstrue
if the current loop is on its last iteration. -
isLast
Returnstrue
if the loop with the specified name is on its last iteration. -
getLast
Returns the result ofisLast()
. Exists to allow $loop.last syntax. -
get
This serves two purposes:
- Getting the current value of a sync'ed iterator
- Abbreviate syntax for properties of outer loops
First, it searches all the loops being managed for one with a sync'ed Iterator under the specified name and returns the current value for that sync'ed iterator, if any. If there is no sync'ed iterators or none with that name, then this will check if the specified key is requesting a "property" of an outer loop (e.g.
$loop.count_foo
or$loop.first_foo
). This syntax is shorter and clearer than$loop.getCount('foo')
. If the key starts with a property name and ends with an outer loop name, then the value of that property for that loop is returned. -
get
Asks the loop with the specified name for the current value of the specified sync'ed iterator, if any. -
getIndex
Returns the 0-based index of the item the current loop is handling. So, if this is the first iteration, then the index will be 0. If youskip(int)
ahead in this loop, those skipped iterations will still be reflected in the index. If iteration has not begun, this will returnnull
. -
getIndex
Returns the 0-based index of the item the specified loop is handling. So, if this is the first iteration, then the index will be 0. If youskip(int)
ahead in this loop, those skipped iterations will still be reflected in the index. If iteration has not begun, this will returnnull
. -
getCount
Returns the number of items the current loop has handled. So, if this is the first iteration, then the count will be 1. If youskip(int)
ahead in this loop, those skipped iterations will still be included in the count. -
getCount
Returns the number of items the specified loop has handled. So, if this is the first iteration, then the count will be 1. If youskip(int)
ahead in this loop, those skipped iterations will still be included in the count. -
getThis
Returns the most recentLoopTool.ManagedIterator
for this instance. This can be used to access properties like the count, index, isFirst, isLast, etc which would otherwise fail on the last item in a loop due to the necessity of popping iterators off the stack when the last item is retrieved. (See VELTOOLS-124) -
getDepth
public int getDepth()Returns the number of loops currently on the stack. This is only useful for debugging, as iterators are popped off the stack at the start of their final iteration, making this frequently "incorrect". -
findIterator
Finds theLoopTool.ManagedIterator
with the specified name if it is in this instance's iterator stack. -
pop
Don't let templates call this, but allow subclasses and ManagedIterator to have access. -
getIterator
Wraps access toClassUtils.getIterator(java.lang.Object)
is a nice little try/catch block to prevent exceptions from escaping into the template. In the case of such problems, this will returnnull
.
-