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.persistence.memoryimpl;

import java.util.*;
import java.io.*;

import org.netbeans.mdr.persistence.*;
import org.netbeans.mdr.util.*;

/** Default memory implementation of {@link
 *  org.netbeans.mdr.persistence.SinglevaluedIndex} using 
 *  {@link java.util.Hashtable}.
 * @author  Pavel Buzek
 * @version 
 */
public class SinglevaluedIndexImpl extends Object implements SinglevaluedIndex, Streamable {

    /* -------------------------------------------------------------------- */
    /* -- Private attributes ---------------------------------------------- */
    /* -------------------------------------------------------------------- */

    private String name;
    private Storage.EntryType keyType;
    private Storage.EntryType valueType;
    protected Map table;
    protected StorageImpl storage;
    
    protected TransactionLog transLog = new TransactionLog (this);

    /* -------------------------------------------------------------------- */
    /* -- Constructors ---------------------------------------------------- */
    /* -------------------------------------------------------------------- */

    /** Constructor used when restoring the streamable index from a stream. */
    public SinglevaluedIndexImpl () {
    }
    
    /** Creates a new single-valued index. */
    public SinglevaluedIndexImpl(String name, StorageImpl storage, Storage.EntryType keyType, Storage.EntryType valueType) {
        this.name = name;
        this.keyType = keyType;
        this.valueType = valueType;
        table = new HashMap();
        this.storage = storage;
    }

    /* -------------------------------------------------------------------- */
    /* -- Implementation of org.netbeans.mdr.persistence.Index ------------ */
    /* -------------------------------------------------------------------- */
    
    public String getName() throws StorageException {
        return this.name;
    }

    public Storage.EntryType getValueType() throws StorageException {
        return this.valueType;
    }

    public Storage.EntryType getKeyType() throws StorageException {
        return this.keyType;
    }
    
    /** Returns a set view of the keys contained in this index.
     * Returned set is read only and may not be modified.
     * @return keys contained in this index
     * @throws StorageException
     */
    public synchronized java.util.Set keySet() throws StorageException {
        return table.keySet();
    }
    
    /** Adds the specified value to values associated in this index with the
     * specified key. If the index puts limit on number of values associated
     * with one key and adding value would break this limit, it throws
     * StorageBadRequestException.
     * @param key
     * @param value
     * @throws StorageException
     */
    public synchronized void add(Object key,Object value) throws StorageException {        
        Object original = table.put (key, value);
        if (original != null) {
            table.put(key, original);
            throw new StorageBadRequestException (
                "Cannot add more than one item to key in single-valued index.");
        }
        transLog.logAdd (key);
    }
    
    /** Removes all values assosiated in the index with specified key.
     * @return true if this index changed as a result of this call
     * @param key
     * @throws StorageException
     */
    public synchronized boolean remove(Object key) throws StorageException {
        Object value = table.remove(key);
        if (value != null) {
            transLog.logRemove (key, value);
            return true;
        } else {
            return false;
        }
    }

    /* -------------------------------------------------------------------- */
    /* -- Implementation of org.netbeans.mdr.persistence.SinglevaluedIndex  */
    /* -------------------------------------------------------------------- */
    
    /** Associates the specified value with the specified key in this index.
     * @return true if there was an item in this index that was associated with the key
     * prior to this call
     * @param key
     * @param value
     * @throws StorageException
     */
    public synchronized boolean put(Object key,Object value) throws StorageException {                
        Object old = table.put(key, value);
        if (old == null) {
            transLog.logAdd (key);
            return false;
        } else {
            transLog.logReplace (key, old);
            return true;
        }
    }
    
    /** Replaces the original value associated with the specified key in this index
     * with new value. If no value was associated with this key prior to this call
     * StorageBadRequestException is thrown.
     * @param key
     * @param value
     * @throws StorageException
     * @throws StorageBadRequestException if the index has no entry with the given
     *           key 
     */
    public synchronized void replace(Object key, Object value) throws StorageException {
        Object original = table.put(key, value);
        if (original == null) {
            table.remove(key);
            throw new StorageBadRequestException ("Cannot replace item that does not exist in the index.");
        }
        transLog.logReplace (key, original);
    }
    
