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