001 package railo.runtime.java; 002 003 import java.lang.reflect.Field; 004 import java.lang.reflect.InvocationTargetException; 005 import java.lang.reflect.Modifier; 006 import java.util.ArrayList; 007 import java.util.Date; 008 import java.util.Iterator; 009 import java.util.List; 010 011 import railo.runtime.PageContext; 012 import railo.runtime.dump.DumpData; 013 import railo.runtime.dump.DumpProperties; 014 import railo.runtime.dump.DumpUtil; 015 import railo.runtime.exp.ExpressionException; 016 import railo.runtime.exp.PageException; 017 import railo.runtime.op.Caster; 018 import railo.runtime.op.Operator; 019 import railo.runtime.op.date.DateCaster; 020 import railo.runtime.reflection.Reflector; 021 import railo.runtime.reflection.pairs.MethodInstance; 022 import railo.runtime.type.Collection; 023 import railo.runtime.type.ObjectWrap; 024 import railo.runtime.type.Objects; 025 import railo.runtime.type.Struct; 026 import railo.runtime.type.dt.DateTime; 027 import railo.runtime.type.util.ArrayUtil; 028 import railo.runtime.util.VariableUtil; 029 import railo.runtime.util.VariableUtilImpl; 030 031 032 /** 033 * class to handle initialising and call native object from railo 034 */ 035 public class JavaObject implements Objects,ObjectWrap { 036 037 private Class clazz; 038 private boolean isInit=false; 039 private Object object; 040 private VariableUtil variableUtil; 041 042 /** 043 * constructor with className to load 044 * @param variableUtil 045 * @param clazz 046 * @throws ExpressionException 047 */ 048 public JavaObject(VariableUtil variableUtil,Class clazz) { 049 this.variableUtil=variableUtil; 050 this.clazz=clazz; 051 } 052 053 054 public JavaObject(VariableUtil variableUtil,Object object) { 055 this.variableUtil=variableUtil; 056 this.clazz=object.getClass(); 057 this.object=object; 058 isInit=true; 059 } 060 061 public Object get(PageContext pc, String propertyName) throws PageException { 062 if(isInit) { 063 return variableUtil.get(pc,object,propertyName); 064 } 065 066 // Check Field 067 Field[] fields = Reflector.getFieldsIgnoreCase(clazz,propertyName,null); 068 if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) { 069 try { 070 return fields[0].get(null); 071 } 072 catch (Exception e) { 073 throw Caster.toPageException(e); 074 } 075 } 076 // Getter 077 MethodInstance mi = Reflector.getGetterEL(clazz,propertyName); 078 if(mi!=null) { 079 if(Modifier.isStatic(mi.getMethod().getModifiers())) { 080 try { 081 return mi.invoke(null); 082 } 083 catch (IllegalAccessException e) { 084 throw Caster.toPageException(e); 085 } 086 catch (InvocationTargetException e) { 087 throw Caster.toPageException(e.getTargetException()); 088 } 089 } 090 } 091 // male Instance 092 return variableUtil.get(pc,init(),propertyName); 093 } 094 095 @Override 096 public Object get(PageContext pc, Collection.Key key) throws PageException { 097 return get(pc, key.getString()); 098 } 099 100 public Object get(PageContext pc, String propertyName, Object defaultValue) { 101 if(isInit) { 102 return variableUtil.get(pc,object,propertyName,defaultValue); 103 } 104 // Field 105 Field[] fields = Reflector.getFieldsIgnoreCase(clazz,propertyName,null); 106 if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) { 107 try { 108 return fields[0].get(null); 109 } catch (Exception e) {} 110 } 111 // Getter 112 MethodInstance mi = Reflector.getGetterEL(clazz,propertyName); 113 if(mi!=null) { 114 if(Modifier.isStatic(mi.getMethod().getModifiers())) { 115 try { 116 return mi.invoke(null); 117 } 118 catch (Exception e) {} 119 } 120 } 121 try { 122 return variableUtil.get(pc,init(),propertyName,defaultValue); 123 } catch (PageException e1) { 124 return defaultValue; 125 } 126 } 127 128 @Override 129 public Object get(PageContext pc, Collection.Key key, Object defaultValue) { 130 return get(pc, key.getString(), defaultValue); 131 } 132 133 @Override 134 public Object set(PageContext pc, Collection.Key propertyName, Object value) throws PageException { 135 if(isInit) { 136 return ((VariableUtilImpl)variableUtil).set(pc,object,propertyName,value); 137 } 138 // Field 139 Field[] fields=Reflector.getFieldsIgnoreCase(clazz,propertyName.getString(),null); 140 if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) { 141 try { 142 fields[0].set(null,value); 143 return value; 144 } catch (Exception e) { 145 Caster.toPageException(e); 146 } 147 } 148 // Getter 149 MethodInstance mi = Reflector.getSetter(clazz,propertyName.getString(),value,null); 150 if(mi!=null) { 151 if(Modifier.isStatic(mi.getMethod().getModifiers())) { 152 try { 153 return mi.invoke(null); 154 } 155 catch (IllegalAccessException e) { 156 throw Caster.toPageException(e); 157 } 158 catch (InvocationTargetException e) { 159 throw Caster.toPageException(e.getTargetException()); 160 } 161 } 162 } 163 164 165 return ((VariableUtilImpl)variableUtil).set(pc,init(),propertyName,value); 166 } 167 168 @Override 169 public Object setEL(PageContext pc, Collection.Key propertyName, Object value) { 170 if(isInit) { 171 return variableUtil.setEL(pc,object,propertyName,value); 172 } 173 // Field 174 Field[] fields=Reflector.getFieldsIgnoreCase(clazz,propertyName.getString(),null); 175 if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) { 176 try { 177 fields[0].set(null,value); 178 } catch (Exception e) {} 179 return value; 180 } 181 // Getter 182 MethodInstance mi = Reflector.getSetter(clazz,propertyName.getString(),value,null); 183 if(mi!=null) { 184 if(Modifier.isStatic(mi.getMethod().getModifiers())) { 185 try { 186 return mi.invoke(null); 187 } 188 catch (Exception e) {} 189 } 190 } 191 192 try { 193 return variableUtil.setEL(pc,init(),propertyName,value); 194 } catch (PageException e1) { 195 return value; 196 } 197 } 198 199 public Object call(PageContext pc, String methodName, Object[] arguments) throws PageException { 200 if(arguments==null)arguments=new Object[0]; 201 202 // init 203 if(methodName.equalsIgnoreCase("init")) { 204 return init(arguments); 205 } 206 else if(isInit) { 207 return Reflector.callMethod(object,methodName,arguments); 208 } 209 210 211 try { 212 // get method 213 MethodInstance mi = Reflector.getMethodInstance(clazz,methodName,arguments); 214 // call static method if exist 215 if(Modifier.isStatic(mi.getMethod().getModifiers())) { 216 return mi.invoke(null); 217 } 218 219 if(arguments.length==0 && methodName.equalsIgnoreCase("getClass")){ 220 return clazz; 221 } 222 223 // invoke constructor and call instance method 224 return mi.invoke(init()); 225 } 226 catch(InvocationTargetException e) { 227 Throwable target = e.getTargetException(); 228 if(target instanceof PageException) throw (PageException)target; 229 throw Caster.toPageException(e.getTargetException()); 230 } 231 catch(Exception e) { 232 throw Caster.toPageException(e); 233 } 234 } 235 236 @Override 237 public Object call(PageContext pc, Collection.Key methodName, Object[] arguments) throws PageException { 238 return call(pc, methodName.getString(), arguments); 239 } 240 241 public Object callWithNamedValues(PageContext pc, String methodName, Struct args) throws PageException { 242 Iterator<Object> it = args.valueIterator(); 243 List<Object> values=new ArrayList<Object>(); 244 while(it.hasNext()) { 245 values.add(it.next()); 246 } 247 return call(pc,methodName,values.toArray(new Object[values.size()])); 248 } 249 250 public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException { 251 return callWithNamedValues(pc, methodName.getString(), args); 252 } 253 254 /** 255 * initialize method (default no object) 256 * @return initialize object 257 * @throws PageException 258 */ 259 private Object init() throws PageException { 260 return init(new Object[0]); 261 } 262 263 private Object init(Object defaultValue) { 264 return init(new Object[0],defaultValue); 265 } 266 267 /** 268 * initialize method 269 * @param arguments 270 * @return Initalised Object 271 * @throws PageException 272 */ 273 private Object init(Object[] arguments) throws PageException { 274 object=Reflector.callConstructor(clazz,arguments); 275 isInit=true; 276 return object; 277 } 278 private Object init(Object[] arguments, Object defaultValue) { 279 object=Reflector.callConstructor(clazz,arguments,defaultValue); 280 isInit=object!=defaultValue; 281 return object; 282 } 283 284 285 @Override 286 public Object getEmbededObject() throws PageException { 287 if(object==null)init(); 288 return object; 289 } 290 291 @Override 292 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties props) { 293 try { 294 return DumpUtil.toDumpData(getEmbededObject(), pageContext,maxlevel,props); 295 } catch (PageException e) { 296 return DumpUtil.toDumpData(clazz, pageContext,maxlevel,props); 297 } 298 } 299 300 /** 301 * @return the containing Class 302 */ 303 public Class getClazz() {return clazz;} 304 305 public boolean isInitalized() { 306 return isInit; 307 } 308 309 @Override 310 public String castToString() throws PageException { 311 return Caster.toString(getEmbededObject()); 312 } 313 314 315 316 @Override 317 public String castToString(String defaultValue) { 318 try { 319 return Caster.toString(getEmbededObject(),defaultValue); 320 } catch (PageException e) { 321 return defaultValue; 322 } 323 } 324 325 326 @Override 327 public boolean castToBooleanValue() throws PageException { 328 return Caster.toBooleanValue(getEmbededObject()); 329 } 330 331 @Override 332 public Boolean castToBoolean(Boolean defaultValue) { 333 try { 334 return Caster.toBoolean(getEmbededObject(),defaultValue); 335 } catch (PageException e) { 336 return defaultValue; 337 } 338 } 339 340 @Override 341 public double castToDoubleValue() throws PageException { 342 return Caster.toDoubleValue(getEmbededObject()); 343 } 344 345 @Override 346 public double castToDoubleValue(double defaultValue) { 347 try { 348 return Caster.toDoubleValue(getEmbededObject(),defaultValue); 349 } catch (PageException e) { 350 return defaultValue; 351 } 352 } 353 354 @Override 355 public DateTime castToDateTime() throws PageException { 356 return Caster.toDatetime(getEmbededObject(),null); 357 } 358 359 @Override 360 public DateTime castToDateTime(DateTime defaultValue) { 361 try { 362 return DateCaster.toDateAdvanced(getEmbededObject(),true,null,defaultValue); 363 } catch (PageException e) { 364 return defaultValue; 365 } 366 } 367 368 @Override 369 public Object getEmbededObject(Object def) { 370 if(object==null)init(def); 371 return object; 372 } 373 374 /** 375 * @return the object 376 */ 377 public Object getObject() { 378 return object; 379 } 380 381 @Override 382 public int compareTo(boolean b) throws PageException { 383 return Operator.compare(castToBooleanValue(), b); 384 } 385 386 @Override 387 public int compareTo(DateTime dt) throws PageException { 388 return Operator.compare((Date)castToDateTime(), (Date)dt); 389 } 390 391 @Override 392 public int compareTo(double d) throws PageException { 393 return Operator.compare(castToDoubleValue(), d); 394 } 395 396 @Override 397 public int compareTo(String str) throws PageException { 398 return Operator.compare(castToString(), str); 399 } 400 401 }