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