    /** Returns the value to which this index maps the specified key.
     * StorageBadRequestException is thrown if there is no value for the key.
     * @return value associated with specified key
     * @param key
     * @throws StorageException
     * @throws StorageBadRequestException
     */
    public synchronized Object get(Object key) throws StorageException {
        Object value = table.get(key);
        if (value == null) {            
            throw new StorageBadRequestException ("Item not found: " + key);
        }        
        return value;        
    }
    
    /** Like get, but if the index contains keys, this returns the object 
     * corresponding to the key
     * @return
     * @param key
     * @throws StorageException
     */
    public synchronized Object getObject (Object key, SinglevaluedIndex repos) throws StorageException {
        if (keyType == Storage.EntryType.MOFID) {
            synchronized (repos) {
                return repos.get(get(key));
            }
        } else {
            return get(key);
        }
    }

    /** Returns the value to which this index maps the specified key
     * or null if there is no value for this key.
     * @return value associated with specified key or null
     * @param key
     * @throws StorageException
     */
    public synchronized Object getIfExists(Object key) throws StorageException {
        return table.get (key);
    }

    /** Like getIfExists, but if the index contains keys, this returns the object 
     * corresponding to the key
     * @return
     * @param key
     * @throws StorageException
     */
    public synchronized Object getObjectIfExists (Object key, SinglevaluedIndex repos) throws StorageException {
    	Object val = getIfExists(key);
        if (val == null) {
            return null;
        } else {
            if (keyType == Storage.EntryType.MOFID) {
                synchronized (repos) {
                    return repos.get(val);
                }
            } else {
                return val;
            }
        }
    }
    
    /** Returns a collection view of the values contained in this index.
     * Returned collection is read only and may not be modified.
     * If this index has no items, empty Collection is returned.
     * @return
     * @throws StorageException
     */
    public synchronized java.util.Collection values() throws StorageException {
        return table.values();
    }

    /* -------------------------------------------------------------------- */
    /* -- Implementation of org.netbeans.mdr.persistence.Streamable ------- */
    /* -------------------------------------------------------------------- */

    /** This method will be used to move changed object from storage cache
     * to the persistent part of storage. It writes the object`s state
     * (set of attributes) in the stream as an array of bytes, for example
     * in textual representation.
     * @param outputStream OutputStream that holds value of a Streamable object
     */
    public void write(java.io.OutputStream out) throws StorageException {
        try {
            IOUtils.writeString(out, name);
            out.write(keyType.encode());
            out.write(valueType.encode());
            Utils.write(out, table, storage);
        } catch (java.io.IOException e) {
            throw new StorageIOException(e);
        }
    }
    /** Restore state of the Storable object from the stream.
     * @param inputStream InputStream that represents an internal representation of fields of a Streamable object
     * in which it was written by {@link write } method
     */
    public void read(java.io.InputStream is) throws StorageException {
        try {
            name = IOUtils.readString(is);
            keyType = Storage.EntryType.decodeEntryType((byte) is.read());
            valueType = Storage.EntryType.decodeEntryType((byte) is.read());
            table = (Map) Utils.read(is, storage);
        } catch (java.io.IOException e) {
            throw new StorageIOException(e);
        }
    }

    /**
     * Returns key-value pairs, where the key contains the queried prefix.
     */
    public synchronized Collection queryByKeyPrefix (Object prefix, SinglevaluedIndex primaryIndex) throws StorageException {
        if (keyType != Storage.EntryType.STRING) {
            throw new UnsupportedOperationException ("Key type must be EntryType.STRING");
        }
        if (!(prefix instanceof String)) {
            throw new StorageBadRequestException ("String object parameter expected.");
        }
        
        List result = new LinkedList ();
        Iterator iter = table.keySet().iterator ();
        while (iter.hasNext ()) {            
            String key = (String) iter.next ();
            if (key.startsWith ((String) prefix)) {
                result.add (new MapEntryImpl (key, getObject (key, primaryIndex)));
            }
        }
        return result;
    }
    
    /* -------------------------------------------------------------------- */
    /* -- Transaction support --------------------------------------------- */
    /* -------------------------------------------------------------------- */        
    
    protected synchronized void rollBackChanges () throws StorageException {        
        transLog.rollBack ();
        transLog.clear ();        
    }
    
    protected synchronized void commitChanges () throws StorageException {        
        transLog.clear ();
    }
    
    /* -------------------------------------------------------------------- */
    /* -- Methods not specified by any interface -------------------------- */
    /* -------------------------------------------------------------------- */

    /** Does nothing. */
    public void changed (Object key) {
    }
}
... 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.