1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl.parser;
18
19 import org.apache.commons.jexl.JexlContext;
20 import org.apache.commons.jexl.util.Coercion;
21 import org.apache.commons.jexl.util.Introspector;
22 import org.apache.commons.jexl.util.introspection.Info;
23 import org.apache.commons.jexl.util.introspection.VelPropertyGet;
24
25 import java.util.List;
26 import java.util.Map;
27 import java.lang.reflect.Array;
28
29
30 /***
31 * Like an ASTIdentifier, but with array access allowed
32 *
33 * $foo[2]
34 *
35 * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
36 * @version $Id: ASTArrayAccess.java,v 1.7 2004/08/22 07:42:35 dion Exp $
37 */
38 public class ASTArrayAccess extends SimpleNode
39 {
40 /*** dummy velocity info */
41 private static Info DUMMY = new Info("", 1, 1);
42
43 public ASTArrayAccess(int id)
44 {
45 super(id);
46 }
47
48 public ASTArrayAccess(Parser p, int id)
49 {
50 super(p, id);
51 }
52
53
54 /*** Accept the visitor. **/
55 public Object jjtAccept(ParserVisitor visitor, Object data)
56 {
57 return visitor.visit(this, data);
58 }
59
60
61
62
63
64
65
66
67 public Object execute(Object obj, JexlContext jc)
68 throws Exception
69 {
70 ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);
71
72 obj = base.execute(obj,jc);
73
74
75
76
77 for(int i=1; i<jjtGetNumChildren(); i++)
78 {
79 Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);
80
81 if(loc==null)
82 return null;
83
84 obj = evaluateExpr(obj, loc);
85 }
86
87 return obj;
88 }
89
90 /***
91 * return the value of this node
92 */
93 public Object value(JexlContext jc)
94 throws Exception
95 {
96
97
98
99
100 ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);
101
102 Object o = base.value(jc);
103
104
105
106
107 for(int i=1; i<jjtGetNumChildren(); i++)
108 {
109 Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);
110
111 if(loc==null)
112 return null;
113
114 o = evaluateExpr(o, loc);
115 }
116
117 return o;
118 }
119
120 public static Object evaluateExpr(Object o, Object loc)
121 throws Exception
122 {
123
124
125
126
127 if (o == null)
128 return null;
129
130 if (loc == null)
131 return null;
132
133 if (o instanceof Map)
134 {
135 if (!((Map)o).containsKey(loc))
136 return null;
137
138 return ((Map)o).get(loc);
139 }
140 else if (o instanceof List)
141 {
142 int idx = Coercion.coerceInteger(loc).intValue();
143
144 try
145 {
146 return ((List)o).get(idx);
147 }
148 catch(IndexOutOfBoundsException iobe)
149 {
150 return null;
151 }
152 }
153 else if (o.getClass().isArray())
154 {
155 int idx = Coercion.coerceInteger(loc).intValue();
156
157 try
158 {
159 return Array.get(o, idx);
160 }
161 catch(ArrayIndexOutOfBoundsException aiobe)
162 {
163 return null;
164 }
165 }
166 else
167 {
168
169
170
171
172 String s = loc.toString();
173
174 VelPropertyGet vg = Introspector.getUberspect().getPropertyGet(o, s, DUMMY);
175
176 if (vg != null)
177 {
178 return vg.invoke(o);
179 }
180 }
181
182 throw new Exception("Unsupported object type for array [] accessor");
183 }
184
185 public String getIdentifierString()
186 {
187 return ((ASTIdentifier) jjtGetChild(0)).getIdentifierString();
188 }
189 }