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