EMMA Coverage Report (generated Tue May 18 22:13:27 CDT 2004)
[all classes][org.apache.velocity.runtime.directive]

COVERAGE SUMMARY FOR SOURCE FILE [Foreach.java]

nameclass, %method, %block, %line, %
Foreach.java100% (1/1)100% (5/5)96%  (139/145)91%  (31/34)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Foreach100% (1/1)100% (5/5)96%  (139/145)91%  (31/34)
render (InternalContextAdapter, Writer, Node): boolean 100% (1/1)94%  (94/100)88%  (22/25)
Foreach (): void 100% (1/1)100% (3/3)100% (1/1)
getName (): String 100% (1/1)100% (2/2)100% (1/1)
getType (): int 100% (1/1)100% (2/2)100% (1/1)
init (RuntimeServices, InternalContextAdapter, Node): void 100% (1/1)100% (38/38)100% (6/6)

1package org.apache.velocity.runtime.directive;
2 
3/*
4 * Copyright 2000-2001,2004 The Apache Software Foundation.
5 * 
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 * 
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 * 
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 
19import java.io.Writer;
20import java.io.IOException;
21 
22import java.util.Iterator;
23 
24import org.apache.velocity.runtime.RuntimeServices;
25import org.apache.velocity.runtime.RuntimeConstants;
26 
27import org.apache.velocity.context.InternalContextAdapter;
28 
29import org.apache.velocity.runtime.parser.node.Node;
30 
31import org.apache.velocity.exception.MethodInvocationException;
32import org.apache.velocity.exception.ParseErrorException;
33import org.apache.velocity.exception.ResourceNotFoundException;
34 
35import org.apache.velocity.util.introspection.Info;
36 
37/**
38 * Foreach directive used for moving through arrays,
39 * or objects that provide an Iterator.
40 *
41 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
42 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
43 * @version $Id: Foreach.java,v 1.42.4.1 2004/03/03 23:22:55 geirm Exp $
44 */
45public class Foreach extends Directive
46{
47    /**
48     * Return name of this directive.
49     */
50    public String getName()
51    {
52        return "foreach";
53    }        
54    
55    /**
56     * Return type of this directive.
57     */
58    public int getType()
59    {
60        return BLOCK;
61    }        
62 
63    /**
64     * The name of the variable to use when placing
65     * the counter value into the context. Right
66     * now the default is $velocityCount.
67     */
68    private String counterName;
69 
70    /**
71     * What value to start the loop counter at.
72     */
73    private int counterInitialValue;
74 
75    /**
76     * The reference name used to access each
77     * of the elements in the list object. It
78     * is the $item in the following:
79     *
80     * #foreach ($item in $list)
81     *
82     * This can be used class wide because
83     * it is immutable.
84     */
85    private String elementKey;
86 
87    /**
88     *  immutable, so create in init
89     */
90    protected Info uberInfo;
91 
92    /**
93     *  simple init - init the tree and get the elementKey from
94     *  the AST
95     */
96    public void init(RuntimeServices rs, InternalContextAdapter context, Node node)
97        throws Exception
98    {
99        super.init(rs, context, node);
100 
101        counterName = rsvc.getString(RuntimeConstants.COUNTER_NAME);
102        counterInitialValue = rsvc.getInt(RuntimeConstants.COUNTER_INITIAL_VALUE);
103 
104        /*
105         *  this is really the only thing we can do here as everything
106         *  else is context sensitive
107         */
108 
109        elementKey = node.jjtGetChild(0).getFirstToken().image.substring(1);
110 
111        /*
112         * make an uberinfo - saves new's later on
113         */
114 
115        uberInfo = new Info(context.getCurrentTemplateName(),
116                getLine(),getColumn());
117    }
118 
119    /**
120     *  renders the #foreach() block
121     */
122    public boolean render(InternalContextAdapter context,
123                           Writer writer, Node node)
124        throws IOException,  MethodInvocationException, ResourceNotFoundException,
125                ParseErrorException
126    {        
127        /*
128         *  do our introspection to see what our collection is
129         */
130 
131        Object listObject = node.jjtGetChild(2).value(context);
132 
133        if (listObject == null)
134             return false;
135 
136        Iterator i = null;
137 
138        try
139        {
140            i = rsvc.getUberspect().getIterator(listObject, uberInfo);
141        }
142        catch(Exception ee)
143        {
144            System.out.println(ee);
145        }
146 
147        if (i == null)
148        {
149            return false;
150        }
151 
152        int counter = counterInitialValue;
153        
154        /*
155         *  save the element key if there is one,
156         *  and the loop counter
157         */
158 
159        Object o = context.get(elementKey);
160        Object ctr = context.get( counterName);
161 
162        while (i.hasNext())
163        {
164            context.put( counterName , new Integer(counter));
165            context.put(elementKey,i.next());
166            node.jjtGetChild(3).render(context, writer);
167            counter++;
168        }
169 
170        /*
171         * restores the loop counter (if we were nested)
172         * if we have one, else just removes
173         */
174        
175        if (ctr != null)
176        {
177            context.put(counterName, ctr);
178        }
179        else
180        {
181            context.remove(counterName);
182        }
183 
184 
185        /*
186         *  restores element key if exists
187         *  otherwise just removes
188         */
189 
190        if (o != null)
191        {
192            context.put(elementKey, o);
193        }
194        else
195        {
196            context.remove(elementKey);
197        }
198 
199        return true;
200    }
201}

[all classes][org.apache.velocity.runtime.directive]
EMMA 2.0.4015 (stable) (C) Vladimir Roubtsov