1 29 30 package com.caucho.quercus.env; 31 32 import com.caucho.quercus.program.JavaClassDef; 33 34 import com.caucho.quercus.QuercusRuntimeException; 35 import com.caucho.quercus.UnimplementedException; 36 37 import java.util.*; 38 import java.util.logging.*; 39 40 43 public class JavaMapAdapter 44 extends JavaAdapter 45 { 46 private static final Logger log 47 = Logger.getLogger(JavaMapAdapter.class.getName()); 48 49 private Map _map; 51 52 private long _nextAvailableIndex; 53 54 public JavaMapAdapter(Env env, Map map) 55 { 56 this(env, map, env.getJavaClassDefinition(map.getClass().getName())); 57 } 58 59 public JavaMapAdapter(Env env, Map map, JavaClassDef def) 60 { 61 super(env, map, def); 62 _map = map; 63 64 updateNextAvailableIndex(); 65 } 66 67 70 public void clear() 71 { 72 _map.clear(); 73 74 _nextAvailableIndex = 0; 75 } 76 77 public int size() 78 { 79 return _map.size(); 80 } 81 82 85 @Override 86 public Object toJavaObject(Env env, Class type) 87 { 88 if (type.isAssignableFrom(_map.getClass())) { 89 return _map; 90 } 91 else { 92 env.warning(L.l("Can't assign {0} to {1}", 93 _map.getClass().getName(), type.getName())); 94 95 return null; 96 } 97 } 98 99 102 public Value copy() 103 { 104 try { 105 Class cl = _map.getClass(); 106 107 Map map = (Map)cl.newInstance(); 108 109 map.putAll(_map); 110 111 return new JavaMapAdapter(getEnv(), map, getClassDef()); 112 } 113 catch (Exception e) { 114 throw new QuercusRuntimeException(e); 115 } 116 } 117 118 121 public int getSize() 122 { 123 return size(); 124 } 125 126 129 public Value get(Value key) 130 { 131 Object obj = _map.get(key.toJavaObject()); 132 133 if (obj != null) 134 return wrapJava(_map.get(key.toJavaObject())); 135 else 136 return UnsetValue.UNSET; 137 } 138 139 142 public Value remove(Value key) 143 { 144 updateNextAvailableIndex(); 145 146 if (key.isLongConvertible() || key instanceof BooleanValue) { 147 long pos = key.toLong(); 149 150 Object value = _map.remove(Long.valueOf(pos)); 151 152 if (value != null) { 153 if (pos + 1 == _nextAvailableIndex) 154 updateNextAvailableIndex(); 155 156 return wrapJava(value); 157 } 158 } 159 else { 160 Object value = _map.remove(key.toJavaObject()); 161 162 if (value != null) 163 return wrapJava(value); 164 } 165 166 return UnsetValue.UNSET; 167 } 168 169 172 public Value createTailKey() 173 { 174 updateNextAvailableIndex(); 175 return LongValue.create(_nextAvailableIndex); 176 } 177 178 181 public Value putImpl(Value key, Value value) 182 { 183 Object keyObject; 184 185 if (key.isLongConvertible() || key instanceof BooleanValue) { 186 keyObject = Long.valueOf(key.toLong()); 187 } 188 else { 189 keyObject = key.toJavaObject(); 190 } 191 192 Value val = wrapJava(_map.put(keyObject, value.toJavaObject())); 193 194 updateNextAvailableIndex(keyObject); 195 196 return val; 197 } 198 199 202 public Set<Map.Entry<Value,Value>> entrySet() 203 { 204 return new MapSet(); 205 } 206 207 210 public Set<Map.Entry> objectEntrySet() 211 { 212 return _map.entrySet(); 213 } 214 215 218 public Collection<Value> values() 219 { 220 return new ValueCollection(); 221 } 222 223 public Value []getValueArray(Env env) 224 { 225 Value[] values = new Value[getSize()]; 226 227 int i = 0; 228 for (Object entry: _map.values()) { 229 values[i++] = env.wrapJava(entry); 230 } 231 232 return values; 233 } 234 235 238 private void updateNextAvailableIndex() 239 { 240 _nextAvailableIndex = 0; 241 242 for (Object key : _map.keySet()) { 243 updateNextAvailableIndex(key); 244 } 245 } 246 247 250 private void updateNextAvailableIndex(Object objectKey) 251 { 252 if (objectKey instanceof Long ) { 253 long key = ((Long )objectKey).longValue(); 254 255 if (_nextAvailableIndex <= key) 256 _nextAvailableIndex = key + 1; 257 } 258 } 259 260 public class MapSet 261 extends AbstractSet<Map.Entry<Value,Value>> 262 { 263 MapSet() 264 { 265 } 266 267 public int size() 268 { 269 return getSize(); 270 } 271 272 public Iterator<Map.Entry<Value,Value>> iterator() 273 { 274 return new MapIterator(_map); 275 } 276 } 277 278 public class MapIterator 279 implements Iterator<Map.Entry<Value,Value>> 280 { 281 private Iterator<Map.Entry> _iterator; 282 283 public MapIterator(Map map) 284 { 285 _iterator = map.entrySet().iterator(); 286 } 287 288 public boolean hasNext() 289 { 290 return _iterator.hasNext(); 291 } 292 293 public Map.Entry<Value,Value> next() 294 { 295 Map.Entry entry = _iterator.next(); 296 297 Value key = wrapJava(entry.getKey()); 298 Value value = wrapJava(entry.getValue()); 299 300 return new MapEntry(key, value); 301 } 302 303 public void remove() 304 { 305 throw new UnsupportedOperationException (); 306 } 307 } 308 309 public static class MapEntry 310 implements Map.Entry<Value,Value> 311 { 312 private final Value _key; 313 private Value _value; 314 315 public MapEntry(Value key, Value value) 316 { 317 _key = key; 318 _value = value; 319 } 320 321 public Value getKey() 322 { 323 return _key; 324 } 325 326 public Value getValue() 327 { 328 return _value; 329 } 330 331 public Value setValue(Value value) 332 { 333 Value oldValue = _value; 334 335 _value = value; 336 337 return oldValue; 338 } 339 } 340 341 public class ValueCollection 342 extends AbstractCollection<Value> 343 { 344 ValueCollection() 345 { 346 } 347 348 public int size() 349 { 350 return getSize(); 351 } 352 353 public Iterator<Value> iterator() 354 { 355 return new ValueIterator(_map.values()); 356 } 357 } 358 359 public class ValueIterator 360 implements Iterator<Value> 361 { 362 private Iterator _iterator; 363 364 public ValueIterator(Collection collection) 365 { 366 _iterator = collection.iterator(); 367 } 368 369 public boolean hasNext() 370 { 371 return _iterator.hasNext(); 372 } 373 374 public Value next() 375 { 376 return wrapJava(_iterator.next()); 377 } 378 379 public void remove() 380 { 381 throw new UnsupportedOperationException (); 382 } 383 } 384 } 385 | Popular Tags |