1 19 20 package org.netbeans.mdr.storagemodel.transientimpl; 21 22 import java.util.ArrayList ; 23 import java.util.HashMap ; 24 import java.util.Set ; 25 import java.util.Collection ; 26 import java.util.Iterator ; 27 import org.netbeans.mdr.persistence.SinglevaluedIndex; 28 import org.netbeans.mdr.persistence.StorageException; 29 import org.netbeans.mdr.persistence.StorageBadRequestException; 30 import org.netbeans.mdr.persistence.Storage; 31 import org.netbeans.mdr.storagemodel.MdrStorage; 32 import org.netbeans.mdr.util.MapEntryImpl; 33 import org.netbeans.mdr.util.DebugException; 34 import org.netbeans.mdr.util.Logger; 35 36 40 public class TransientSinglevaluedIndex extends TransientIndex implements SinglevaluedIndex { 41 42 protected class SinglevaluedEntryKeySet extends EntryKeySet { 43 44 protected ArrayList collectKeys() { 45 ArrayList result = new ArrayList (); 46 for (Iterator it = map.values().iterator(); it.hasNext();) { 47 Entry entry = (Entry) it.next(); 48 if (entry.isValid()) 49 result.add(entry.getKey()); 50 } 51 return result; 52 } 53 54 public java.util.Iterator iterator() { 55 return new SinglevaluedIterator(true); 56 } 57 58 } 59 60 protected class ValuesCollection implements Collection { 61 62 public boolean add(Object obj) { 63 throw new UnsupportedOperationException (); 64 } 65 66 public boolean addAll(java.util.Collection collection) { 67 throw new UnsupportedOperationException (); 68 } 69 70 public void clear() { 71 for (Iterator it = map.values().iterator(); it.hasNext();) { 72 Entry entry = (Entry) it.next(); 73 it.remove(); 74 try { 75 handleRemove(entry.getKey(), entry); 76 } catch (StorageException se) { 77 Logger.getDefault().notify(Logger.INFORMATIONAL, se); 78 } 79 } 80 } 81 82 public boolean contains(Object obj) { 83 for (Iterator it = map.values().iterator(); it.hasNext();) { 84 Entry entry = (Entry) it.next(); 85 Object value = entry.getValue(); 86 if (value == null) { 87 it.remove(); 88 entry.dispose(); 89 } 90 else if (value.equals(obj)) { 91 return true; 92 } 93 } 94 return false; 95 } 96 97 public boolean containsAll(java.util.Collection collection) { 98 boolean result = true; 99 for (Iterator it = collection.iterator(); it.hasNext();) { 100 result &= this.contains(it.next()); 101 } 102 return result; 103 } 104 105 public boolean isEmpty() { 106 expungeStaleEntries(); 107 return map.size() == 0; 108 } 109 110 public java.util.Iterator iterator() { 111 return new SinglevaluedIterator(false); 112 } 113 114 public boolean remove(Object obj) { 115 try { 116 return TransientSinglevaluedIndex.this.remove(obj); 117 }catch (StorageException se) { 118 throw new DebugException(se.toString()); 119 } 120 } 121 122 public boolean removeAll(java.util.Collection collection) { 123 boolean result = false; 124 for (Iterator it = collection.iterator(); it.hasNext();) { 125 result |= this.remove(it.next()); 126 } 127 return result; 128 } 129 130 public boolean retainAll(java.util.Collection collection) { 131 boolean result = false; 132 for (Iterator it = map.values().iterator(); it.hasNext();) { 133 Entry entry = (Entry) it.next(); 134 if (!entry.isValid()) { 135 it.remove(); 136 entry.dispose(); 137 } 138 else if (!collection.contains(entry.getValue())) { 139 it.remove(); 140 try { 141 handleRemove(entry.getKey(), entry); 142 result = true; 143 } catch (StorageException se) { 144 Logger.getDefault().notify(Logger.INFORMATIONAL, se); 145 } 146 } 147 } 148 return result; 149 } 150 151 public int size() { 152 expungeStaleEntries(); 153 return map.size(); 154 } 155 156 public Object [] toArray() { 157 ArrayList result = collectValues(); 158 return result.toArray(); 159 } 160 161 public Object [] toArray(Object [] obj) { 162 ArrayList result = collectValues(); 163 return result.toArray(obj); 164 } 165 166 public ArrayList collectValues() { 167 ArrayList result = new ArrayList (); 168 for (Iterator it = map.values().iterator(); it.hasNext();) { 169 Entry entry = (Entry) it.next(); 170 if (!entry.isValid()) { 171 it.remove(); 172 entry.dispose(); 173 } 174 else 175 result.add(entry.getValue()); 176 } 177 return result; 178 } 179 180 } 181 182 protected class SinglevaluedIterator implements Iterator { 183 184 private Iterator innerIt; 185 private boolean isKey; 186 private Entry top; 187 private Entry last; 188 189 public SinglevaluedIterator(boolean isKey) { 190 this.innerIt = map.values().iterator(); 191 this.isKey = isKey; 192 } 193 194 public boolean hasNext() { 195 while (top == null) { 196 if (!this.innerIt.hasNext()) 197 return false; 198 top = (Entry) this.innerIt.next(); 199 if (!top.isValid()) { 200 top.dispose(); 201 top = null; 202 innerIt.remove(); 203 } 204 } 205 return true; 206 } 207 208 public Object next() { 209 while (top == null) { 210 top = (Entry) this.innerIt.next(); 211 if (!top.isValid()) { 212 top.dispose(); 213 top = null; 214 innerIt.remove(); 215 } 216 } 217 last = top; 218 top = null; 219 if (this.isKey) 220 return last.getKey(); 221 else 222 return last.getValue(); 223 } 224 225 public void remove() { 226 if (last != null) { 227 innerIt.remove(); 228 try { 229 handleRemove(last.getKey(), last); 230 } catch (StorageException se) { 231 Logger.getDefault().notify(Logger.INFORMATIONAL, se); 232 } 233 last = null; 234 } 235 else { 236 throw new IllegalStateException (); 237 } 238 } 239 } 240 241 242 public TransientSinglevaluedIndex(MdrStorage storage, String name, Storage.EntryType keyType, Storage.EntryType valueType) { 243 super(storage, name, keyType, valueType); 244 } 245 246 public void add(Object key, Object value) throws StorageException { 247 this.addNoTx(key, value); 248 this.handleAdd(key, value); 249 } 250 251 public Object get(Object key) throws StorageException, StorageBadRequestException { 252 Object result = this.getIfExists(key); 253 if (result == null) 254 throw new StorageBadRequestException(); 255 return result; 256 } 257 258 public Object getIfExists(Object key) throws StorageException { 259 if (this.map == null) 260 return null; 261 else 262 expungeStaleEntries(); 263 Entry e = (Entry) this.map.get(key); 264 if (e == null) 265 return null; 266 if (!e.isValid()) 267 return null; 268 else 269 return e.getValue(); 270 } 271 272 public Object getObject(Object key, SinglevaluedIndex repos) throws StorageException { 273 Object result = this.getObjectIfExists(key, repos); 274 if (result == null) 275 throw new StorageBadRequestException(); 276 return result; 277 } 278 279 public Object getObjectIfExists(Object key, SinglevaluedIndex repos) throws StorageException { 280 Object result = this.get(key); 281 if (result == null) 282 return result; 283 else 284 return repos.get(repos); 285 } 286 287 protected void handleRemove(Object key, Object value) throws StorageException { 288 Object val =((Entry)value).getValue(); 289 this.txlog.push(new CompensatingTransaction.RemoveCTx(key, val)); 290 ((Entry)value).dispose(); 291 } 292 293 public java.util.Set keySet() throws StorageException { 294 if (this.map == null) 295 this.map = new HashMap (); 296 return new SinglevaluedEntryKeySet(); 297 } 298 299 306 public boolean put(Object key, Object value) throws StorageException { 307 if (this.map == null) 308 this.map = new HashMap (); 309 else 310 expungeStaleEntries(); 311 Entry e = new Entry(key, value); 312 Object oldValue = map.put(key, e); 313 if (oldValue != null) 314 this.handleRemove(key, oldValue); 315 this.handleAdd(key, value); 316 return oldValue != null; 317 } 318 319 327 public void replace(Object key, Object value) throws StorageException, StorageBadRequestException { 328 if (map == null) 329 throw new StorageBadRequestException(); 330 else { 331 expungeStaleEntries(); 332 if (this.map.get(key) == null) 333 throw new StorageBadRequestException(); 334 } 335 Entry e = new Entry(key, value); 336 Object oldValue = this.map.put(key, e); 337 this.handleRemove(key, oldValue); 338 this.handleAdd(key, value); 339 } 340 341 347 public java.util.Collection values() throws StorageException { 348 return new ValuesCollection(); 349 } 350 351 354 public Collection queryByKeyPrefix (Object prefix, SinglevaluedIndex primaryIndex) throws StorageException { 355 if (getKeyType () != Storage.EntryType.STRING) { 356 throw new UnsupportedOperationException ("Key type must be EntryType.STRING"); 357 } 358 if (!(prefix instanceof String )) { 359 throw new StorageBadRequestException ("String object parameter expected."); 360 } 361 362 java.util.List result = new java.util.LinkedList (); 363 Iterator iter = keySet().iterator (); 364 while (iter.hasNext ()) { 365 String key = (String ) iter.next (); 366 if (key.startsWith ((String ) prefix)) { 367 result.add (new MapEntryImpl (key, getObject (key, primaryIndex))); 368 } 369 } 370 return result; 371 } 372 373 protected void expungeStaleEntries() { 374 KeyedReference ref = null; 375 while ((ref = (KeyedReference) this.refQueue.poll()) != null) { 376 Object key = ref.getLookupKey(); 377 Entry e = (Entry) this.map.remove(key); 378 if (e != null) e.dispose(); 380 } 381 } 382 383 protected final void addNoTx(Object key, Object value) throws StorageException { 384 if (this.map == null) { 385 this.map = new HashMap (); 386 } 387 else { 388 expungeStaleEntries(); 389 if (this.map.get(key) != null) 390 throw new StorageBadRequestException(); 391 } 392 Entry e = new Entry(key, value); 393 this.map.put(key, e); 394 } 395 396 protected final Object removeNoTx (Object key, Object value) throws StorageException { 397 expungeStaleEntries(); 398 Entry e = (Entry) this.map.remove(key); 399 Object result = e.getValue (); 400 e.dispose (); 401 return result; 402 } 403 404 } 405 | Popular Tags |