/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.util; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import lucee.commons.lang.CFTypes; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.loader.engine.CFMLEngine; import lucee.runtime.PageContext; import lucee.runtime.config.NullSupportHelper; import lucee.runtime.exp.ExpressionException; import lucee.runtime.exp.PageException; import lucee.runtime.functions.xml.XmlSearch; import lucee.runtime.op.Caster; import lucee.runtime.op.Decision; import lucee.runtime.reflection.Reflector; import lucee.runtime.security.SecurityManager; import lucee.runtime.text.xml.XMLUtil; import lucee.runtime.text.xml.struct.XMLStruct; import lucee.runtime.text.xml.struct.XMLStructFactory; import lucee.runtime.type.Collection; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.FunctionValue; import lucee.runtime.type.KeyImpl; import lucee.runtime.type.Objects; import lucee.runtime.type.Query; import lucee.runtime.type.QueryColumn; import lucee.runtime.type.Struct; import lucee.runtime.type.UDFPlus; import lucee.runtime.type.scope.Undefined; import lucee.runtime.type.util.ArrayUtil; import lucee.runtime.type.util.KeyConstants; import lucee.runtime.type.util.MemberUtil; import lucee.runtime.type.util.Type; import lucee.runtime.type.wrap.MapAsStruct; import org.w3c.dom.Node; /** * Class to handle CF Variables (set,get,call) */ public final class VariableUtilImpl implements VariableUtil { @Override public Object getCollection(PageContext pc, Object coll, String key, Object defaultValue) { if(coll instanceof Query) { // TODO sollte nicht null sein return ((Query)coll).getColumn(key,null); } return get(pc,coll,key,defaultValue); } @Override public Object getCollection(PageContext pc, Object coll, Collection.Key key, Object defaultValue) { if(coll instanceof Query) { QueryColumn qc = ((Query)coll).getColumn(key,null); if(qc==null) return defaultValue; return qc; } return get(pc,coll,key,defaultValue); } @Override public Object get(PageContext pc, Object coll, String key, Object defaultValue) { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,KeyImpl.init(key),defaultValue); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(key,defaultValue); } // Map else if(coll instanceof Map) { Object rtn=((Map)coll).get(key); //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); if(rtn!=null) return rtn; return defaultValue; } // List else if(coll instanceof List) { int index=Caster.toIntValue(key,Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return defaultValue; try { return ((List)coll).get(index-1); } catch(IndexOutOfBoundsException e) { return defaultValue; } } // Native Array else if(Decision.isNativeArray(coll)) { return ArrayUtil.get(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,defaultValue); } // Node else if(coll instanceof Node) { return XMLStructFactory.newInstance((Node)coll,false).get(key,defaultValue); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { return Reflector.getProperty(coll,key,defaultValue); } return null; } @Override public Object get(PageContext pc, Object coll, Collection.Key key, Object defaultValue) { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,key,defaultValue); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(key,defaultValue); } // Map else if(coll instanceof Map) { Object rtn=((Map)coll).get(key.getString()); //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); if(rtn!=null) return rtn; return defaultValue; } // List else if(coll instanceof List) { int index=Caster.toIntValue(key,Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return defaultValue; try { return ((List)coll).get(index-1); } catch(IndexOutOfBoundsException e) { return defaultValue; } } // Native Array else if(Decision.isNativeArray(coll)) { return ArrayUtil.get(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,defaultValue); } // Node else if(coll instanceof Node) { return XMLStructFactory.newInstance((Node)coll,false).get(key,defaultValue); } else if(coll==null) return defaultValue; // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { return Reflector.getProperty(coll,key.getString(),defaultValue); } return defaultValue; } public Object getLight(PageContext pc, Object coll, Collection.Key key, Object defaultValue) { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,key,defaultValue); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(key,defaultValue); } // Map else if(coll instanceof Map) { //Object rtn=null; try { Object rtn=((Map)coll).get(key.getString()); //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); if(rtn!=null) return rtn; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} return Reflector.getField(coll,key.getString(),defaultValue); //return rtn; } // List else if(coll instanceof List) { int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return null; try { return ((List)coll).get(index-1); } catch(IndexOutOfBoundsException e) { return defaultValue; } } return defaultValue; } @Override public Object getLight(PageContext pc, Object coll, String key, Object defaultValue) { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,KeyImpl.init(key),defaultValue); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(key,defaultValue); } // Map else if(coll instanceof Map) { try { Object rtn=((Map)coll).get(key); //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); if(rtn!=null) return rtn; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} return Reflector.getProperty(coll,key,defaultValue); //return rtn; } // List else if(coll instanceof List) { int index=Caster.toIntValue(key,Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return null; try { return ((List)coll).get(index-1); } catch(IndexOutOfBoundsException e) { return defaultValue; } } return defaultValue; } @Override public Object getCollection(PageContext pc, Object coll, String key) throws PageException { if(coll instanceof Query) { return ((Query)coll).getColumn(key); } return get(pc,coll,key); } public Object getCollection(PageContext pc, Object coll, Collection.Key key) throws PageException { if(coll instanceof Query) { return ((Query)coll).getColumn(key); } return get(pc,coll,key); } public Object get(PageContext pc, Object coll, Collection.Key key) throws PageException { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,key); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(key); } // Map else if(coll instanceof Map) { Object rtn=null; try { rtn=((Map)coll).get(key.getString()); if(rtn==null && coll.getClass().getName().startsWith("org.hibernate.")) rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString())); if(rtn!=null) return rtn; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} rtn = Reflector.getProperty(coll,key.getString(),null); if(rtn!=null) return rtn; String realKey = MapAsStruct.getCaseSensitiveKey((Map)coll, key.getString()); String detail=null; if(realKey!=null) { 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"; } throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in Map ("+((Map)coll).getClass().getName()+")",detail); } // List else if(coll instanceof List) { try { Object rtn=((List)coll).get(Caster.toIntValue(key.getString())-1); if(rtn==null) throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in List"); return rtn; } catch(IndexOutOfBoundsException e) { throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in List"); } } // Native Array else if(Decision.isNativeArray(coll)) { Object rtn=ArrayUtil.get(coll,Caster.toIntValue(key.getString())-1,null); if(rtn==null) throw new ExpressionException("Key ["+key.getString()+"] doesn't exist in Native Array"); return rtn; } // Node else if(coll instanceof Node) { //print.out("get:"+key); return XMLStructFactory.newInstance((Node)coll,false).get(key); } else if(coll instanceof String) { if(Decision.isInteger(key.getString())) { // i do the decision call and the caster call, because in most cases the if will be false String str=(String)coll; int index = Caster.toIntValue(key.getString(),-1); if(index>0 && index<=str.length()) { return str.substring(index-1,index); } } } // HTTPSession /*else if(coll instanceof HttpSession) { return ((HttpSession)coll).getAttribute(key.getString()); }*/ // Direct Object Access if(coll!=null && pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { return Reflector.getProperty(coll,key.getString()); } throw new ExpressionException("No matching property ["+key.getString()+"] found"); } @Override public Object get(PageContext pc, Object coll, String key) throws PageException { // Objects if(coll instanceof Objects) { return ((Objects)coll).get(pc,KeyImpl.init(key)); } // Collection else if(coll instanceof Collection) { return ((Collection)coll).get(KeyImpl.init(key)); } // Map else if(coll instanceof Map) { Object rtn=null; try { rtn=((Map)coll).get(key); //if(rtn==null)rtn=((Map)coll).get(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); if(rtn!=null) return rtn; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} rtn = Reflector.getProperty(coll,key,null); if(rtn!=null) return rtn; throw new ExpressionException("Key ["+key+"] doesn't exist in Map ("+Caster.toClassName(coll)+")","keys are ["+keyList(((Map)coll))+"]"); } // List else if(coll instanceof List) { try { Object rtn=((List)coll).get(Caster.toIntValue(key)-1); if(rtn==null) throw new ExpressionException("Key ["+key+"] doesn't exist in List"); return rtn; } catch(IndexOutOfBoundsException e) { throw new ExpressionException("Key ["+key+"] doesn't exist in List"); } } // Native Array else if(Decision.isNativeArray(coll)) { Object rtn=ArrayUtil.get(coll,Caster.toIntValue(key)-1,null); if(rtn==null) throw new ExpressionException("Key ["+key+"] doesn't exist in Native Array"); return rtn; } // Node else if(coll instanceof Node) { return XMLStructFactory.newInstance((Node)coll,false).get(key); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { return Reflector.getProperty(coll,key); } throw new ExpressionException("No matching property ["+key+"] found"); } private String keyList(Map map) { StringBuffer sb=new StringBuffer(); Iterator it = map.keySet().iterator(); while(it.hasNext()) { if(sb.length()>0)sb.append(','); sb.append(StringUtil.toStringNative(it.next(),"")); } return sb.toString(); } @Override public Object set(PageContext pc, Object coll, Collection.Key key,Object value) throws PageException { // Objects if(coll instanceof Objects) { ((Objects)coll).set(pc,key,value); return value; } // Collection else if(coll instanceof Collection) { ((Collection)coll).set(key,value); return value; } // Map else if(coll instanceof Map) { /* no idea why this is here try { Reflector.setProperty(coll,key.getString(),value); return value; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);}*/ ((Map)coll).put(key.getString(),value); return value; } // List else if(coll instanceof List) { List list=((List)coll); int index=Caster.toIntValue(key.getString()); if(list.size()>=index)list.set(index-1,value); else { while(list.size()<index-1)list.add(null); list.add(value); } return value; } // Native Array else if(Decision.isNativeArray(coll)) { try { return ArrayUtil.set(coll,Caster.toIntValue(key.getString())-1,value); } catch (Exception e) { throw new ExpressionException("invalid index ["+key.getString()+"] for Native Array, can't expand Native Arrays"); } } // Node else if(coll instanceof Node) { return XMLUtil.setProperty((Node)coll,key,value); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { try { Reflector.setProperty(coll,key.getString(),value); return value; } catch(PageException pe) {} } throw new ExpressionException("can't assign value to a Object of this type ["+Type.getName(coll)+"] with key "+key.getString()); } /** * @see lucee.runtime.util.VariableUtil#set(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object) */ @Override public Object set(PageContext pc, Object coll, String key,Object value) throws PageException { // Objects if(coll instanceof Objects) { ((Objects)coll).set(pc,KeyImpl.init(key),value); return value; } // Collection else if(coll instanceof Collection) { ((Collection)coll).set(key,value); return value; } // Map else if(coll instanceof Map) { /*try { Reflector.setProperty(coll,key,value); return value; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);}*/ ((Map)coll).put(key,value); return value; } // List else if(coll instanceof List) { List list=((List)coll); int index=Caster.toIntValue(key); if(list.size()>=index)list.set(index-1,value); else { while(list.size()<index-1)list.add(null); list.add(value); } return value; } // Native Array else if(Decision.isNativeArray(coll)) { try { return ArrayUtil.set(coll,Caster.toIntValue(key)-1,value); } catch (Exception e) { throw new ExpressionException("invalid index ["+key+"] for Native Array, can't expand Native Arrays"); } } // Node else if(coll instanceof Node) { return XMLUtil.setProperty((Node)coll,KeyImpl.init(key),value); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { try { Reflector.setProperty(coll,key,value); return value; } catch(PageException pe) {} } throw new ExpressionException("can't assign value to a Object of this type ["+Type.getName(coll)+"] with key "+key); } /** * * @see lucee.runtime.util.VariableUtil#setEL(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object) */ @Override public Object setEL(PageContext pc, Object coll, String key,Object value) { // Objects if(coll instanceof Objects) { ((Objects)coll).setEL(pc,KeyImpl.init(key),value); return value; } // Collection else if(coll instanceof Collection) { ((Collection)coll).setEL(KeyImpl.init(key),value); return value; } // Map else if(coll instanceof Map) { try { Reflector.setProperty(coll,key,value); return value; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} ((Map)coll).put(key,value); return value; } // List else if(coll instanceof List) { List list=((List)coll); int index=Caster.toIntValue(key,Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return null; if(list.size()>=index)list.set(index-1,value); else { while(list.size()<index-1)list.add(null); list.add(value); } return value; } // Native Array else if(Decision.isNativeArray(coll)) { return ArrayUtil.setEL(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,value); } // Node else if(coll instanceof Node) { return XMLUtil.setPropertyEL((Node)coll,KeyImpl.init(key),value); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { Reflector.setPropertyEL(coll,key,value); return value; } return null; } /** * @see lucee.runtime.util.VariableUtil#setEL(lucee.runtime.PageContext, java.lang.Object, lucee.runtime.type.Collection.Key, java.lang.Object) */ @Override public Object setEL(PageContext pc, Object coll, Collection.Key key,Object value) { // Objects if(coll instanceof Objects) { ((Objects)coll).setEL(pc,key,value); return value; } // Collection else if(coll instanceof Collection) { ((Collection)coll).setEL(key,value); return value; } // Map else if(coll instanceof Map) { try { Reflector.setProperty(coll,key.getString(),value); return value; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} ((Map)coll).put(key,value); return value; } // List else if(coll instanceof List) { List list=((List)coll); int index=Caster.toIntValue(key,Integer.MIN_VALUE); if(index==Integer.MIN_VALUE) return null; if(list.size()>=index)list.set(index-1,value); else { while(list.size()<index-1)list.add(null); list.add(value); } return value; } // Native Array else if(Decision.isNativeArray(coll)) { return ArrayUtil.setEL(coll,Caster.toIntValue(key,Integer.MIN_VALUE)-1,value); } // Node else if(coll instanceof Node) { return XMLUtil.setPropertyEL((Node)coll,key,value); } // Direct Object Access if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { Reflector.setPropertyEL(coll,key.getString(),value); return value; } return null; } @Override public Object removeEL(Object coll, String key) { // Collection if(coll instanceof Collection) { return ((Collection)coll).removeEL(KeyImpl.init(key)); } // Map else if(coll instanceof Map) { Object obj = ((Map)coll).remove(key); //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); return obj; } // List else if(coll instanceof List) { int i=Caster.toIntValue(key,Integer.MIN_VALUE); if(i==Integer.MIN_VALUE) return null; return ((List)coll).remove(i); } return null; } @Override public Object removeEL(Object coll, Collection.Key key) { // Collection if(coll instanceof Collection) { return ((Collection)coll).removeEL(key); } // Map else if(coll instanceof Map) { Object obj = ((Map)coll).remove(key.getString()); //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); return obj; } // List else if(coll instanceof List) { int i=Caster.toIntValue(key,Integer.MIN_VALUE); if(i==Integer.MIN_VALUE) return null; return ((List)coll).remove(i); } return null; } /** * @see lucee.runtime.util.VariableUtil#remove(java.lang.Object, java.lang.String) */ @Override public Object remove(Object coll, String key) throws PageException { // Collection if(coll instanceof Collection) { return ((Collection)coll).remove(KeyImpl.init(key)); } // Map else if(coll instanceof Map) { Object obj=((Map)coll).remove(key); //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); if(obj==null) throw new ExpressionException("can't remove key ["+key+"] from map"); return obj; } // List else if(coll instanceof List) { int i=Caster.toIntValue(key); Object obj=((List)coll).remove(i); if(obj==null) throw new ExpressionException("can't remove index ["+key+"] from list"); return obj; } /*/ Native Array TODO this below else if(Decision.isNativeArray(o)) { try { return ArrayUtil.set(o,Caster.toIntValue(key)-1,value); } catch (Exception e) { return getDirectProperty(o, key, new ExpressionException("Key doesn't exist in Native Array"),false); } }*/ // TODO Support for Node throw new ExpressionException("can't remove key ["+key+"] from Object of type ["+Caster.toTypeName(coll)+"]"); } public Object remove(Object coll, Collection.Key key) throws PageException { // Collection if(coll instanceof Collection) { return ((Collection)coll).remove(key); } // Map else if(coll instanceof Map) { Object obj=((Map)coll).remove(key.getString()); //if(obj==null)obj=((Map)coll).remove(MapAsStruct.getCaseSensitiveKey((Map)coll, key)); if(obj==null) throw new ExpressionException("can't remove key ["+key+"] from map"); return obj; } // List else if(coll instanceof List) { int i=Caster.toIntValue(key); Object obj=((List)coll).remove(i); if(obj==null) throw new ExpressionException("can't remove index ["+key+"] from list"); return obj; } /*/ Native Array TODO this below else if(Decision.isNativeArray(o)) { try { return ArrayUtil.set(o,Caster.toIntValue(key)-1,value); } catch (Exception e) { return getDirectProperty(o, key, new ExpressionException("Key doesn't exist in Native Array"),false); } }*/ // TODO Support for Node throw new ExpressionException("can't remove key ["+key+"] from Object of type ["+Caster.toTypeName(coll)+"]"); } /** * @see lucee.runtime.util.VariableUtil#callFunction(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) */ @Override public Object callFunction(PageContext pc, Object coll, String key, Object[] args) throws PageException { if(args.length>0 && args[0] instanceof FunctionValue) return callFunctionWithNamedValues(pc, coll, key, args); return callFunctionWithoutNamedValues(pc, coll, key, args); } /** * @see lucee.runtime.util.VariableUtil#callFunctionWithoutNamedValues(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) */ @Override public Object callFunctionWithoutNamedValues(PageContext pc, Object coll, String key, Object[] args) throws PageException { return callFunctionWithoutNamedValues(pc, coll, KeyImpl.init(key), args); } @Override public Object callFunctionWithoutNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args) throws PageException { // Objects if(coll instanceof Objects) { return ((Objects)coll).call(pc,key,args); } // call UDF Object prop=getLight(pc,coll,key,null); if(prop instanceof UDFPlus) { return ((UDFPlus)prop).call(pc,key,args,false); } // Strings if(coll instanceof String) { return MemberUtil.call(pc,coll,key,args, new short[]{CFTypes.TYPE_STRING}, new String[]{"string"}); } // Locale if(coll instanceof Locale) { return MemberUtil.call(pc,coll,key,args, new short[]{CFTypes.TYPE_LOCALE}, new String[]{"locale"}); } // TimeZone if(coll instanceof TimeZone) { return MemberUtil.call(pc,coll,key,args, new short[]{CFTypes.TYPE_TIMEZONE}, new String[]{"timezone"}); } // Boolean if(coll instanceof Boolean) { return MemberUtil.call(pc, coll, key, args, new short[]{CFTypes.TYPE_BOOLEAN}, new String[]{"boolean"}); } // Map || XML if(coll instanceof Map) { if(coll instanceof Node) return MemberUtil.call(pc, coll, key, args, new short[]{CFTypes.TYPE_XML,CFTypes.TYPE_STRUCT}, new String[]{"xml","struct"}); return MemberUtil.call(pc, coll, key, args, new short[]{CFTypes.TYPE_STRUCT}, new String[]{"struct"}); } // List if(coll instanceof List) { return MemberUtil.call(pc, coll, key, args, new short[]{CFTypes.TYPE_ARRAY}, new String[]{"array"}); } // Date if(coll instanceof Date) { return MemberUtil.call(pc, coll, key, args, new short[]{CFTypes.TYPE_DATETIME}, new String[]{"date"}); } // call Object Wrapper if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) { if(!(coll instanceof Undefined))return Reflector.callMethod(coll,key,args); } throw new ExpressionException("No matching Method/Function for "+key+"("+Reflector.getDspMethods(Reflector.getClasses(args))+")"); } // FUTURE add to interface public Object callFunctionWithoutNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args, boolean noNull,Object defaultValue) { // MUST make an independent impl for performance reasons try { if(!noNull || NullSupportHelper.full()) return callFunctionWithoutNamedValues(pc, coll, key, args); Object obj = callFunctionWithoutNamedValues(pc, coll, key, args); return obj==null?defaultValue:obj; } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); return defaultValue; } } /** * @see lucee.runtime.util.VariableUtil#callFunctionWithNamedValues(lucee.runtime.PageContext, java.lang.Object, java.lang.String, java.lang.Object[]) */ @Override public Object callFunctionWithNamedValues(PageContext pc, Object coll, String key, Object[] args) throws PageException { return callFunctionWithNamedValues(pc, coll, KeyImpl.init(key), args); } @Override public Object callFunctionWithNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args) throws PageException { // Objects if(coll instanceof Objects) { return ((Objects)coll).callWithNamedValues(pc,key, Caster.toFunctionValues(args)); } // call UDF Object prop=getLight(pc,coll,key,null); if(prop instanceof UDFPlus) { return ((UDFPlus)prop).callWithNamedValues(pc,key,Caster.toFunctionValues(args),false); } // Strings if(coll instanceof String) { return MemberUtil.callWithNamedValues(pc,coll,key,Caster.toFunctionValues(args), CFTypes.TYPE_STRING, "string"); } throw new ExpressionException("No matching Method/Function ["+key+"] for call with named arguments found "); } // FUTURE add to interface public Object callFunctionWithNamedValues(PageContext pc, Object coll, Collection.Key key, Object[] args, boolean noNull, Object defaultValue) { // MUST make an independent impl for performance reasons try { if(!noNull || NullSupportHelper.full()) return callFunctionWithNamedValues(pc, coll, key, args); Object obj = callFunctionWithNamedValues(pc, coll, key, args); return obj==null?defaultValue:obj; } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); return defaultValue; } } @Override public Object callFunctionWithNamedValues(PageContext pc, Object coll, Collection.Key key, Struct args) throws PageException { // Objects if(coll instanceof Objects) { return ((Objects)coll).callWithNamedValues(pc,key, args); } // call UDF Object prop=getLight(pc,coll,key,null); if(prop instanceof UDFPlus) { return ((UDFPlus)prop).callWithNamedValues(pc,key,args,false); } throw new ExpressionException("No matching Method/Function for call with named arguments found"); } // used by generated bytecode public static Object recordcount(PageContext pc,Object obj) throws PageException{ if(obj instanceof Query) return Caster.toDouble(((Query)obj).getRecordcount()); return pc.getCollection(obj, KeyConstants._RECORDCOUNT); } // used by generated bytecode public static Object currentrow(PageContext pc,Object obj) throws PageException{ if(obj instanceof Query) return Caster.toDouble(((Query)obj).getCurrentrow(pc.getId())); return pc.getCollection(obj, KeyConstants._CURRENTROW); } // used by generated bytecode public static Object columnlist(PageContext pc,Object obj) throws PageException{ if(obj instanceof Query) { Key[] columnNames = ((Query)obj).getColumnNames(); boolean upperCase=pc.getCurrentTemplateDialect()==CFMLEngine.DIALECT_CFML; StringBuilder sb=new StringBuilder(); for(int i=0;i<columnNames.length;i++) { if(i>0)sb.append(','); sb.append(upperCase?columnNames[i].getUpperString():columnNames[i].getString()); } return sb.toString(); } return pc.getCollection(obj, KeyConstants._COLUMNLIST); } }