alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

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

 

new blog posts

 

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.