1 19 20 package org.netbeans.mdr.storagemodel.transientimpl; 21 22 import java.lang.ref.Reference ; 23 import java.lang.ref.ReferenceQueue ; 24 import java.lang.ref.WeakReference ; 25 import java.util.ArrayList ; 26 import java.util.HashMap ; 27 import java.util.Set ; 28 import java.util.Collection ; 29 import java.util.Iterator ; 30 import org.netbeans.mdr.persistence.*; 31 import org.netbeans.mdr.storagemodel.StorableBaseObject; 32 import org.netbeans.mdr.storagemodel.TransientStorableObject; 33 import org.netbeans.mdr.storagemodel.MdrStorage; 34 import org.netbeans.mdr.util.DebugException; 35 39 public abstract class TransientIndex extends TransactionalIndex { 40 41 private String name; 42 private Storage.EntryType keyType; 43 private Storage.EntryType valueType; 44 protected MdrStorage storage; 45 protected HashMap map; 46 protected ReferenceQueue refQueue; 47 48 49 protected static class KeyedReference extends WeakReference { 50 51 private org.netbeans.mdr.persistence.MOFID key; 52 53 public KeyedReference(Object referent, ReferenceQueue queue, org.netbeans.mdr.persistence.MOFID key) { 54 super(referent, queue); 55 this.key = key; 56 } 57 58 public org.netbeans.mdr.persistence.MOFID getLookupKey() { 59 return this.key; 60 } 61 } 62 63 protected class Entry { 64 65 private Object key; 66 private Object value; 67 68 73 public Entry(Object firstEnd, Object secondEnd) throws StorageException { 74 TransientStorableObject firstEndObj = null; 75 if (MdrStorage.isTransientMofId((org.netbeans.mdr.persistence.MOFID)firstEnd)) { 76 firstEndObj = (TransientStorableObject) TransientIndex.this.storage.getObject((org.netbeans.mdr.persistence.MOFID)firstEnd); 77 if (firstEndObj == null) 78 throw new StorageBadRequestException(); 79 key = new KeyedReference(firstEndObj, refQueue, (org.netbeans.mdr.persistence.MOFID)firstEnd); 80 } 81 else { 82 key = firstEnd; 83 } 84 85 if (MdrStorage.isTransientMofId((org.netbeans.mdr.persistence.MOFID)secondEnd)) { 86 TransientStorableObject secondEndObj = (TransientStorableObject) TransientIndex.this.storage.getObject((org.netbeans.mdr.persistence.MOFID)secondEnd); 87 if (secondEndObj == null) 88 throw new StorageBadRequestException(); 89 value = new KeyedReference(secondEndObj, refQueue, (org.netbeans.mdr.persistence.MOFID)firstEnd); 90 if (firstEndObj != null) 91 firstEndObj.addReferent(secondEndObj); 92 } 93 else { 94 value = secondEnd; 95 } 96 } 97 98 103 public void dispose() { 104 if ((this.key instanceof Reference ) && (this.value instanceof Reference )) { 105 TransientStorableObject ktso = (TransientStorableObject) ((Reference )this.key).get(); 106 TransientStorableObject vtso = (TransientStorableObject) ((Reference )this.value).get(); 107 if (ktso != null) 108 ktso.removeReferent(vtso); 109 } 110 } 111 112 116 public boolean isValid() { 117 if ((this.key instanceof Reference ) && ((Reference )this.key).get() == null) { 118 return false; 119 } 120 if (value instanceof Reference ) { 121 return (((Reference )value).get() != null); 122 } 123 else { 124 return true; 125 } 126 } 127 128 130 public org.netbeans.mdr.persistence.MOFID getValue() { 131 if (this.value instanceof Reference ) { 132 TransientStorableObject result = (TransientStorableObject) ((Reference ) this.value).get(); 133 if (result != null) 134 return result.getMofId(); 135 else 136 return null; 137 } 138 else { 139 return (org.netbeans.mdr.persistence.MOFID) this.value; 140 } 141 } 142 143 public org.netbeans.mdr.persistence.MOFID getKey() { 144 if (this.key instanceof Reference ) { 145 TransientStorableObject tso = (TransientStorableObject) ((Reference )this.key).get(); 146 if (tso == null) 147 return null; 148 else 149 return tso.getMofId(); 150 } 151 else 152 return (org.netbeans.mdr.persistence.MOFID) this.key; 153 } 154 155 public int hashCode() { 156 return this.getKey().hashCode(); 157 } 158 159 public boolean equals(Object other) { 160 if (!(other instanceof Entry)) 161 return false; 162 Entry e = (Entry) other; 163 return this.getValue().equals(e.getValue()) && 164 this.getKey().equals(e.getKey()); 165 } 166 167 } 168 169 protected abstract class EntryKeySet implements Set { 170 171 172 public boolean add(Object o) { 173 throw new UnsupportedOperationException (); 174 } 175 176 public boolean addAll(Collection c) { 177 throw new UnsupportedOperationException (); 178 } 179 180 public void clear() { 181 for (Iterator it = TransientIndex.this.map.keySet().iterator(); it.hasNext();) { 182 Object keyMofId = it.next(); 183 Object values = TransientIndex.this.map.get(keyMofId); 184 it.remove(); 185 try { 186 TransientIndex.this.handleRemove(keyMofId, values); 187 }catch (StorageException se) { 188 throw new DebugException(se.toString()); 189 } 190 } 191 } 192 193 public boolean contains(Object o) { 194 TransientIndex.this.expungeStaleEntries(); 195 Entry e = (Entry) TransientIndex.this.map.get(o); 196 return (e != null && e.isValid()); 197 } 198 199 public boolean containsAll(Collection c) { 200 boolean result = true; 201 for (Iterator it = c.iterator(); it.hasNext(); ) { 202 result &= this.contains(it.next()); 203 } 204 return result; 205 } 206 207 public boolean isEmpty() { 208 TransientIndex.this.expungeStaleEntries(); 209 return TransientIndex.this.map.size() == 0; 210 } 211 212 public boolean remove(Object o) { 213 try { 214 Object values = TransientIndex.this.map.get(o); 215 TransientIndex.this.remove(o); 216 handleRemove(o, values); 217 return values != null; 218 }catch (StorageException se) { 219 return false; 220 } 221 } 222 223 public boolean removeAll(Collection c) { 224 boolean result = false; 225 for (Iterator it = c.iterator(); it.hasNext();) { 226 result |= this.remove(it.next()); 227 } 228 return result; 229 } 230 231 public boolean retainAll(Collection c) { 232 TransientIndex.this.expungeStaleEntries(); 233 boolean result = false; 234 for (Iterator it = TransientIndex.this.map.keySet().iterator(); it.hasNext(); ) { 235 Object key = it.next(); 236 if (!c.contains(key)) { 237 Object values = TransientIndex.this.map.get(key); 238 it.remove(); 239 try { 240 TransientIndex.this.handleRemove(key, values); 241 }catch (StorageException se) { 242 throw new DebugException(se.toString()); 243 } 244 result = true; 245 } 246 } 247 return result; 248 } 249 250 public int size() { 251 TransientIndex.this.expungeStaleEntries(); 252 return TransientIndex.this.map.size(); 253 } 254 255 public Object [] toArray() { 256 return this.collectKeys().toArray(); 257 } 258 259 260 public Object [] toArray(Object [] a) { 261 return this.collectKeys().toArray(a); 262 } 263 264 public abstract Iterator iterator(); 265 266 protected abstract ArrayList collectKeys(); 267 268 } 269 270 271 272 public TransientIndex(MdrStorage storage, String name, Storage.EntryType keyType, Storage.EntryType valueType) { 273 this.refQueue = new ReferenceQueue (); 274 this.storage = storage; 275 this.name = name; 276 this.keyType = keyType; 277 this.valueType = valueType; 278 } 279 280 public abstract void add(Object key, Object value) throws StorageException; 281 282 public Storage.EntryType getKeyType() throws StorageException { 283 return this.keyType; 284 } 285 286 public String getName() throws StorageException { 287 return this.name; 288 } 289 290 public Storage.EntryType getValueType() throws StorageException { 291 return this.valueType; 292 } 293 294 295 296 public boolean remove(Object key) throws StorageException { 297 expungeStaleEntries(); 298 Object value = this.map.remove(key); 299 this.handleRemove(key, value); 300 return value != null; 301 } 302 303 304 public abstract java.util.Set keySet() throws StorageException; 305 306 protected abstract void expungeStaleEntries(); 307 308 protected abstract void handleRemove(Object key, Object value) throws StorageException; 309 310 protected void handleAdd(Object key, Object value) { 311 this.txlog.push(new CompensatingTransaction.AddCTx(key, value)); 312 } 313 314 } 315 | Popular Tags |