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    }