blob: 82a65faf92e0b3c714b6e46fd2dae2a9c85ed814 [file] [log] [blame]
/**********************************************************************
* This file is part of the "Object Teams Runtime Environment"
*
* Copyright 2010 Stephan Herrmann.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Stephan Herrmann - Initial API and implementation
**********************************************************************/
package org.objectteams;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/**
* This class defines hash maps where both key and value are weak references.
* It is implemented by delegating to a WeakHashMap and additionally
* wrapping the value in a WeakReference.
*
* @author stephan
* @since 0.7.0
* @param <K> type of keys: a base class
* @param <V> type of values: a role class
*/
public class DoublyWeakHashMap<K,V> implements Map<K,V> {
private WeakHashMap<K, WeakReference<V>> map;
public DoublyWeakHashMap() {
this.map = new WeakHashMap<K, WeakReference<V>>();
}
public int size() {
return this.map.size();
}
public boolean isEmpty() {
return this.map.isEmpty();
}
// used from hasRole() and lifting (duplicate role check)
public boolean containsKey(Object key) {
return this.map.containsKey(key);
}
public boolean containsValue(Object value) {
throw new UnsupportedFeatureException("Method containsValue is not implemented for internal class DoublyWeakHashMap.");
}
// used from getRole()
public V get(Object key) {
WeakReference<V> valRef = this.map.get(key);
return valRef == null ? null : valRef.get();
}
// used from migrateToBase() and lifting constructor
public synchronized V put(K key, V value) {
this.map.put(key, new WeakReference<V>(value));
return value;
}
// used from unregisterRole(), migrateToBase()
public synchronized V remove(Object key) {
WeakReference<V> value = this.map.remove(key);
return (value == null) ? null : value.get();
}
public void putAll(Map<? extends K, ? extends V> t) {
for (Entry<? extends K, ? extends V> entry : t.entrySet())
this.map.put(entry.getKey(), new WeakReference<V>(entry.getValue()));
}
public void clear() {
this.map.clear();
}
public Set<K> keySet() {
return this.map.keySet();
}
// used from getAllRoles() et al.
public synchronized Collection<V> values() {
ArrayList<V> result = new ArrayList<V>(this.map.size());
for (WeakReference<V> valRef : this.map.values()) {
V value = valRef.get();
if (value != null)
result.add(value);
}
return result;
}
public Set<java.util.Map.Entry<K, V>> entrySet() {
throw new UnsupportedFeatureException("Method entrySet is not implemented for internal class DoublyWeakHashMap.");
}
}