package javolution37.javolution.util;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import javolution37.javolution.realtime.LocalContext;
import javolution37.javolution.realtime.LocalReference;

/**
 * 

This class represents a map which can be temporarily modified * without impacting other threads ({@link LocalContext locally} * scoped changes).

* *

Operation on instances of this class are completely thread-safe. * For example: * public class XmlFormat { * static LocalMap CLASS_TO_FORMAT = new LocalMap(); * public static void setFormat(Class forClass, XmlFormat that) { * CLASS_TO_FORMAT.put(forClass, that); // No synchronization required. * } * public static XmlFormat getInstance(Class forClass) { * return CLASS_TO_FORMAT.get(forClass); // No synchronization required. * } * } * public void main(String[] args) { * // Sets default (global settings). * XmlFormat.setFormat(Foo.class, xFormat); * XmlFormat.setFormat(Bar.class, yFormat); * } * ... // Another thread. * LocalContext.enter(); * try { // Use of local context to avoid impacting other threads. * XmlFormat.setFormat(Foo.class, zFormat); * XmlFormat.getInstance(Foo.class); // Returns zFormat * XmlFormat.getInstance(Bar.class); // Returns yFormat (inherited) * } finally { * LocalContext.exit(); * } * getInstance(Foo.class); // Returns xFormat * [/code]

* *

Note: Because key-value mappings are inherited, the semantic of * {@link #remove} and {@link #clear} is slightly modified (associate * null values instead of removing the entries).

* * @author Jean-Marie Dautelle * @version 3.7, January 27, 2005 */ public final class LocalMap implements Map { /** * Holds the fast map reference (shared map). */ private final LocalReference _mapRef = new LocalReference(new FastMap().setShared(true)); /** * Default constructor. */ public LocalMap() { } /** * Sets the key comparator for this local map. * * @param keyComparator the key comparator. * @return this */ public LocalMap setKeyComparator(FastComparator keyComparator) { localMap().setKeyComparator(keyComparator); return this; } /** * Sets the value comparator for this local map. * * @param valueComparator the value comparator. * @return this */ public LocalMap setValueComparator(FastComparator valueComparator) { localMap().setValueComparator(valueComparator); return this; } /** * Sets the default value for the specified key (typically done at * initialization). * * @param key the key with which the specified value is to be associated. * @param defaultValue the default value to be associated with the * specified key. * @return the previous default value associated with specified key, or * null if there was no mapping for key. A * null return can also indicate that the map * previously associated null with the specified key. * @throws NullPointerException if the key is null. */ public V putDefault( K key, V defaultValue) { return ( V ) ((FastMap) _mapRef.getDefault()).put(key, defaultValue); } /** * Returns the number of key-value mappings in this map. * * @return this map's size. */ public int size() { return ((FastMap) _mapRef.get()).size(); } /** * Indicates if this map contains no key-value mappings. * * @return true if this map contains no key-value mappings; * false otherwise. */ public boolean isEmpty() { return ((FastMap) _mapRef.get()).isEmpty(); } /** * Indicates if this map contains a mapping for the specified key. * * @param key the key whose presence in this map is to be tested. * @return true if this map contains a mapping for the * specified key; false otherwise. * @throws NullPointerException if the key is null. */ public boolean containsKey(Object key) { return ((FastMap) _mapRef.get()).containsKey(key); } /** * Indicates if this map associates one or more keys to the * specified value. * * @param value the value whose presence in this map is to be tested. * @return true if this map maps one or more keys to the * specified value. * @throws NullPointerException if the key is null. */ public boolean containsValue(Object value) { return ((FastMap) _mapRef.get()).containsValue(value); } /** * Returns the value to which this map associates the specified key. * * @param key the key whose associated value is to be returned. * @return the value to which this map maps the specified key, or * null if there is no mapping for the key. * @throws NullPointerException if key is null. */ public V get(Object key) { return ( V ) ((FastMap) _mapRef.get()).get(key); } /** * Associates the specified value with the specified key in this map. * * @param key the key with which the specified value is to be associated. * @param value the value to be associated with the specified key. * @return the previous value associated with specified key, or * null if there was no mapping for key. A * null return can also indicate that the map * previously associated null with the specified key. * @throws NullPointerException if the key is null. */ public V put( K key, V value) { return ( V ) localMap().put(key, value); } /** * Copies all of the mappings from the specified map to this map. * * @param map the mappings to be stored in this map. * @throws NullPointerException the specified map is null, * or the specified map contains null keys. */ public void putAll(Map map) { localMap().putAll(map); } /** * Removes the mapping for this key from this map if present * (sets the local value to null). * * @param key the key whose value is set to null * @return put(key, null) * @throws NullPointerException if the key is null. */ public V remove(Object key) { return put(( K )key, null); } /** * Removes all mappings from this map (sets the local values to * null). */ public void clear() { FastMap localMap = localMap(); for (FastMap.Entry e = localMap.head(), end = localMap.tail(); (e = (FastMap.Entry) e.getNext()) != end;) { e.setValue(null); } } /** * Returns a {@link FastCollection} view of the keys contained in this map. * * @return a set view of the keys contained in this map * (instance of {@link FastCollection}). */ public Set keySet() { return localMap().keySet(); } /** * Returns a {@link FastCollection} view of the values contained in this * map. * * @return a collection view of the values contained in this map * (instance of {@link FastCollection}). */ public Collection values() { return localMap().values(); } /** * Returns a {@link FastCollection} view of the mappings contained in this * map. * * @return a collection view of the mappings contained in this map * (instance of {@link FastCollection}). */ public Set > entrySet() { return localMap().entrySet(); } /** * Returns the local map or creates one on the stack and populates * it from inherited settings. * * @return a shared fast map belonging to the current local context. */ private FastMap localMap() { FastMap localMap = (FastMap) _mapRef.getLocal(); return (localMap != null) ? localMap : newLocalMap(); } private FastMap newLocalMap() { FastMap parentMap = (FastMap) _mapRef.get(); FastMap localMap = FastMap.newInstance(); localMap.setShared(true); localMap.setKeyComparator(parentMap.getKeyComparator()); localMap.setValueComparator(parentMap.getValueComparator()); localMap.putAll(parentMap); _mapRef.set(localMap); return localMap; } }

Ads help maintain this website.