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