package net.sourceforge.mayfly.util;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class ImmutableMap<K, V> implements Map<K, V> {
Map<K, V> delegate;
public ImmutableMap() {
delegate = Collections.EMPTY_MAP;
}
public ImmutableMap(Map map) {
delegate = Collections.unmodifiableMap(new LinkedHashMap(map));
}
public ImmutableMap(K key, V value) {
delegate = Collections.singletonMap(key, value);
}
private ImmutableMap(Map alreadyCopied, boolean didICopyIt) {
if (!didICopyIt) {
throw new RuntimeException("Call with() or public constructor instead");
}
delegate = Collections.unmodifiableMap(alreadyCopied);
}
public ImmutableMap with(K key, V value) {
Map copy = new LinkedHashMap(this);
copy.put(key, value);
return new ImmutableMap(copy, true);
}
public ImmutableMap add(K key, V value) {
Map copy = new LinkedHashMap(this);
if (copy.put(key, value) != null) {
throw new RuntimeException("key " + key + " already exists");
}
return new ImmutableMap(copy, true);
}
public ImmutableMap without(K key) {
Map copy = new LinkedHashMap(this);
if (copy.remove(key) == null) {
throw new NoSuchKeyException(key.toString());
}
return new ImmutableMap(copy, true);
}
public void clear() {
throw new UnsupportedOperationException("Attempt to mutate immutable map");
}
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
public Set<Map.Entry<K, V>> entrySet() {
return delegate.entrySet();
}
@Override
public boolean equals(Object o) {
return delegate.equals(o);
}
public V get(Object key) {
return delegate.get(key);
}
@Override
public int hashCode() {
return delegate.hashCode();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public Set<K> keySet() {
return delegate.keySet();
}
public V put(K key, V value) {
throw new UnsupportedOperationException("Attempt to mutate immutable map");
}
public void putAll(Map m) {
throw new UnsupportedOperationException("Attempt to mutate immutable map");
}
public V remove(Object key) {
throw new UnsupportedOperationException("Attempt to mutate immutable map");
}
public int size() {
return delegate.size();
}
public Collection<V> values() {
return delegate.values();
}
@Override
public String toString() {
return delegate.toString();
}
}