01: /*
02: * Copyright 2002-2006 The Apache Software Foundation.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.apache.commons.jexl.parser;
18:
19: import java.util.Iterator;
20:
21: import org.apache.commons.jexl.JexlContext;
22: import org.apache.commons.jexl.util.Introspector;
23: import org.apache.commons.jexl.util.introspection.Info;
24:
25: /**
26: * ForEach statement. Syntax: foreach (var in iterable) Statement()
27: *
28: * @author Dion Gillard
29: * @since 1.1
30: */
31: public class ASTForeachStatement extends SimpleNode {
32: /** dummy velocity info. */
33: private static final Info DUMMY = new Info("", 1, 1);
34: /** index of the loop variable. */
35: private static final int VAR_INDEX = 0;
36: /** index of the items. */
37: private static final int ITEMS_INDEX = 1;
38: /** index of the code to execute. */
39: private static final int STATEMENT_INDEX = 2;
40:
41: /**
42: * Create the node given an id.
43: *
44: * @param id node id.
45: */
46: public ASTForeachStatement(int id) {
47: super (id);
48: }
49:
50: /**
51: * Create a node with the given parser and id.
52: *
53: * @param p a parser.
54: * @param id node id.
55: */
56: public ASTForeachStatement(Parser p, int id) {
57: super (p, id);
58: }
59:
60: /** {@inheritDoc} */
61: public Object jjtAccept(ParserVisitor visitor, Object data) {
62: return visitor.visit(this , data);
63: }
64:
65: /** {@inheritDoc} */
66: public Object value(JexlContext jc) throws Exception {
67: Object result = null;
68: /* first child is the loop variable */
69: ASTReference loopVariable = (ASTReference) jjtGetChild(VAR_INDEX);
70: /* second child is the variable to iterate */
71: SimpleNode iterable = (SimpleNode) jjtGetChild(ITEMS_INDEX);
72: Object iterableValue = iterable.value(jc);
73: // make sure there is a value to iterate on and a statement to execute
74: if (iterableValue != null
75: && jjtGetNumChildren() >= (STATEMENT_INDEX + 1)) {
76: /* third child is the statement to execute */
77: SimpleNode statement = (SimpleNode) jjtGetChild(2);
78: // get an iterator for the collection/array etc via the
79: // introspector.
80: Iterator itemsIterator = Introspector.getUberspect()
81: .getIterator(iterableValue, DUMMY);
82: while (itemsIterator.hasNext()) {
83: // set loopVariable to value of iterator
84: Object value = itemsIterator.next();
85: jc.getVars().put(loopVariable.getRootString(), value);
86: // execute statement
87: result = statement.value(jc);
88: }
89: }
90: return result;
91: }
92: }
|