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 org.netbeans.mdr.persistence.*;
import java.util.*;
import java.io.*;

import org.netbeans.mdr.util.*;

/** Default memory implementation of {@link
 *  org.netbeans.mdr.persistence.MultivaluedIndex} using 
 *  {@link java.util.Hashtable}.
 *
 * 

[PENDING]: {@link #isUnique()} is ignored when adding new values. * @author Pavel Buzek, Martin Matula * @version */ public abstract class MultivaluedIndexImpl implements MultivaluedIndex, Streamable { /* -------------------------------------------------------------------- */ /* -- Private atttributes --------------------------------------------- */ /* -------------------------------------------------------------------- */ protected String name; protected Storage.EntryType keyType; protected Storage.EntryType valueType; protected boolean unique; protected Map entries; protected StorageImpl storage; protected MultivalueLog transLog = new MultivalueLog (this); /* -------------------------------------------------------------------- */ /* -- Constructors ---------------------------------------------------- */ /* -------------------------------------------------------------------- */ /** Creates a new multi-valued index. */ public MultivaluedIndexImpl(String name, StorageImpl storage, Storage.EntryType keyType, Storage.EntryType valueType, boolean unique) { this.name = name; this.keyType = keyType; this.valueType = valueType; this.unique = unique; this.storage = storage; entries = new HashMap(); } /** Constructor used when restoring the streamable index from a stream. */ public MultivaluedIndexImpl() { } /* -------------------------------------------------------------------- */ /* -- 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; } public synchronized boolean remove(Object key) throws StorageException { Object value = entries.remove(key); if (value != null) { transLog.logRemoveKey(key, value); return true; } else return false; } public synchronized java.util.Set keySet() throws StorageException { return entries.keySet(); } /** Appends the specified element to the end of the list of values * associated with the specified key. */ public synchronized void add(Object key,Object value) throws StorageException { Collection vals = (Collection) entries.get (key); if (vals == null) { vals = new ArrayList (); entries.put(key, vals); } else if (unique && vals.contains(value)) { throw createValueAlreadyContainedExc(key, value); } vals.add(value); transLog.logAdd(key, value); } /* -------------------------------------------------------------------- */ /* -- Implementation of org.netbeans.mdr.persistence.MultivaluedIndex */ /* -------------------------------------------------------------------- */ public boolean isUnique() throws StorageException { return unique; } public synchronized java.util.Collection getItems(Object key) throws StorageException { Collection vals = (Collection) entries.get(key); if (vals == null) { vals = new ArrayList(); entries.put(key, vals); } return new MIWrapper((List) vals, key); } public synchronized java.util.Collection getObjects(Object key, SinglevaluedIndex s) throws StorageException { if (keyType == Storage.EntryType.MOFID) { return new MOWrapper((List) getItems(key), s, key); } else { return getItems(key); } } /** Removes the first occurrence of the specified element in the list * of values associated with the specified key. */ public synchronized boolean remove(Object key,Object value) throws StorageException { Collection vals = (Collection) entries.get (key); if (vals != null && vals.remove(value)) { transLog.logRemove(key, value); return true; } else { return false; } } /* -------------------------------------------------------------------- */ /* -- 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, entries, 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()); entries = (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 = entries.keySet().iterator (); while (iter.hasNext ()) { String key = (String) iter.next (); if (key.startsWith ((String) prefix)) { result.add (new MapEntryImpl (key, getObjects (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 -------------------------- */ /* -------------------------------------------------------------------- */ protected static boolean isUniqueValue(List list, Object value, int index) { Iterator iter = list.iterator(); for (int x = 0; iter.hasNext(); x++) { Object obj = iter.next(); if (x == index) continue; if (value.equals(obj)) return false; } return true; } protected StorageBadRequestException createValueAlreadyContainedExc(Object key, Object value) { return new StorageBadRequestException("Unique index already contains value " + value + " for key " + key); } public void changed(Object key) { } void setKey(Object key, Object vals) { entries.put(key, vals); } private class MIWrapper extends AbstractList { private final List inner; private final Object key; public MIWrapper(List inner, Object key) { this.inner = inner; this.key = key; } public Object get(int param) { synchronized (MultivaluedIndexImpl.this) { return inner.get(param); } } public int size() { synchronized (MultivaluedIndexImpl.this) { return inner.size(); } } public Object set(int index, Object element) { synchronized (MultivaluedIndexImpl.this) { Object orig; if (unique && !isUniqueValue(inner, element, index)) { throw new RuntimeStorageException(createValueAlreadyContainedExc(key, element)); } if ((orig = inner.set(index, element)) != null) { transLog.logReplace(key, orig, index); } return orig; } } public void add(int index, Object element) { synchronized (MultivaluedIndexImpl.this) { if (unique && inner.contains(element)) { throw new RuntimeStorageException(createValueAlreadyContainedExc(key, element)); } inner.add(index, element); transLog.logAdd(key, element, index); } } public Object remove(int index) { synchronized (MultivaluedIndexImpl.this) { Object orig; if ((orig = inner.remove(index)) != null) { transLog.logRemove(key, orig, index); return orig; } else { return null; } } } } private class MOWrapper extends AbstractList { private final List inner; private final SinglevaluedIndex pi; private final Object key; public MOWrapper(List inner, SinglevaluedIndex pi, Object key) { this.inner = inner; this.pi = pi; this.key = key; } public Object get(int param) { try { return pi.get(inner.get(param)); } catch (StorageException e) { throw (RuntimeException) Logger.getDefault().annotate(new RuntimeException(), e); } } public int size() { synchronized (MultivaluedIndexImpl.this) { return inner.size(); } } public Object set(int index, Object element) { if (element instanceof MOFID) { if (unique && !isUniqueValue(inner, element, index)) { throw new RuntimeStorageException(createValueAlreadyContainedExc(key, element)); } return inner.set(index, element); } else { throw new IllegalArgumentException(); } } public void add(int index, Object element) { if (element instanceof MOFID) { if (unique && inner.contains(element)) { throw new RuntimeStorageException(createValueAlreadyContainedExc(key, element)); } inner.add(index, element); } else { throw new IllegalArgumentException(); } } public Object remove(int index) { return inner.remove(index); } } }

... 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.