|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.mdr.storagemodel.transientimpl; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; import java.util.Collection; import java.util.Iterator; import org.netbeans.mdr.persistence.*; import org.netbeans.mdr.storagemodel.StorableBaseObject; import org.netbeans.mdr.storagemodel.TransientStorableObject; import org.netbeans.mdr.storagemodel.MdrStorage; import org.netbeans.mdr.util.DebugException; /** * * @author Tomas Zezula */ public abstract class TransientIndex extends TransactionalIndex { private String name; private Storage.EntryType keyType; private Storage.EntryType valueType; protected MdrStorage storage; protected HashMap map; protected ReferenceQueue refQueue; protected static class KeyedReference extends WeakReference { private org.netbeans.mdr.persistence.MOFID key; public KeyedReference(Object referent, ReferenceQueue queue, org.netbeans.mdr.persistence.MOFID key) { super(referent, queue); this.key = key; } public org.netbeans.mdr.persistence.MOFID getLookupKey() { return this.key; } } protected class Entry { private Object key; private Object value; /** Creates new association link entry * In case that some of object is transient * it needs to resolve it and hold week reference * to be able to detect that the entry should be freed */ public Entry(Object firstEnd, Object secondEnd) throws StorageException { TransientStorableObject firstEndObj = null; if (MdrStorage.isTransientMofId((org.netbeans.mdr.persistence.MOFID)firstEnd)) { firstEndObj = (TransientStorableObject) TransientIndex.this.storage.getObject((org.netbeans.mdr.persistence.MOFID)firstEnd); if (firstEndObj == null) throw new StorageBadRequestException(); key = new KeyedReference(firstEndObj, refQueue, (org.netbeans.mdr.persistence.MOFID)firstEnd); } else { key = firstEnd; } if (MdrStorage.isTransientMofId((org.netbeans.mdr.persistence.MOFID)secondEnd)) { TransientStorableObject secondEndObj = (TransientStorableObject) TransientIndex.this.storage.getObject((org.netbeans.mdr.persistence.MOFID)secondEnd); if (secondEndObj == null) throw new StorageBadRequestException(); value = new KeyedReference(secondEndObj, refQueue, (org.netbeans.mdr.persistence.MOFID)firstEnd); if (firstEndObj != null) firstEndObj.addReferent(secondEndObj); } else { value = secondEnd; } } /** Called in removed method * it must free reference in graph of objects * in case that both ends are transient. * Otherwise does nothing */ public void dispose() { if ((this.key instanceof Reference) && (this.value instanceof Reference)) { TransientStorableObject ktso = (TransientStorableObject) ((Reference)this.key).get(); TransientStorableObject vtso = (TransientStorableObject) ((Reference)this.value).get(); if (ktso != null) ktso.removeReferent(vtso); } } /** Tests the validity of entry * The entry is valid if both ends refers to valid * objects (MOFID->W(!NULL), W(!NULL)->MOFID, W(!NULL)->W(!NULL)) */ public boolean isValid() { if ((this.key instanceof Reference) && ((Reference)this.key).get() == null) { return false; } if (value instanceof Reference) { return (((Reference)value).get() != null); } else { return true; } } /** Retuns the value of end as MOFID */ public org.netbeans.mdr.persistence.MOFID getValue() { if (this.value instanceof Reference) { TransientStorableObject result = (TransientStorableObject) ((Reference) this.value).get(); if (result != null) return result.getMofId(); else return null; } else { return (org.netbeans.mdr.persistence.MOFID) this.value; } } public org.netbeans.mdr.persistence.MOFID getKey() { if (this.key instanceof Reference) { TransientStorableObject tso = (TransientStorableObject) ((Reference)this.key).get(); if (tso == null) return null; else return tso.getMofId(); } else return (org.netbeans.mdr.persistence.MOFID) this.key; } public int hashCode() { return this.getKey().hashCode(); } public boolean equals(Object other) { if (!(other instanceof Entry)) return false; Entry e = (Entry) other; return this.getValue().equals(e.getValue()) && this.getKey().equals(e.getKey()); } } protected abstract class EntryKeySet implements Set { public boolean add(Object o) { throw new UnsupportedOperationException(); } public boolean addAll(Collection c) { throw new UnsupportedOperationException(); } public void clear() { for (Iterator it = TransientIndex.this.map.keySet().iterator(); it.hasNext();) { Object keyMofId = it.next(); Object values = TransientIndex.this.map.get(keyMofId); it.remove(); try { TransientIndex.this.handleRemove(keyMofId, values); }catch (StorageException se) { throw new DebugException(se.toString()); } } } public boolean contains(Object o) { TransientIndex.this.expungeStaleEntries(); Entry e = (Entry) TransientIndex.this.map.get(o); return (e != null && e.isValid()); } public boolean containsAll(Collection c) { boolean result = true; for (Iterator it = c.iterator(); it.hasNext(); ) { result &= this.contains(it.next()); } return result; } public boolean isEmpty() { TransientIndex.this.expungeStaleEntries(); return TransientIndex.this.map.size() == 0; } public boolean remove(Object o) { try { Object values = TransientIndex.this.map.get(o); TransientIndex.this.remove(o); handleRemove(o, values); return values != null; }catch (StorageException se) { return false; } } public boolean removeAll(Collection c) { boolean result = false; for (Iterator it = c.iterator(); it.hasNext();) { result |= this.remove(it.next()); } return result; } public boolean retainAll(Collection c) { TransientIndex.this.expungeStaleEntries(); boolean result = false; for (Iterator it = TransientIndex.this.map.keySet().iterator(); it.hasNext(); ) { Object key = it.next(); if (!c.contains(key)) { Object values = TransientIndex.this.map.get(key); it.remove(); try { TransientIndex.this.handleRemove(key, values); }catch (StorageException se) { throw new DebugException(se.toString()); } result = true; } } return result; } public int size() { TransientIndex.this.expungeStaleEntries(); return TransientIndex.this.map.size(); } public Object[] toArray() { return this.collectKeys().toArray(); } public Object[] toArray(Object[] a) { return this.collectKeys().toArray(a); } public abstract Iterator iterator(); protected abstract ArrayList collectKeys(); } /** Creates a new instance of TransientIndex */ public TransientIndex(MdrStorage storage, String name, Storage.EntryType keyType, Storage.EntryType valueType) { this.refQueue = new ReferenceQueue(); this.storage = storage; this.name = name; this.keyType = keyType; this.valueType = valueType; } public abstract void add(Object key, Object value) throws StorageException; public Storage.EntryType getKeyType() throws StorageException { return this.keyType; } public String getName() throws StorageException { return this.name; } public Storage.EntryType getValueType() throws StorageException { return this.valueType; } public boolean remove(Object key) throws StorageException { expungeStaleEntries(); Object value = this.map.remove(key); this.handleRemove(key, value); return value != null; } public abstract java.util.Set keySet() throws StorageException; protected abstract void expungeStaleEntries(); protected abstract void handleRemove(Object key, Object value) throws StorageException; protected void handleAdd(Object key, Object value) { this.txlog.push(new CompensatingTransaction.AddCTx(key, value)); } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.