001 package railo.runtime.type.wrap; 002 003 import java.util.Iterator; 004 import java.util.Map; 005 006 import railo.runtime.PageContext; 007 import railo.runtime.dump.DumpData; 008 import railo.runtime.dump.DumpProperties; 009 import railo.runtime.dump.DumpUtil; 010 import railo.runtime.exp.ExpressionException; 011 import railo.runtime.exp.PageException; 012 import railo.runtime.op.Caster; 013 import railo.runtime.op.Duplicator; 014 import railo.runtime.type.Collection; 015 import railo.runtime.type.KeyImpl; 016 import railo.runtime.type.Struct; 017 import railo.runtime.type.dt.DateTime; 018 import railo.runtime.type.it.EntryIterator; 019 import railo.runtime.type.it.KeyIterator; 020 import railo.runtime.type.it.StringIterator; 021 import railo.runtime.type.it.ValueIterator; 022 import railo.runtime.type.util.StructSupport; 023 024 /** 025 * 026 */ 027 public class MapAsStruct extends StructSupport implements Struct { 028 029 Map map; 030 private boolean caseSensitive; 031 032 /** 033 * constructor of the class 034 * @param map 035 * @param caseSensitive 036 */ 037 private MapAsStruct(Map map, boolean caseSensitive) { 038 this.map=map; 039 this.caseSensitive=caseSensitive; 040 } 041 042 043 public static Struct toStruct(Map map) { 044 return toStruct(map,false); 045 } 046 047 public static Struct toStruct(Map map, boolean caseSensitive) { 048 if(map instanceof Struct) return ((Struct)map); 049 return new MapAsStruct(map,caseSensitive); 050 } 051 052 @Override 053 public int size() { 054 return map.size(); 055 } 056 057 @Override 058 public synchronized Collection.Key[] keys() { 059 int len=size(); 060 Collection.Key[] k=new Collection.Key[len]; 061 Iterator it = map.keySet().iterator(); 062 int count=0; 063 while(it.hasNext()) { 064 k[count++]=KeyImpl.init(it.next().toString()); 065 } 066 return k; 067 } 068 069 public static String getCaseSensitiveKey(Map map,String key) { 070 Iterator it = map.keySet().iterator(); 071 String strKey; 072 while(it.hasNext()) { 073 strKey=Caster.toString(it.next(),""); 074 if(strKey.equalsIgnoreCase(key)) return strKey; 075 } 076 return null; 077 } 078 079 @Override 080 public synchronized Object remove(Collection.Key key) throws ExpressionException { 081 Object obj= map.remove(key.getString()); 082 if(obj==null) { 083 if(map.containsKey(key.getString())) return null; 084 if(!caseSensitive){ 085 String csKey = getCaseSensitiveKey(map,key.getString()); 086 if(csKey!=null)obj= map.remove(csKey); 087 if(obj!=null)return obj; 088 } 089 throw new ExpressionException("can't remove key ["+key.getString()+"] from map, key doesn't exist"); 090 } 091 return obj; 092 } 093 094 @Override 095 public synchronized Object removeEL(Collection.Key key) { 096 Object obj= map.remove(key.getString()); 097 if(!caseSensitive && obj==null) { 098 String csKey = getCaseSensitiveKey(map,key.getString()); 099 if(csKey!=null)obj= map.remove(csKey); 100 } 101 return obj; 102 } 103 104 @Override 105 public synchronized void clear() { 106 map.clear(); 107 } 108 109 @Override 110 public synchronized Object get(Collection.Key key) throws ExpressionException { 111 Object o=map.get(key.getString()); 112 if(o==null) { 113 if(map.containsKey(key.getString())) return null; 114 if(!caseSensitive){ 115 String csKey = getCaseSensitiveKey(map,key.getString()); 116 if(csKey!=null)o= map.get(csKey); 117 if(o!=null || map.containsKey(csKey)) return o; 118 } 119 throw new ExpressionException("key "+key.getString()+" doesn't exist in "+Caster.toClassName(map)); 120 } 121 return o; 122 } 123 124 @Override 125 public synchronized Object get(Collection.Key key, Object defaultValue) { 126 Object obj=map.get(key.getString()); 127 if(obj==null) { 128 if(map.containsKey(key.getString())) return null; 129 if(!caseSensitive){ 130 String csKey = getCaseSensitiveKey(map,key.getString()); 131 if(csKey!=null)obj= map.get(csKey); 132 if(obj!=null || map.containsKey(csKey)) return obj; 133 } 134 return defaultValue; 135 } 136 return obj; 137 } 138 139 @Override 140 public synchronized Object set(Collection.Key key, Object value) throws PageException { 141 return map.put(key.getString(),value); 142 } 143 144 @Override 145 public synchronized Object setEL(Collection.Key key, Object value) { 146 return map.put(key.getString(),value); 147 } 148 149 @Override 150 public synchronized Iterator<Collection.Key> keyIterator() { 151 return new KeyIterator(keys()); 152 } 153 154 @Override 155 public Iterator<String> keysAsStringIterator() { 156 return new StringIterator(keys()); 157 } 158 159 @Override 160 public Iterator<Entry<Key, Object>> entryIterator() { 161 return new EntryIterator(this,keys()); 162 } 163 164 @Override 165 public Iterator<Object> valueIterator() { 166 return new ValueIterator(this,keys()); 167 } 168 169 170 171 @Override 172 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 173 return DumpUtil.toDumpData(map, pageContext,maxlevel,dp); 174 } 175 176 @Override 177 public synchronized Collection duplicate(boolean deepCopy) { 178 return new MapAsStruct(Duplicator.duplicateMap(map,deepCopy),caseSensitive); 179 } 180 181 182 183 @Override 184 public boolean containsKey(Collection.Key key) { 185 186 //return map.containsKey(key.getString()); 187 188 boolean contains = map.containsKey(key.getString()); 189 if(contains) return true; 190 if(!caseSensitive)return map.containsKey(getCaseSensitiveKey(map,key.getString())); 191 return false; 192 } 193 194 @Override 195 public String castToString() throws ExpressionException { 196 throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to String", 197 "Use Built-In-Function \"serialize(Struct):String\" to create a String from Struct"); 198 } 199 @Override 200 public String castToString(String defaultValue) { 201 return defaultValue; 202 } 203 204 205 @Override 206 public boolean castToBooleanValue() throws ExpressionException { 207 throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a boolean value"); 208 } 209 210 @Override 211 public Boolean castToBoolean(Boolean defaultValue) { 212 return defaultValue; 213 } 214 215 216 @Override 217 public double castToDoubleValue() throws ExpressionException { 218 throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a number value"); 219 } 220 221 @Override 222 public double castToDoubleValue(double defaultValue) { 223 return defaultValue; 224 } 225 226 227 @Override 228 public DateTime castToDateTime() throws ExpressionException { 229 throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a Date"); 230 } 231 232 @Override 233 public DateTime castToDateTime(DateTime defaultValue) { 234 return defaultValue; 235 } 236 237 @Override 238 public int compareTo(boolean b) throws ExpressionException { 239 throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a boolean value"); 240 } 241 242 @Override 243 public int compareTo(DateTime dt) throws PageException { 244 throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a DateTime Object"); 245 } 246 247 @Override 248 public int compareTo(double d) throws PageException { 249 throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a numeric value"); 250 } 251 252 @Override 253 public int compareTo(String str) throws PageException { 254 throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a String"); 255 } 256 257 @Override 258 public boolean containsValue(Object value) { 259 return map.containsValue(value); 260 } 261 262 @Override 263 public java.util.Collection values() { 264 return map.values(); 265 } 266 }