001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.util; 020 021import java.util.Iterator; 022import java.util.List; 023import java.util.Map; 024 025import lucee.commons.lang.CFTypes; 026import lucee.commons.lang.ExceptionUtil; 027import lucee.commons.lang.StringUtil; 028import lucee.runtime.PageContext; 029import lucee.runtime.exp.ExpressionException; 030import lucee.runtime.exp.PageException; 031import lucee.runtime.op.Caster; 032import lucee.runtime.op.Decision; 033import lucee.runtime.reflection.Reflector; 034import lucee.runtime.security.SecurityManager; 035import lucee.runtime.text.xml.XMLUtil; 036import lucee.runtime.text.xml.struct.XMLStructFactory; 037import lucee.runtime.type.Collection; 038import lucee.runtime.type.Collection.Key; 039import lucee.runtime.type.FunctionValue; 040import lucee.runtime.type.KeyImpl; 041import lucee.runtime.type.Objects; 042import lucee.runtime.type.Query; 043import lucee.runtime.type.QueryColumn; 044import lucee.runtime.type.Struct; 045import lucee.runtime.type.UDFPlus; 046import lucee.runtime.type.scope.Undefined; 047import lucee.runtime.type.util.ArrayUtil; 048import lucee.runtime.type.util.KeyConstants; 049import lucee.runtime.type.util.MemberUtil; 050import lucee.runtime.type.util.Type; 051import lucee.runtime.type.wrap.MapAsStruct; 052 053import org.w3c.dom.Node; 054 055/** 056 * Class to handle CF Variables (set,get,call) 057 */ 058public final class VariableUtilImpl implements VariableUtil { 059 060 @Override 061 public Object getCollection(PageContext pc, Object coll, String key, Object defaultValue) { 062 if(coll instanceof Query) { 063 // TODO sollte nicht null sein 064 return ((Query)coll).getColumn(key,null); 065 } 066 return get(pc,coll,key,defaultValue); 067 } 068 069 public Object getCollection(PageContext pc, Object coll, Collection.Key key, Object defaultValue) {// FUTURE add to interface 070 if(coll instanceof Query) { 071 QueryColumn qc = ((Query)coll).getColumn(key,null); 072 if(qc==null) return defaultValue; 073 return qc; 074 } 075 return get(pc,coll,key,defaultValue); 076 } 077 078 @Override 079 public Object get(PageContext pc, Object coll, String key, Object defaultValue) { 080 // Objects 081 if(coll instanceof Objects) { 082 return ((Objects)coll).get(pc,KeyImpl.init(key),defaultValue); 083 } 084 // Collection 085 else if(coll instanceof Collection) { 086 return ((Collection)coll).get(key,defaultValue); 087 } 088 // Map 089 else if(coll instanceof Map) { 090 Object rtn=((Map)coll).get(key); 091 //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 092 if(rtn!=null) return rtn; 093 return defaultValue; 094 } 095 // List 096 else if(coll instanceof List) { 097 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 098 if(index==Integer.MIN_VALUE) return defaultValue; 099 try { 100 return ((List)coll).get(index-1); 101 } 102 catch(IndexOutOfBoundsException e) { 103 return defaultValue; 104 } 105 } 106 // Native Array 107 else if(Decision.isNativeArray(coll)) { 108 return ArrayUtil.get(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,defaultValue); 109 } 110 // Node 111 else if(coll instanceof Node) { 112 return XMLStructFactory.newInstance((Node)coll,false).get(key,defaultValue); 113 } 114 // Direct Object Access 115 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 116 return Reflector.getProperty(coll,key,defaultValue); 117 } 118 return null; 119 120 } 121 122 123 @Override 124 public Object get(PageContext pc, Object coll, Collection.Key key, Object defaultValue) { 125 // Objects 126 //print.out("key:"+key.getString()); 127 if(coll instanceof Objects) { 128 return ((Objects)coll).get(pc,key,defaultValue); 129 } 130 // Collection 131 else if(coll instanceof Collection) { 132 return ((Collection)coll).get(key,defaultValue); 133 } 134 // Map 135 else if(coll instanceof Map) { 136 137 Object rtn=((Map)coll).get(key.getString()); 138 //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); 139 if(rtn!=null) return rtn; 140 return defaultValue; 141 142 } 143 // List 144 else if(coll instanceof List) { 145 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 146 if(index==Integer.MIN_VALUE) return defaultValue; 147 try { 148 return ((List)coll).get(index-1); 149 } 150 catch(IndexOutOfBoundsException e) { 151 return defaultValue; 152 } 153 } 154 // Native Array 155 else if(Decision.isNativeArray(coll)) { 156 return ArrayUtil.get(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,defaultValue); 157 } 158 // Node 159 else if(coll instanceof Node) { 160 return XMLStructFactory.newInstance((Node)coll,false).get(key,defaultValue); 161 } 162 // Direct Object Access 163 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 164 return Reflector.getProperty(coll,key.getString(),defaultValue); 165 } 166 return null; 167 168 } 169 170 public Object getLight(PageContext pc, Object coll, Collection.Key key, Object defaultValue) { 171 // Objects 172 if(coll instanceof Objects) { 173 return ((Objects)coll).get(pc,key,defaultValue); 174 } 175 // Collection 176 else if(coll instanceof Collection) { 177 return ((Collection)coll).get(key,defaultValue); 178 } 179 // Map 180 else if(coll instanceof Map) { 181 //Object rtn=null; 182 try { 183 Object rtn=((Map)coll).get(key.getString()); 184 //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); 185 if(rtn!=null) return rtn; 186 } 187 catch(Throwable t) { 188 ExceptionUtil.rethrowIfNecessary(t); 189 } 190 return Reflector.getField(coll,key.getString(),defaultValue); 191 //return rtn; 192 } 193 // List 194 else if(coll instanceof List) { 195 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 196 if(index==Integer.MIN_VALUE) return null; 197 try { 198 return ((List)coll).get(index-1); 199 } 200 catch(IndexOutOfBoundsException e) { 201 return defaultValue; 202 } 203 } 204 return defaultValue; 205 } 206 207 @Override 208 public Object getLight(PageContext pc, Object coll, String key, Object defaultValue) { 209 // Objects 210 if(coll instanceof Objects) { 211 return ((Objects)coll).get(pc,KeyImpl.init(key),defaultValue); 212 } 213 // Collection 214 else if(coll instanceof Collection) { 215 return ((Collection)coll).get(key,defaultValue); 216 } 217 // Map 218 else if(coll instanceof Map) { 219 try { 220 Object rtn=((Map)coll).get(key); 221 //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 222 if(rtn!=null) return rtn; 223 } 224 catch(Throwable t) { 225 ExceptionUtil.rethrowIfNecessary(t); 226 } 227 return Reflector.getProperty(coll,key,defaultValue); 228 //return rtn; 229 } 230 // List 231 else if(coll instanceof List) { 232 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 233 if(index==Integer.MIN_VALUE) return null; 234 try { 235 return ((List)coll).get(index-1); 236 } 237 catch(IndexOutOfBoundsException e) { 238 return defaultValue; 239 } 240 } 241 return defaultValue; 242 } 243 244 @Override 245 public Object getCollection(PageContext pc, Object coll, String key) throws PageException { 246 if(coll instanceof Query) { 247 return ((Query)coll).getColumn(key); 248 } 249 return get(pc,coll,key); 250 } 251 public Object getCollection(PageContext pc, Object coll, Collection.Key key) throws PageException { 252 if(coll instanceof Query) { 253 return ((Query)coll).getColumn(key); 254 } 255 return get(pc,coll,key); 256 } 257 258 public Object get(PageContext pc, Object coll, Collection.Key key) throws PageException { 259 // Objects 260 if(coll instanceof Objects) { 261 return ((Objects)coll).get(pc,key); 262 } 263 // Collection 264 else if(coll instanceof Collection) { 265 return ((Collection)coll).get(key); 266 } 267 // Map 268 else if(coll instanceof Map) { 269 Object rtn=null; 270 try { 271 rtn=((Map)coll).get(key.getString()); 272 if(rtn==null && coll.getClass().getName().startsWith("org.hibernate.")) 273 rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); 274 if(rtn!=null) return rtn; 275 } 276 catch(Throwable t) { 277 ExceptionUtil.rethrowIfNecessary(t); 278 } 279 rtn = Reflector.getProperty(coll,key.getString(),null); 280 if(rtn!=null) return rtn; 281 282 String realKey = MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString()); 283 String detail=null; 284 if(realKey!=null) { 285 detail="The keys for this Map are case-sensitive, use bracked notation like this \"map['"+realKey+"']\" instead of dot notation like this \"map."+realKey+"\" to address the Map"; 286 } 287 288 throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in Map ("+((Map)coll).getClass().getName()+")",detail); 289 } 290 // List 291 else if(coll instanceof List) { 292 try { 293 Object rtn=((List)coll).get(Caster.toIntValue(key.getString())-1); 294 if(rtn==null) throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in List"); 295 return rtn; 296 } 297 catch(IndexOutOfBoundsException e) { 298 throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in List"); 299 } 300 } 301 // Native Array 302 else if(Decision.isNativeArray(coll)) { 303 Object rtn=ArrayUtil.get(coll,Caster.toIntValue(key.getString())-1,null); 304 if(rtn==null) throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in Native Array"); 305 return rtn; 306 } 307 // Node 308 else if(coll instanceof Node) { 309 //print.out("get:"+key); 310 return XMLStructFactory.newInstance((Node)coll,false).get(key); 311 } 312 else if(coll instanceof String) { 313 if(Decision.isInteger(key.getString())) { // i do the decision call and the caster call, because in most cases the if will be false 314 String str=(String)coll; 315 int index = Caster.toIntValue(key.getString(),-1); 316 if(index>0 && index<=str.length()) { 317 return str.substring(index-1,index); 318 } 319 } 320 } 321 // HTTPSession 322 /*else if(coll instanceof HttpSession) { 323 return ((HttpSession)coll).getAttribute(key.getString()); 324 }*/ 325 326 327 328 // Direct Object Access 329 if(coll!=null && pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 330 return Reflector.getProperty(coll,key.getString()); 331 } 332 throw new ExpressionException("No matching property ["+key.getString()+"] found"); 333 334 } 335 336 @Override 337 public Object get(PageContext pc, Object coll, String key) throws PageException { 338 // Objects 339 if(coll instanceof Objects) { 340 return ((Objects)coll).get(pc,KeyImpl.init(key)); 341 } 342 // Collection 343 else if(coll instanceof Collection) { 344 345 return ((Collection)coll).get(KeyImpl.init(key)); 346 } 347 // Map 348 else if(coll instanceof Map) { 349 Object rtn=null; 350 try { 351 rtn=((Map)coll).get(key); 352 //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 353 if(rtn!=null) return rtn; 354 355 } 356 catch(Throwable t) { 357 ExceptionUtil.rethrowIfNecessary(t); 358 } 359 rtn = Reflector.getProperty(coll,key,null); 360 if(rtn!=null) return rtn; 361 throw new ExpressionException("Key ["+key+"] doesn't exist in Map ("+Caster.toClassName(coll)+")","keys are ["+keyList(((Map)coll))+"]"); 362 } 363 // List 364 else if(coll instanceof List) { 365 try { 366 Object rtn=((List)coll).get(Caster.toIntValue(key)-1); 367 if(rtn==null) throw new ExpressionException("Key ["+key+"] doesn't exist in List"); 368 return rtn; 369 } 370 catch(IndexOutOfBoundsException e) { 371 throw new ExpressionException("Key ["+key+"] doesn't exist in List"); 372 } 373 } 374 // Native Array 375 else if(Decision.isNativeArray(coll)) { 376 Object rtn=ArrayUtil.get(coll,Caster.toIntValue(key)-1,null); 377 if(rtn==null) throw new ExpressionException("Key ["+key+"] doesn't exist in Native Array"); 378 return rtn; 379 } 380 // Node 381 else if(coll instanceof Node) { 382 return XMLStructFactory.newInstance((Node)coll,false).get(key); 383 } 384 // Direct Object Access 385 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 386 return Reflector.getProperty(coll,key); 387 } 388 throw new ExpressionException("No matching property ["+key+"] found"); 389 390 } 391 392 393 private String keyList(Map map) { 394 StringBuffer sb=new StringBuffer(); 395 Iterator it = map.keySet().iterator(); 396 while(it.hasNext()) { 397 if(sb.length()>0)sb.append(','); 398 sb.append(StringUtil.toStringNative(it.next(),"")); 399 } 400 return sb.toString(); 401 } 402 403 public Object set(PageContext pc, Object coll, Collection.Key key,Object value) throws PageException { 404 // Objects 405 if(coll instanceof Objects) { 406 ((Objects)coll).set(pc,key,value); 407 return value; 408 } 409 // Collection 410 else if(coll instanceof Collection) { 411 ((Collection)coll).set(key,value); 412 return value; 413 } 414 // Map 415 else if(coll instanceof Map) { 416 ((Map)coll).put(key.getString(),value); 417 return value; 418 } 419 // List 420 else if(coll instanceof List) { 421 List list=((List)coll); 422 int index=Caster.toIntValue(key.getString()); 423 if(list.size()>=index)list.set(index-1,value); 424 else { 425 while(list.size()<index-1)list.add(null); 426 list.add(value); 427 } 428 return value; 429 } 430 // Native Array 431 else if(Decision.isNativeArray(coll)) { 432 try { 433 return ArrayUtil.set(coll,Caster.toIntValue(key.getString())-1,value); 434 } catch (Exception e) { 435 throw new ExpressionException("invalid index ["+key.getString()+"] for Native Array, can't expand Native Arrays"); 436 } 437 } 438 // Node 439 else if(coll instanceof Node) { 440 return XMLUtil.setProperty((Node)coll,key,value); 441 } 442 // Direct Object Access 443 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 444 try { 445 Reflector.setProperty(coll,key.getString(),value); 446 return value; 447 } 448 catch(PageException pe) {} 449 } 450 throw new ExpressionException("can't assign value to a Object of this type ["+Type.getName(coll)+"] with key "+key.getString()); 451 } 452 453 454 /** 455 * @see lucee.runtime.util.VariableUtil#set(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object) 456 */ 457 public Object set(PageContext pc, Object coll, String key,Object value) throws PageException { 458 // Objects 459 if(coll instanceof Objects) { 460 ((Objects)coll).set(pc,KeyImpl.init(key),value); 461 return value; 462 } 463 // Collection 464 else if(coll instanceof Collection) { 465 ((Collection)coll).set(key,value); 466 return value; 467 } 468 // Map 469 else if(coll instanceof Map) { 470 ((Map)coll).put(key,value); 471 return value; 472 } 473 // List 474 else if(coll instanceof List) { 475 List list=((List)coll); 476 int index=Caster.toIntValue(key); 477 if(list.size()>=index)list.set(index-1,value); 478 else { 479 while(list.size()<index-1)list.add(null); 480 list.add(value); 481 } 482 return value; 483 } 484 // Native Array 485 else if(Decision.isNativeArray(coll)) { 486 try { 487 return ArrayUtil.set(coll,Caster.toIntValue(key)-1,value); 488 } catch (Exception e) { 489 throw new ExpressionException("invalid index ["+key+"] for Native Array, can't expand Native Arrays"); 490 } 491 } 492 // Node 493 else if(coll instanceof Node) { 494 return XMLUtil.setProperty((Node)coll,KeyImpl.init(key),value); 495 } 496 // Direct Object Access 497 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 498 try { 499 Reflector.setProperty(coll,key,value); 500 return value; 501 } 502 catch(PageException pe) {} 503 } 504 throw new ExpressionException("can't assign value to a Object of this type ["+Type.getName(coll)+"] with key "+key); 505 } 506 507 /** 508 * 509 * @see lucee.runtime.util.VariableUtil#setEL(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object) 510 */ 511 public Object setEL(PageContext pc, Object coll, String key,Object value) { 512 // Objects 513 if(coll instanceof Objects) { 514 ((Objects)coll).setEL(pc,KeyImpl.init(key),value); 515 return value; 516 } 517 // Collection 518 else if(coll instanceof Collection) { 519 ((Collection)coll).setEL(KeyImpl.init(key),value); 520 return value; 521 } 522 // Map 523 else if(coll instanceof Map) { 524 try { 525 Reflector.setProperty(coll,key,value); 526 return value; 527 } 528 catch(Throwable t) { 529 ExceptionUtil.rethrowIfNecessary(t); 530 } 531 ((Map)coll).put(key,value); 532 return value; 533 } 534 // List 535 else if(coll instanceof List) { 536 List list=((List)coll); 537 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 538 if(index==Integer.MIN_VALUE) return null; 539 if(list.size()>=index)list.set(index-1,value); 540 else { 541 while(list.size()<index-1)list.add(null); 542 list.add(value); 543 } 544 return value; 545 } 546 // Native Array 547 else if(Decision.isNativeArray(coll)) { 548 return ArrayUtil.setEL(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,value); 549 } 550 // Node 551 else if(coll instanceof Node) { 552 return XMLUtil.setPropertyEL((Node)coll,KeyImpl.init(key),value); 553 } 554 // Direct Object Access 555 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 556 Reflector.setPropertyEL(coll,key,value); 557 return value; 558 } 559 return null; 560 } 561 562 /** 563 * @see lucee.runtime.util.VariableUtil#setEL(lucee.runtime.PageContext, java.lang.Object, lucee.runtime.type.Collection.Key, java.lang.Object) 564 */ 565 public Object setEL(PageContext pc, Object coll, Collection.Key key,Object value) { 566 // Objects 567 if(coll instanceof Objects) { 568 ((Objects)coll).setEL(pc,key,value); 569 return value; 570 } 571 // Collection 572 else if(coll instanceof Collection) { 573 ((Collection)coll).setEL(key,value); 574 return value; 575 } 576 // Map 577 else if(coll instanceof Map) { 578 try { 579 Reflector.setProperty(coll,key.getString(),value); 580 return value; 581 } 582 catch(Throwable t) { 583 ExceptionUtil.rethrowIfNecessary(t); 584 } 585 ((Map)coll).put(key,value); 586 return value; 587 } 588 // List 589 else if(coll instanceof List) { 590 List list=((List)coll); 591 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 592 if(index==Integer.MIN_VALUE) return null; 593 if(list.size()>=index)list.set(index-1,value); 594 else { 595 while(list.size()<index-1)list.add(null); 596 list.add(value); 597 } 598 return value; 599 } 600 // Native Array 601 else if(Decision.isNativeArray(coll)) { 602 return ArrayUtil.setEL(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,value); 603 } 604 // Node 605 else if(coll instanceof Node) { 606 return XMLUtil.setPropertyEL((Node)coll,key,value); 607 } 608 // Direct Object Access 609 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 610 Reflector.setPropertyEL(coll,key.getString(),value); 611 return value; 612 } 613 return null; 614 } 615 616 /** 617 * 618 * @see lucee.runtime.util.VariableUtil#removeEL(java.lang.Object, java.lang.String) 619 */ 620 public Object removeEL(Object coll, String key) { 621 // Collection 622 if(coll instanceof Collection) { 623 return ((Collection)coll).removeEL(KeyImpl.init(key)); 624 } 625 // Map 626 else if(coll instanceof Map) { 627 Object obj = ((Map)coll).remove(key); 628 //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 629 return obj; 630 } 631 // List 632 else if(coll instanceof List) { 633 int i=Caster.toIntValue(key,Integer.MIN_VALUE); 634 if(i==Integer.MIN_VALUE) return null; 635 return ((List)coll).remove(i); 636 } 637 return null; 638 } 639 640 public Object removeEL(Object coll, Collection.Key key) { 641 // Collection 642 if(coll instanceof Collection) { 643 return ((Collection)coll).removeEL(key); 644 } 645 // Map 646 else if(coll instanceof Map) { 647 Object obj = ((Map)coll).remove(key.getString()); 648 //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 649 return obj; 650 } 651 // List 652 else if(coll instanceof List) { 653 int i=Caster.toIntValue(key,Integer.MIN_VALUE); 654 if(i==Integer.MIN_VALUE) return null; 655 return ((List)coll).remove(i); 656 } 657 return null; 658 } 659 660 661 /** 662 * @see lucee.runtime.util.VariableUtil#remove(java.lang.Object, java.lang.String) 663 */ 664 public Object remove(Object coll, String key) throws PageException { 665 // Collection 666 if(coll instanceof Collection) { 667 return ((Collection)coll).remove(KeyImpl.init(key)); 668 } 669 // Map 670 else if(coll instanceof Map) { 671 Object obj=((Map)coll).remove(key); 672 //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 673 if(obj==null) throw new ExpressionException("can't remove key ["+key+"] from map"); 674 return obj; 675 } 676 // List 677 else if(coll instanceof List) { 678 int i=Caster.toIntValue(key); 679 Object obj=((List)coll).remove(i); 680 if(obj==null) throw new ExpressionException("can't remove index ["+key+"] from list"); 681 return obj; 682 } 683 /*/ Native Array TODO this below 684 else if(Decision.isNativeArray(o)) { 685 try { 686 return ArrayUtil.set(o,Caster.toIntValue(key)-1,value); 687 } catch (Exception e) { 688 return getDirectProperty(o, key, new ExpressionException("Key doesn't exist in Native Array"),false); 689 } 690 }*/ 691 // TODO Support for Node 692 throw new ExpressionException("can't remove key ["+key+"] from Object of type ["+Caster.toTypeName(coll)+"]"); 693 } 694 695 public Object remove(Object coll, Collection.Key key) throws PageException { 696 // Collection 697 if(coll instanceof Collection) { 698 return ((Collection)coll).remove(key); 699 } 700 // Map 701 else if(coll instanceof Map) { 702 Object obj=((Map)coll).remove(key.getString()); 703 //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); 704 if(obj==null) throw new ExpressionException("can't remove key ["+key+"] from map"); 705 return obj; 706 } 707 // List 708 else if(coll instanceof List) { 709 int i=Caster.toIntValue(key); 710 Object obj=((List)coll).remove(i); 711 if(obj==null) throw new ExpressionException("can't remove index ["+key+"] from list"); 712 return obj; 713 } 714 /*/ Native Array TODO this below 715 else if(Decision.isNativeArray(o)) { 716 try { 717 return ArrayUtil.set(o,Caster.toIntValue(key)-1,value); 718 } catch (Exception e) { 719 return getDirectProperty(o, key, new ExpressionException("Key doesn't exist in Native Array"),false); 720 } 721 }*/ 722 // TODO Support for Node 723 throw new ExpressionException("can't remove key ["+key+"] from Object of type ["+Caster.toTypeName(coll)+"]"); 724 } 725 726 /** 727 * @see lucee.runtime.util.VariableUtil#callFunction(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) 728 */ 729 public Object callFunction(PageContext pc, Object coll, String key, Object[] args) throws PageException { 730 if(args.length>0 && args[0] instanceof FunctionValue) 731 return callFunctionWithNamedValues(pc, coll, key, args); 732 return callFunctionWithoutNamedValues(pc, coll, key, args); 733 } 734 735 /** 736 * @see lucee.runtime.util.VariableUtil#callFunctionWithoutNamedValues(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) 737 */ 738 public Object callFunctionWithoutNamedValues(PageContext pc, Object coll, String key, Object[] args) throws PageException { 739 return callFunctionWithoutNamedValues(pc, coll, KeyImpl.init(key), args); 740 } 741 742 public Object callFunctionWithoutNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args) throws PageException { 743 // Objects 744 if(coll instanceof Objects) { 745 return ((Objects)coll).call(pc,key,args); 746 } 747 // call UDF 748 Object prop=getLight(pc,coll,key,null); 749 if(prop instanceof UDFPlus) { 750 return ((UDFPlus)prop).call(pc,key,args,false); 751 } 752 // Strings 753 if(coll instanceof String) { 754 return MemberUtil.call(pc,coll,key,args, CFTypes.TYPE_STRING, "string"); 755 } 756 757 // call Object Wrapper 758 if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { 759 if(!(coll instanceof Undefined))return Reflector.callMethod(coll,key,args); 760 } 761 throw new ExpressionException("No matching Method/Function for "+key+"("+Reflector.getDspMethods(Reflector.getClasses(args))+")"); 762 763 764 } 765 766 /** 767 * @see lucee.runtime.util.VariableUtil#callFunctionWithNamedValues(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) 768 */ 769 public Object callFunctionWithNamedValues(PageContext pc, Object coll, String key, Object[] args) throws PageException { 770 return callFunctionWithNamedValues(pc, coll, KeyImpl.init(key), args); 771 } 772 773 public Object callFunctionWithNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args) throws PageException { 774 // Objects 775 if(coll instanceof Objects) { 776 return ((Objects)coll).callWithNamedValues(pc,key, Caster.toFunctionValues(args)); 777 } 778 // call UDF 779 Object prop=getLight(pc,coll,key,null); 780 if(prop instanceof UDFPlus) { 781 return ((UDFPlus)prop).callWithNamedValues(pc,key,Caster.toFunctionValues(args),false); 782 } 783 784 // Strings 785 if(coll instanceof String) { 786 return MemberUtil.callWithNamedValues(pc,coll,key,Caster.toFunctionValues(args), CFTypes.TYPE_STRING, "string"); 787 } 788 789 790 throw new ExpressionException("No matching Method/Function ["+key+"] for call with named arguments found "); 791 } 792 793 public Object callFunctionWithNamedValues(PageContext pc, Object coll, Collection.Key key, Struct args) throws PageException { 794 // Objects 795 if(coll instanceof Objects) { 796 return ((Objects)coll).callWithNamedValues(pc,key, args); 797 } 798 // call UDF 799 Object prop=getLight(pc,coll,key,null); 800 if(prop instanceof UDFPlus) { 801 return ((UDFPlus)prop).callWithNamedValues(pc,key,args,false); 802 } 803 throw new ExpressionException("No matching Method/Function for call with named arguments found"); 804 } 805 806 // used by generated bytecode 807 public static Object recordcount(PageContext pc,Object obj) throws PageException{ 808 if(obj instanceof Query) return Caster.toDouble(((Query)obj).getRecordcount()); 809 return pc.getCollection(obj, KeyConstants._RECORDCOUNT); 810 } 811 // used by generated bytecode 812 public static Object currentrow(PageContext pc,Object obj) throws PageException{ 813 if(obj instanceof Query) return Caster.toDouble(((Query)obj).getCurrentrow(pc.getId())); 814 return pc.getCollection(obj, KeyConstants._CURRENTROW); 815 } 816 // used by generated bytecode 817 public static Object columnlist(PageContext pc,Object obj) throws PageException{ 818 if(obj instanceof Query) { 819 Key[] columnNames = ((Query)obj).getColumnNames(); 820 821 boolean upperCase=true;//((ConfigImpl)ThreadLocalPageContext.getConfig()).getDotNotationUpperCase(); 822 823 824 StringBuilder sb=new StringBuilder(); 825 for(int i=0;i<columnNames.length;i++) { 826 if(i>0)sb.append(','); 827 sb.append(upperCase?columnNames[i].getUpperString():columnNames[i].getString()); 828 } 829 return sb.toString(); 830 831 832 } 833 return pc.getCollection(obj, KeyConstants._COLUMNLIST); 834 } 835 836}