KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > directive > Foreach


1 package 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
19 import java.io.Writer JavaDoc;
20 import java.io.IOException JavaDoc;
21
22 import java.util.Iterator JavaDoc;
23
24 import org.apache.velocity.runtime.RuntimeServices;
25 import org.apache.velocity.runtime.RuntimeConstants;
26
27 import org.apache.velocity.context.InternalContextAdapter;
28
29 import org.apache.velocity.runtime.parser.node.Node;
30
31 import org.apache.velocity.exception.MethodInvocationException;
32 import org.apache.velocity.exception.ParseErrorException;
33 import org.apache.velocity.exception.ResourceNotFoundException;
34
35 import 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  */

45 public class Foreach extends Directive
46 {
47     /**
48      * Return name of this directive.
49      */

50     public String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc
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 JavaDoc writer, Node node)
124         throws IOException JavaDoc, MethodInvocationException, ResourceNotFoundException,
125             ParseErrorException
126     {
127         /*
128          * do our introspection to see what our collection is
129          */

130
131         Object JavaDoc listObject = node.jjtGetChild(2).value(context);
132
133         if (listObject == null)
134              return false;
135
136         Iterator JavaDoc i = null;
137
138         try
139         {
140             i = rsvc.getUberspect().getIterator(listObject, uberInfo);
141         }
142         catch(Exception JavaDoc 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 JavaDoc o = context.get(elementKey);
160         Object JavaDoc ctr = context.get( counterName);
161
162         while (i.hasNext())
163         {
164             context.put( counterName , new Integer JavaDoc(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 }
202
Popular Tags