KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > el > ArrayExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.el;
30
31 import com.caucho.util.BeanUtil;
32 import com.caucho.vfs.WriteStream;
33
34 import javax.el.ELContext;
35 import javax.el.ELException;
36 import java.io.IOException JavaDoc;
37 import java.lang.reflect.Array JavaDoc;
38 import java.lang.reflect.Method JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Map JavaDoc;
41
42 /**
43  * Represents an array reference:
44  *
45  * <pre>
46  * a[b]
47  * </pre>
48  */

49 public class ArrayExpr extends Expr {
50   private Expr _left;
51   private Expr _right;
52
53   // cached getter method
54
private Class JavaDoc _lastClass;
55   private String JavaDoc _lastField;
56   private Method JavaDoc _lastMethod;
57
58   /**
59    * Creates a new array expression.
60    *
61    * @param left the object expression
62    * @param right the index expression.
63    */

64   public ArrayExpr(Expr left, Expr right)
65   {
66     _left = left;
67     _right = right;
68   }
69
70   /**
71    * Returns the base expression.
72    */

73   public Expr getExpr()
74   {
75     return _left;
76   }
77
78   /**
79    * Returns the index expression.
80    */

81   public Expr getIndex()
82   {
83     return _right;
84   }
85
86   /**
87    * Creates a method for constant arrays.
88    */

89   @Override JavaDoc
90   public Expr createMethod(Expr []args)
91   {
92     if (! (_right instanceof StringLiteral))
93       return null;
94
95     StringLiteral literal = (StringLiteral) _right;
96
97     return new MethodExpr(_left, literal.getValue(), args);
98   }
99   
100   /**
101    * Evaluate the expression as an object.
102    *
103    * @param env the variable environment
104    *
105    * @return the evaluated object
106    */

107   @Override JavaDoc
108   public Object JavaDoc getValue(ELContext env)
109     throws ELException
110   {
111     Object JavaDoc aObj = _left.getValue(env);
112
113     if (aObj == null)
114       return null;
115
116     Object JavaDoc fieldObj = _right.getValue(env);
117     if (fieldObj == null)
118       return null;
119
120     if (aObj instanceof Map JavaDoc) {
121       return ((Map JavaDoc) aObj).get(fieldObj);
122     }
123     
124     if (aObj instanceof List JavaDoc) {
125       int ref = (int) toLong(fieldObj, null);
126
127       try {
128     List JavaDoc list = (List JavaDoc) aObj;
129
130     if (ref < 0 || list.size() < ref)
131       return null;
132     else
133       return list.get(ref);
134       } catch (IndexOutOfBoundsException JavaDoc e) {
135       } catch (Exception JavaDoc e) {
136         return invocationError(e);
137       }
138     }
139
140     Class JavaDoc aClass = aObj.getClass();
141     
142     if (aClass.isArray()) {
143       int ref = (int) toLong(fieldObj, null);
144
145       try {
146         return Array.get(aObj, ref);
147       } catch (IndexOutOfBoundsException JavaDoc e) {
148       } catch (Exception JavaDoc e) {
149         return error(e, env);
150       }
151     }
152
153     String JavaDoc fieldName = toString(fieldObj, env);
154
155     Method JavaDoc getMethod = null;
156     try {
157       synchronized (this) {
158         if (_lastClass == aClass && _lastField.equals(fieldName))
159           getMethod = _lastMethod;
160         else {
161       // XXX: the Introspection is a memory hog
162
// BeanInfo info = Introspector.getBeanInfo(aClass);
163
getMethod = BeanUtil.getGetMethod(aClass, fieldName);
164           _lastClass = aClass;
165           _lastField = fieldName;
166           _lastMethod = getMethod;
167         }
168       }
169
170       if (getMethod != null)
171         return getMethod.invoke(aObj, (Object JavaDoc []) null);
172     } catch (Exception JavaDoc e) {
173       return invocationError(e);
174     }
175
176     try {
177       getMethod = aClass.getMethod("get", new Class JavaDoc[] { String JavaDoc.class });
178
179       if (getMethod != null)
180         return getMethod.invoke(aObj, new Object JavaDoc[] {fieldName});
181     } catch (NoSuchMethodException JavaDoc e) {
182       return null;
183     } catch (Exception JavaDoc e) {
184       return invocationError(e);
185     }
186
187     try {
188       getMethod = aClass.getMethod("get", new Class JavaDoc[] { Object JavaDoc.class });
189
190       if (getMethod != null)
191         return getMethod.invoke(aObj, new Object JavaDoc[] {fieldObj});
192     } catch (Exception JavaDoc e) {
193       return invocationError(e);
194     }
195
196     ELException e = new ELException(L.l("no get method {0} for class {1}",
197                                         fieldName, aClass.getName()));
198
199     error(e, env);
200     
201     return null;
202   }
203
204   /**
205    * Prints the code to create an LongLiteral.
206    *
207    * @param os stream to the generated *.java code
208    */

209   @Override JavaDoc
210   public void printCreate(WriteStream os)
211     throws IOException JavaDoc
212   {
213     os.print("new com.caucho.el.ArrayExpr(");
214     _left.printCreate(os);
215     os.print(", ");
216     _right.printCreate(os);
217     os.print(")");
218   }
219
220   /**
221    * Returns true for equal strings.
222    */

223   public boolean equals(Object JavaDoc o)
224   {
225     if (! (o instanceof ArrayExpr))
226       return false;
227
228     ArrayExpr expr = (ArrayExpr) o;
229
230     return (_left.equals(expr._left) && _right.equals(expr._right));
231   }
232
233   /**
234    * Returns a readable representation of the expr.
235    */

236   public String JavaDoc toString()
237   {
238     return _left + "[" + _right + "]";
239   }
240 }
241
Popular Tags