Source Code Cross Referenced for Foreach.java in  » Template-Engine » Velocity » org » apache » velocity » runtime » directive » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » Velocity » org.apache.velocity.runtime.directive 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.runtime.directive;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.    
020:         */
021:
022:        import java.io.IOException;
023:        import java.io.Writer;
024:        import java.util.Iterator;
025:
026:        import org.apache.velocity.app.event.EventCartridge;
027:        import org.apache.velocity.context.Context;
028:        import org.apache.velocity.context.InternalContextAdapter;
029:        import org.apache.velocity.exception.MethodInvocationException;
030:        import org.apache.velocity.exception.ParseErrorException;
031:        import org.apache.velocity.exception.ResourceNotFoundException;
032:        import org.apache.velocity.exception.TemplateInitException;
033:        import org.apache.velocity.runtime.RuntimeConstants;
034:        import org.apache.velocity.runtime.RuntimeServices;
035:        import org.apache.velocity.runtime.parser.node.ASTReference;
036:        import org.apache.velocity.runtime.parser.node.Node;
037:        import org.apache.velocity.runtime.parser.node.SimpleNode;
038:        import org.apache.velocity.runtime.resource.Resource;
039:        import org.apache.velocity.util.introspection.Info;
040:        import org.apache.velocity.util.introspection.IntrospectionCacheData;
041:
042:        /**
043:         * Foreach directive used for moving through arrays,
044:         * or objects that provide an Iterator.
045:         *
046:         * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
047:         * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
048:         * @author Daniel Rall
049:         * @version $Id: Foreach.java 479060 2006-11-25 00:30:19Z henning $
050:         */
051:        public class Foreach extends Directive {
052:            /**
053:             * A special context to use when the foreach iterator returns a null.  This
054:             * is required since the standard context may not support nulls.
055:             * All puts and gets are passed through, except for the foreach iterator key.
056:             */
057:            protected static class NullHolderContext implements 
058:                    InternalContextAdapter {
059:                private InternalContextAdapter innerContext = null;
060:                private String loopVariableKey = "";
061:                private boolean active = true;
062:
063:                /**
064:                 * Create the context as a wrapper to be used within the foreach
065:                 * @param key the reference used in the foreach
066:                 * @param context the parent context
067:                 */
068:                private NullHolderContext(String key,
069:                        InternalContextAdapter context) {
070:                    innerContext = context;
071:                    if (key != null)
072:                        loopVariableKey = key;
073:                }
074:
075:                /**
076:                 * Get an object from the context, or null if the key is equal to the loop variable
077:                 * @see org.apache.velocity.context.InternalContextAdapter#get(java.lang.String)
078:                 * @exception MethodInvocationException passes on potential exception from reference method call
079:                 */
080:                public Object get(String key) throws MethodInvocationException {
081:                    return (active && loopVariableKey.equals(key)) ? null
082:                            : innerContext.get(key);
083:                }
084:
085:                /**
086:                 * @see org.apache.velocity.context.InternalContextAdapter#put(java.lang.String key, java.lang.Object value)
087:                 */
088:                public Object put(String key, Object value) {
089:                    if (loopVariableKey.equals(key) && (value == null)) {
090:                        active = true;
091:                    }
092:
093:                    return innerContext.put(key, value);
094:                }
095:
096:                /**
097:                 * Allows callers to explicitly put objects in the local context.
098:                 * Objects added to the context through this method always end up
099:                 * in the top-level context of possible wrapped contexts.
100:                 *
101:                 * @param key name of item to set.
102:                 * @param value object to set to key.
103:                 * @see org.apache.velocity.context.InternalWrapperContext#localPut(String, Object)
104:                 */
105:                public Object localPut(final String key, final Object value) {
106:                    return put(key, value);
107:                }
108:
109:                /**
110:                 * Does the context contain the key
111:                 * @see org.apache.velocity.context.InternalContextAdapter#containsKey(java.lang.Object key)
112:                 */
113:                public boolean containsKey(Object key) {
114:                    return innerContext.containsKey(key);
115:                }
116:
117:                /**
118:                 * @see org.apache.velocity.context.InternalContextAdapter#getKeys()
119:                 */
120:                public Object[] getKeys() {
121:                    return innerContext.getKeys();
122:                }
123:
124:                /**
125:                 * Remove an object from the context
126:                 * @see org.apache.velocity.context.InternalContextAdapter#remove(java.lang.Object key)
127:                 */
128:                public Object remove(Object key) {
129:                    if (loopVariableKey.equals(key)) {
130:                        active = false;
131:                    }
132:                    return innerContext.remove(key);
133:                }
134:
135:                /**
136:                 * @see org.apache.velocity.context.InternalContextAdapter#pushCurrentTemplateName(java.lang.String s)
137:                 */
138:                public void pushCurrentTemplateName(String s) {
139:                    innerContext.pushCurrentTemplateName(s);
140:                }
141:
142:                /**
143:                 * @see org.apache.velocity.context.InternalContextAdapter#popCurrentTemplateName()
144:                 */
145:                public void popCurrentTemplateName() {
146:                    innerContext.popCurrentTemplateName();
147:                }
148:
149:                /**
150:                 * @see org.apache.velocity.context.InternalContextAdapter#getCurrentTemplateName()
151:                 */
152:                public String getCurrentTemplateName() {
153:                    return innerContext.getCurrentTemplateName();
154:                }
155:
156:                /**
157:                 * @see org.apache.velocity.context.InternalContextAdapter#getTemplateNameStack()
158:                 */
159:                public Object[] getTemplateNameStack() {
160:                    return innerContext.getTemplateNameStack();
161:                }
162:
163:                /**
164:                 * @see org.apache.velocity.context.InternalContextAdapter#icacheGet(java.lang.Object key)
165:                 */
166:                public IntrospectionCacheData icacheGet(Object key) {
167:                    return innerContext.icacheGet(key);
168:                }
169:
170:                /**
171:                 * @see org.apache.velocity.context.InternalContextAdapter#icachePut(java.lang.Object key, org.apache.velocity.util.introspection.IntrospectionCacheData o)
172:                 */
173:                public void icachePut(Object key, IntrospectionCacheData o) {
174:                    innerContext.icachePut(key, o);
175:                }
176:
177:                /**
178:                 * @see org.apache.velocity.context.InternalContextAdapter#setCurrentResource(org.apache.velocity.runtime.resource.Resource r)
179:                 */
180:                public void setCurrentResource(Resource r) {
181:                    innerContext.setCurrentResource(r);
182:                }
183:
184:                /**
185:                 * @see org.apache.velocity.context.InternalContextAdapter#getCurrentResource()
186:                 */
187:                public Resource getCurrentResource() {
188:                    return innerContext.getCurrentResource();
189:                }
190:
191:                /**
192:                 * @see org.apache.velocity.context.InternalContextAdapter#getBaseContext()
193:                 */
194:                public InternalContextAdapter getBaseContext() {
195:                    return innerContext.getBaseContext();
196:                }
197:
198:                /**
199:                 * @see org.apache.velocity.context.InternalContextAdapter#getInternalUserContext()
200:                 */
201:                public Context getInternalUserContext() {
202:                    return innerContext.getInternalUserContext();
203:                }
204:
205:                /**
206:                 * @see org.apache.velocity.context.InternalContextAdapter#attachEventCartridge(org.apache.velocity.app.event.EventCartridge ec)
207:                 */
208:                public EventCartridge attachEventCartridge(EventCartridge ec) {
209:                    EventCartridge cartridge = innerContext
210:                            .attachEventCartridge(ec);
211:
212:                    return cartridge;
213:                }
214:
215:                /**
216:                 * @see org.apache.velocity.context.InternalContextAdapter#getEventCartridge()
217:                 */
218:                public EventCartridge getEventCartridge() {
219:                    return innerContext.getEventCartridge();
220:                }
221:
222:                /**
223:                 * @see org.apache.velocity.context.InternalContextAdapter#getAllowRendering()
224:                 */
225:                public boolean getAllowRendering() {
226:                    return innerContext.getAllowRendering();
227:                }
228:
229:                /**
230:                 * @see org.apache.velocity.context.InternalContextAdapter#setAllowRendering(boolean v)
231:                 */
232:                public void setAllowRendering(boolean v) {
233:                    innerContext.setAllowRendering(v);
234:                }
235:
236:            }
237:
238:            /**
239:             * Return name of this directive.
240:             * @return The name of this directive.
241:             */
242:            public String getName() {
243:                return "foreach";
244:            }
245:
246:            /**
247:             * Return type of this directive.
248:             * @return The type of this directive.
249:             */
250:            public int getType() {
251:                return BLOCK;
252:            }
253:
254:            /**
255:             * The name of the variable to use when placing
256:             * the counter value into the context. Right
257:             * now the default is $velocityCount.
258:             */
259:            private String counterName;
260:
261:            /**
262:             * What value to start the loop counter at.
263:             */
264:            private int counterInitialValue;
265:
266:            /**
267:             * The maximum number of times we're allowed to loop.
268:             */
269:            private int maxNbrLoops;
270:
271:            /**
272:             * The reference name used to access each
273:             * of the elements in the list object. It
274:             * is the $item in the following:
275:             *
276:             * #foreach ($item in $list)
277:             *
278:             * This can be used class wide because
279:             * it is immutable.
280:             */
281:            private String elementKey;
282:
283:            /**
284:             *  immutable, so create in init
285:             */
286:            protected Info uberInfo;
287:
288:            /**
289:             *  simple init - init the tree and get the elementKey from
290:             *  the AST
291:             * @param rs
292:             * @param context
293:             * @param node
294:             * @throws TemplateInitException
295:             */
296:            public void init(RuntimeServices rs,
297:                    InternalContextAdapter context, Node node)
298:                    throws TemplateInitException {
299:                super .init(rs, context, node);
300:
301:                counterName = rsvc.getString(RuntimeConstants.COUNTER_NAME);
302:                counterInitialValue = rsvc
303:                        .getInt(RuntimeConstants.COUNTER_INITIAL_VALUE);
304:                maxNbrLoops = rsvc.getInt(RuntimeConstants.MAX_NUMBER_LOOPS,
305:                        Integer.MAX_VALUE);
306:                if (maxNbrLoops < 1) {
307:                    maxNbrLoops = Integer.MAX_VALUE;
308:                }
309:
310:                /*
311:                 *  this is really the only thing we can do here as everything
312:                 *  else is context sensitive
313:                 */
314:
315:                SimpleNode sn = (SimpleNode) node.jjtGetChild(0);
316:
317:                if (sn instanceof  ASTReference) {
318:                    elementKey = ((ASTReference) sn).getRootString();
319:                } else {
320:                    /*
321:                     * the default, error-prone way which we'll remove
322:                     *  TODO : remove if all goes well
323:                     */
324:                    elementKey = sn.getFirstToken().image.substring(1);
325:                }
326:
327:                /*
328:                 * make an uberinfo - saves new's later on
329:                 */
330:
331:                uberInfo = new Info(context.getCurrentTemplateName(),
332:                        getLine(), getColumn());
333:            }
334:
335:            /**
336:             *  renders the #foreach() block
337:             * @param context
338:             * @param writer
339:             * @param node
340:             * @return True if the directive rendered successfully.
341:             * @throws IOException
342:             * @throws MethodInvocationException
343:             * @throws ResourceNotFoundException
344:             * @throws ParseErrorException
345:             */
346:            public boolean render(InternalContextAdapter context,
347:                    Writer writer, Node node) throws IOException,
348:                    MethodInvocationException, ResourceNotFoundException,
349:                    ParseErrorException {
350:                /*
351:                 *  do our introspection to see what our collection is
352:                 */
353:
354:                Object listObject = node.jjtGetChild(2).value(context);
355:
356:                if (listObject == null)
357:                    return false;
358:
359:                Iterator i = null;
360:
361:                try {
362:                    i = rsvc.getUberspect().getIterator(listObject, uberInfo);
363:                }
364:                /**
365:                 * pass through application level runtime exceptions
366:                 */
367:                catch (RuntimeException e) {
368:                    throw e;
369:                } catch (Exception ee) {
370:                    rsvc.getLog().error("Error getting iterator for #foreach",
371:                            ee);
372:                }
373:
374:                if (i == null) {
375:                    return false;
376:                }
377:
378:                int counter = counterInitialValue;
379:                boolean maxNbrLoopsExceeded = false;
380:
381:                /*
382:                 *  save the element key if there is one, and the loop counter
383:                 */
384:                Object o = context.get(elementKey);
385:                Object savedCounter = context.get(counterName);
386:
387:                /*
388:                 * Instantiate the null holder context if a null value
389:                 * is returned by the foreach iterator.  Only one instance is
390:                 * created - it's reused for every null value.
391:                 */
392:                NullHolderContext nullHolderContext = null;
393:
394:                while (!maxNbrLoopsExceeded && i.hasNext()) {
395:                    // TODO: JDK 1.4+ -> valueOf()
396:                    context.localPut(counterName, new Integer(counter));
397:                    Object value = i.next();
398:                    context.localPut(elementKey, value);
399:
400:                    /*
401:                     * If the value is null, use the special null holder context
402:                     */
403:                    if (value == null) {
404:                        if (nullHolderContext == null) {
405:                            // lazy instantiation
406:                            nullHolderContext = new NullHolderContext(
407:                                    elementKey, context);
408:                        }
409:                        node.jjtGetChild(3).render(nullHolderContext, writer);
410:                    } else {
411:                        node.jjtGetChild(3).render(context, writer);
412:                    }
413:                    counter++;
414:
415:                    // Determine whether we're allowed to continue looping.
416:                    // ASSUMPTION: counterInitialValue is not negative!
417:                    maxNbrLoopsExceeded = (counter - counterInitialValue) >= maxNbrLoops;
418:                }
419:
420:                /*
421:                 * restores the loop counter (if we were nested)
422:                 * if we have one, else just removes
423:                 */
424:
425:                if (savedCounter != null) {
426:                    context.put(counterName, savedCounter);
427:                } else {
428:                    context.remove(counterName);
429:                }
430:
431:                /*
432:                 *  restores element key if exists
433:                 *  otherwise just removes
434:                 */
435:
436:                if (o != null) {
437:                    context.put(elementKey, o);
438:                } else {
439:                    context.remove(elementKey);
440:                }
441:
442:                return true;
443:            }
444:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.