001    package railo.runtime.type.util;
002    
003    import java.util.ArrayList;
004    import java.util.Arrays;
005    import java.util.HashSet;
006    import java.util.Iterator;
007    import java.util.Map;
008    import java.util.Map.Entry;
009    import java.util.Set;
010    
011    import railo.commons.lang.SizeOf;
012    import railo.commons.lang.StringUtil;
013    import railo.runtime.PageContext;
014    import railo.runtime.dump.DumpProperties;
015    import railo.runtime.dump.DumpTable;
016    import railo.runtime.dump.DumpTablePro;
017    import railo.runtime.dump.DumpUtil;
018    import railo.runtime.dump.SimpleDumpData;
019    import railo.runtime.exp.PageException;
020    import railo.runtime.op.Caster;
021    import railo.runtime.op.Duplicator;
022    import railo.runtime.type.Collection;
023    import railo.runtime.type.Collection.Key;
024    import railo.runtime.type.KeyImpl;
025    import railo.runtime.type.Struct;
026    import railo.runtime.type.StructImpl;
027    import railo.runtime.type.comparator.TextComparator;
028    
029    /**
030     * 
031     */
032    public final class StructUtil {
033    
034        /**
035         * copy data from source struct to target struct
036         * @param source 
037         * @param target 
038         * @param overwrite overwrite data if exist in target
039         */
040        public static void copy(Struct source, Struct target, boolean overwrite) {
041            railo.runtime.type.Collection.Key[] skeys = source.keys();
042            for(int i=0;i<skeys.length;i++) {
043                if(overwrite || !target.containsKey(skeys[i])) 
044                    target.setEL(skeys[i],source.get(skeys[i],null));
045            }
046        }
047    
048        public static railo.runtime.type.Collection.Key[] toCollectionKeys(String[] skeys) {
049            railo.runtime.type.Collection.Key[] keys = new railo.runtime.type.Collection.Key[skeys.length];
050                    for(int i=0;i<keys.length;i++) {
051                            keys[i]=KeyImpl.init(skeys[i]);
052                    }
053                return keys;
054        }
055        
056            /**
057             * @param sct
058             * @return
059             */
060            public static Struct duplicate(Struct sct,boolean deepCopy) {
061    
062                    Struct rtn=new StructImpl();
063                    railo.runtime.type.Collection.Key[] keys=sct.keys();
064                    railo.runtime.type.Collection.Key key;
065                    for(int i=0;i<keys.length;i++) {
066                            key=keys[i];
067                            rtn.setEL(key,Duplicator.duplicate(sct.get(key,null),deepCopy));
068                    }
069                    return rtn;
070            }
071    
072            public static void putAll(Struct struct, Map map) {
073                    Iterator it = map.entrySet().iterator();
074                    Map.Entry entry;
075                    while(it.hasNext()) {
076                            entry=(Entry) it.next();
077                            struct.setEL(KeyImpl.toKey(entry.getKey(),null), entry.getValue());
078                    }
079            }
080    
081            public static Set entrySet(Struct sct) {
082                    HashSet set=new HashSet();
083            Collection.Key[] keys = sct.keys();
084            for(int i=0;i<keys.length;i++) {
085                set.add(new StructMapEntry(sct,keys[i],sct.get(keys[i], null)));
086            }
087            return set;
088            }
089            
090    
091            public static Set keySet(Struct sct) {
092                    Collection.Key[] arr=sct.keys();
093                    Set set=new HashSet();
094                    
095                    for(int i=0;i<arr.length;i++){
096                            set.add(arr[i].getString());
097                    }
098                    return set;
099            }
100    
101            
102            public static DumpTable toDumpTable(Struct sct,String title,PageContext pageContext, int maxlevel, DumpProperties dp) {
103                    Key[] keys = order(sct.keys());
104                    DumpTable table = new DumpTablePro("struct","#9999ff","#ccccff","#000000");// "#9999ff","#ccccff","#000000"
105                    if(sct.size()>10 && dp.getMetainfo())table.setComment("Entries:"+sct.size());
106                if(!StringUtil.isEmpty(title))table.setTitle(title);
107                    maxlevel--;
108                    int maxkeys=dp.getMaxKeys();
109                    int index=0;
110                    for(int i=0;i<keys.length;i++) {
111                            if(DumpUtil.keyValid(dp,maxlevel,keys[i])){
112                                    if(maxkeys<=index++)break;
113                                    table.appendRow(1,
114                                                    new SimpleDumpData(keys[i].toString()),
115                                                    DumpUtil.toDumpData(sct.get(keys[i],null), 
116                                                    pageContext,maxlevel,dp));
117                            }
118                    }
119                    return table;
120            }
121            
122            
123    
124            private static Key[] order(Key[] keys) {
125                    TextComparator comp=new TextComparator(true,true);
126                    Arrays.sort(keys,comp);
127                    return keys;
128            }
129    
130            /**
131             * create a value return value out of a struct
132             * @param sct
133             * @return
134             */
135            public static java.util.Collection values(Struct sct) {
136                    ArrayList arr = new ArrayList();
137                    Key[] keys = sct.keys();
138                    for(int i=0;i<keys.length;i++) {
139                            arr.add(sct.get(keys[i],null));
140                    }
141                    return arr;
142            }
143    
144            public static Struct copyToStruct(Map map) throws PageException {
145            Struct sct = new StructImpl();
146            Iterator it=map.entrySet().iterator();
147            Map.Entry entry;
148            while(it.hasNext()) {
149                entry=(Entry) it.next();
150                sct.setEL(Caster.toString(entry.getKey()),entry.getValue());
151            }
152            return sct;
153            }
154    
155            /**
156             * return the size of given struct, size of values + keys
157             * @param sct
158             * @return
159             */
160            public static long sizeOf(Struct sct) {
161                    Key[] keys = sct.keys();
162                    long size = SizeOf.size(keys);
163                    if(keys!=null)for(int i=0;i<keys.length;i++) {
164                            size += SizeOf.size(sct.get(keys[i],null));
165                    }
166                    return size;
167            }
168    
169            public static void setELIgnoreWhenNull(Struct sct, String key, Object value) {
170                    setELIgnoreWhenNull(sct, KeyImpl.init(key), value);
171            }
172            public static void setELIgnoreWhenNull(Struct sct, Collection.Key key, Object value) {
173                    if(value!=null)sct.setEL(key, value);
174            }
175    
176            /**
177             * remove every entry hat has this value
178             * @param map
179             * @param obj
180             */
181            public static void removeValue(Map map, Object value) {
182                    Iterator it = map.entrySet().iterator();
183                    Map.Entry entry;
184                    while(it.hasNext()){
185                            entry=(Entry) it.next();
186                            if(entry.getValue()==value)it.remove();
187                    }
188            }
189    }