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