1 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 ; 37 import java.lang.reflect.Array ; 38 import java.lang.reflect.Method ; 39 import java.util.List ; 40 import java.util.Map ; 41 42 49 public class ArrayExpr extends Expr { 50 private Expr _left; 51 private Expr _right; 52 53 private Class _lastClass; 55 private String _lastField; 56 private Method _lastMethod; 57 58 64 public ArrayExpr(Expr left, Expr right) 65 { 66 _left = left; 67 _right = right; 68 } 69 70 73 public Expr getExpr() 74 { 75 return _left; 76 } 77 78 81 public Expr getIndex() 82 { 83 return _right; 84 } 85 86 89 @Override 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 107 @Override 108 public Object getValue(ELContext env) 109 throws ELException 110 { 111 Object aObj = _left.getValue(env); 112 113 if (aObj == null) 114 return null; 115 116 Object fieldObj = _right.getValue(env); 117 if (fieldObj == null) 118 return null; 119 120 if (aObj instanceof Map ) { 121 return ((Map ) aObj).get(fieldObj); 122 } 123 124 if (aObj instanceof List ) { 125 int ref = (int) toLong(fieldObj, null); 126 127 try { 128 List list = (List ) aObj; 129 130 if (ref < 0 || list.size() < ref) 131 return null; 132 else 133 return list.get(ref); 134 } catch (IndexOutOfBoundsException e) { 135 } catch (Exception e) { 136 return invocationError(e); 137 } 138 } 139 140 Class 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 e) { 148 } catch (Exception e) { 149 return error(e, env); 150 } 151 } 152 153 String fieldName = toString(fieldObj, env); 154 155 Method getMethod = null; 156 try { 157 synchronized (this) { 158 if (_lastClass == aClass && _lastField.equals(fieldName)) 159 getMethod = _lastMethod; 160 else { 161 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 []) null); 172 } catch (Exception e) { 173 return invocationError(e); 174 } 175 176 try { 177 getMethod = aClass.getMethod("get", new Class [] { String .class }); 178 179 if (getMethod != null) 180 return getMethod.invoke(aObj, new Object [] {fieldName}); 181 } catch (NoSuchMethodException e) { 182 return null; 183 } catch (Exception e) { 184 return invocationError(e); 185 } 186 187 try { 188 getMethod = aClass.getMethod("get", new Class [] { Object .class }); 189 190 if (getMethod != null) 191 return getMethod.invoke(aObj, new Object [] {fieldObj}); 192 } catch (Exception 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 209 @Override 210 public void printCreate(WriteStream os) 211 throws IOException 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 223 public boolean equals(Object 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 236 public String toString() 237 { 238 return _left + "[" + _right + "]"; 239 } 240 } 241 | Popular Tags |