001 /** 002 * Implements the CFML Function structfindvalue 003 */ 004 package railo.runtime.functions.struct; 005 006 import java.util.Iterator; 007 import java.util.Map.Entry; 008 009 import railo.runtime.PageContext; 010 import railo.runtime.exp.FunctionException; 011 import railo.runtime.exp.PageException; 012 import railo.runtime.ext.function.Function; 013 import railo.runtime.op.Caster; 014 import railo.runtime.type.Array; 015 import railo.runtime.type.ArrayImpl; 016 import railo.runtime.type.Collection; 017 import railo.runtime.type.Collection.Key; 018 import railo.runtime.type.Struct; 019 import railo.runtime.type.StructImpl; 020 import railo.runtime.type.util.KeyConstants; 021 022 public final class StructFindValue implements Function { 023 public static Array call(PageContext pc , railo.runtime.type.Struct struct, String value) throws PageException { 024 return call(pc,struct,value,"one"); 025 } 026 public static Array call(PageContext pc , Struct struct, String value, String scope) throws PageException { 027 // Scope 028 boolean all=false; 029 if(scope.equalsIgnoreCase("one")) all=false; 030 else if(scope.equalsIgnoreCase("all")) all=true; 031 else throw new FunctionException(pc,"structFindValue",3,"scope","invalid scope definition ["+scope+"], valid scopes are [one, all]"); 032 033 Array array=new ArrayImpl(); 034 getValues(pc,array,struct,value,all,""); 035 return array; 036 } 037 /** 038 * @param coll 039 * @param value 040 * @param all 041 * @param buffer 042 * @return 043 * @throws PageException 044 */ 045 private static boolean getValues(PageContext pc,Array array,Collection coll, String value, boolean all, String path) throws PageException { 046 //Key[] keys = coll.keys(); 047 boolean abort=false; 048 Key key; 049 Iterator<Entry<Key, Object>> it = coll.entryIterator(); 050 Entry<Key, Object> e; 051 loop:while(it.hasNext()) { 052 e = it.next(); 053 if(abort)break loop; 054 key=e.getKey(); 055 Object o=e.getValue(); 056 057 // Collection (this function search first for sub) 058 if(o instanceof Collection) { 059 abort=getValues(pc,array,((Collection)o), value, all, StructFindKey.createKey(coll, path, key)); 060 061 } 062 // matching value 063 if(!abort && !StructFindKey.isArray(coll)){ 064 String target=Caster.toString(o,null); 065 if((target!=null && target.equalsIgnoreCase(value)) /*|| (o instanceof Array && checkSub(array,((Array)o),value,all,path,abort))*/) { 066 Struct sct=new StructImpl(); 067 sct.setEL(KeyConstants._key,key.getString()); 068 sct.setEL(KeyConstants._path,StructFindKey.createKey(coll, path, key)); 069 sct.setEL(KeyConstants._owner,coll); 070 array.append(sct); 071 if(!all)abort=true; 072 } 073 } 074 } 075 076 return abort; 077 } 078 }