001 /** 002 * Implements the Cold Fusion Function structfindkey 003 */ 004 package railo.runtime.functions.struct; 005 006 import railo.runtime.PageContext; 007 import railo.runtime.exp.FunctionException; 008 import railo.runtime.exp.PageException; 009 import railo.runtime.ext.function.Function; 010 import railo.runtime.type.Array; 011 import railo.runtime.type.ArrayImpl; 012 import railo.runtime.type.Collection; 013 import railo.runtime.type.KeyImpl; 014 import railo.runtime.type.Struct; 015 import railo.runtime.type.StructImpl; 016 import railo.runtime.type.scope.Argument; 017 018 public final class StructFindKey implements Function { 019 020 public static Array call(PageContext pc , railo.runtime.type.Struct struct, String value) throws PageException { 021 return _call(pc,struct,value,false); 022 } 023 public static Array call(PageContext pc , Struct struct, String value, String scope) throws PageException { 024 // Scope 025 boolean all=false; 026 if(scope.equalsIgnoreCase("one")) all=false; 027 else if(scope.equalsIgnoreCase("all")) all=true; 028 else throw new FunctionException(pc,"structFindValue",3,"scope","invalid scope definition ["+scope+"], valid scopes are [one, all]"); 029 return _call(pc,struct,value,all); 030 } 031 private static Array _call(PageContext pc , Struct struct, String value, boolean all) throws PageException { 032 Array array=new ArrayImpl(); 033 getValues(array,struct,value,all,""); 034 return array; 035 } 036 /** 037 * @param coll 038 * @param value 039 * @param all 040 * @param buffer 041 * @return 042 * @throws PageException 043 */ 044 private static boolean getValues(Array array,Collection coll, String value, boolean all, String path) throws PageException { 045 Collection.Key[] keys=coll.keys(); 046 boolean abort=false; 047 Collection.Key key; 048 049 for(int i=0;i<keys.length;i++) { 050 if(abort)break; 051 key=keys[i]; 052 Object o=coll.get(key); 053 054 // matching value (this function search first for base) 055 if(key.getString().equalsIgnoreCase(value)) { 056 Struct sct=new StructImpl(); 057 058 sct.setEL(KeyImpl.VALUE,o); 059 sct.setEL(KeyImpl.PATH,createKey(coll,path,key)); 060 sct.setEL(KeyImpl.OWNER,coll); 061 array.append(sct); 062 if(!all)abort=true; 063 } 064 065 // Collection 066 if(!abort && o instanceof Collection) { 067 abort=getValues(array,((Collection)o), value, all, createKey(coll,path,key)); 068 } 069 } 070 071 return abort; 072 } 073 static String createKey(Collection coll,String path,Collection.Key key) { 074 StringBuffer p=new StringBuffer(path.toString()); 075 if(isArray(coll)){ 076 p.append('[').append(key.getString()).append(']'); 077 } 078 else{ 079 p.append('.').append(key.getString()); 080 } 081 return p.toString(); 082 } 083 static boolean isArray(Collection coll) { 084 return coll instanceof Array && !(coll instanceof Argument); 085 } 086 }