001 package railo.runtime.functions.struct; 002 003 import java.util.Iterator; 004 import java.util.List; 005 import java.util.Map; 006 007 import railo.runtime.PageContext; 008 import railo.runtime.exp.PageException; 009 import railo.runtime.op.Caster; 010 import railo.runtime.op.Decision; 011 import railo.runtime.type.Collection; 012 import railo.runtime.type.Collection.Key; 013 import railo.runtime.type.KeyImpl; 014 import railo.runtime.type.Struct; 015 import railo.runtime.type.StructImpl; 016 017 public class StructKeyTranslate { 018 public static double call(PageContext pc ,Struct sct) throws PageException { 019 return call(pc, sct,false,false); 020 } 021 public static double call(PageContext pc ,Struct sct,boolean deepTranslation) throws PageException { 022 return call(pc, sct,deepTranslation,false); 023 } 024 public static double call(PageContext pc ,Struct sct,boolean deepTranslation,boolean leaveOriginalKey) throws PageException { 025 return translate(sct, deepTranslation,leaveOriginalKey); 026 } 027 028 public static int translate(Collection coll,boolean deep,boolean leaveOrg) throws PageException { 029 Key[] keys = coll.keys(); 030 boolean isStruct=coll instanceof Struct; 031 String key; 032 int index; 033 int count=0; 034 for(int i=0;i<keys.length;i++){ 035 key=keys[i].getString(); 036 if(deep)count+=translate(coll.get(keys[i]),leaveOrg); 037 if(isStruct && (index=key.indexOf('.'))!=-1){ 038 count++; 039 translate(index,keys[i],key,coll,leaveOrg); 040 } 041 } 042 return count; 043 } 044 045 private static int translate(Object value,boolean leaveOrg) throws PageException { 046 if(value instanceof Collection) 047 return translate((Collection)value, true,leaveOrg); 048 if(value instanceof List) 049 return translate((List)value, leaveOrg); 050 if(value instanceof Map) 051 return translate((Map)value, leaveOrg); 052 if(Decision.isArray(value)) 053 return translate(Caster.toNativeArray(value), leaveOrg); 054 return 0; 055 } 056 057 private static int translate(List list,boolean leaveOrg) throws PageException { 058 Iterator it = list.iterator(); 059 int count=0; 060 while(it.hasNext()){ 061 count+=translate(it.next(),leaveOrg); 062 } 063 return count; 064 } 065 066 private static int translate(Map map,boolean leaveOrg) throws PageException { 067 Iterator it = map.entrySet().iterator(); 068 int count=0; 069 while(it.hasNext()){ 070 count+=translate(((Map.Entry)it.next()).getValue(),leaveOrg); 071 } 072 return count; 073 } 074 075 private static int translate(Object[] arr,boolean leaveOrg) throws PageException { 076 int count=0; 077 for(int i=0;i<arr.length;i++){ 078 count+=translate(arr[i],leaveOrg); 079 } 080 return count; 081 } 082 083 private static void translate(int index, Key key, String strKey, Collection coll,boolean leaveOrg) throws PageException { 084 String left; 085 Object value=leaveOrg?coll.get(key):coll.remove(key); 086 do{ 087 left=strKey.substring(0,index); 088 strKey=strKey.substring(index+1); 089 coll=touch(coll,KeyImpl.init(left)); 090 091 } 092 while((index=strKey.indexOf('.'))!=-1); 093 coll.set(KeyImpl.init(strKey), value); 094 } 095 096 private static Collection touch(Collection coll, Key key) throws PageException { 097 Object obj = coll.get(key,null); 098 if(obj instanceof Collection) return (Collection) obj; 099 if(Decision.isCastableToStruct(obj)) 100 return Caster.toStruct(obj); 101 coll.set(key, coll=new StructImpl()); 102 return coll; 103 104 } 105 }