package com.webobjects.foundation; import java.util.Collection; import java.util.Dictionary; import java.util.Map; /** * <div class="en"> * NSMutableDictionary reimplementation to support JDK 1.5 templates and the * proper collection methods. Use with * </div> * * <div class="ja"> * JDK 1.5 テンプレートをサポートする為の再実装。 * 使用は * </div> * * <pre>{@code * NSMutableDictionary<String, String> env = new NSMutableDictionary<>(System.getenv(), true); * * for (String key : env) * logger.debug(env.valueForKey(key)); * }</pre> * * @param <K> * type of key contents * @param <V> * type of value contents */ @SuppressWarnings("unchecked") public class NSMutableDictionary<K, V> extends NSDictionary<K, V> { static final long serialVersionUID = 6690723083816355576L; //TODO iterator.remove() throws unimplemented public NSMutableDictionary() { } public NSMutableDictionary(int capacity) { this(); if (capacity < 0) { throw new IllegalArgumentException(getClass().getName() + ": Capacity cannot be less than 0"); } _ensureCapacity(capacity); } public NSMutableDictionary(V object, K key) { super(object, key); } public NSMutableDictionary(V[] objects, K[] keys) { super(objects, keys); } public NSMutableDictionary(NSArray<? extends V> objects, NSArray<? extends K> keys) { super(objects, keys); } public NSMutableDictionary(NSDictionary<? extends K, ? extends V> otherDictionary) { _copyMutableDictionary(otherDictionary); } public NSMutableDictionary(Dictionary<? extends K, ? extends V> dictionary, boolean ignoreNull) { super(dictionary, ignoreNull); } public NSMutableDictionary(Map<? extends K, ? extends V> map) { super(map); } public NSMutableDictionary(Map<? extends K, ? extends V> map, boolean ignoreNull) { super(map, ignoreNull); } public void setObjectForKey(V object, K key) { if (object == null) { throw new IllegalArgumentException("Attempt to insert null object into an " + getClass().getName() + "."); } if (key == null) { throw new IllegalArgumentException("Attempt to insert null key into an " + getClass().getName() + "."); } int capacity = _capacity; int count = _count; if (++count > capacity) { _ensureCapacity(count); } if (_NSCollectionPrimitives.addValueInHashTable(key, object, _keys, _objects, _flags)) { _count = count; _keysCache = null; _keySetCache = null; } _entrySetCache = null; _objectsCache = null; } public V removeObjectForKey(Object key) { Object result = null; if (key == null) { throw new IllegalArgumentException("Attempt to remove null key from an " + getClass().getName() + "."); } if (_count != 0) { result = _NSCollectionPrimitives.removeValueInHashTable(key, _keys, _objects, _flags); if (result != null) { _count--; _deletionLimit--; if (_count == 0 || _deletionLimit == 0) { _clearDeletionsAndCollisions(); } _objectsCache = null; _entrySetCache = null; _keysCache = null; _keySetCache = null; } } return (V) result; } public void removeAllObjects() { if (_count != 0) { _objects = new Object[_hashtableBuckets]; _keys = new Object[_hashtableBuckets]; _flags = new byte[_hashtableBuckets]; _count = 0; _objectsCache = null; _entrySetCache = null; _keysCache = null; _keySetCache = null; _deletionLimit = _NSCollectionPrimitives.deletionLimitForTableBuckets(_hashtableBuckets); } } public void setDictionary(NSDictionary<? extends K, ? extends V> otherDictionary) { if (otherDictionary != this) { removeAllObjects(); if (otherDictionary != null) { addEntriesFromDictionary(otherDictionary); } } } public void addEntriesFromDictionary(NSDictionary<? extends K, ? extends V> otherDictionary) { if (otherDictionary != null) { Object[] keys = otherDictionary.keysNoCopy(); for (int i = 0; i < keys.length; i++) { setObjectForKey(otherDictionary.objectForKey(keys[i]), (K)keys[i]); } } } public void removeObjectsForKeys(NSArray<? extends K> keys) { if (keys != null) { Object[] keysArray = keys.objectsNoCopy(); for (int i = 0; i < keysArray.length; i++) { removeObjectForKey(keysArray[i]); } } } @Override public void takeValueForKey(Object value, String key) { if (value != null) { setObjectForKey((V) value, (K) key); } else { removeObjectForKey(key); } } @Override public Object clone() { return new NSMutableDictionary<K, V>(this); } @Override public NSDictionary<K, V> immutableClone() { return new NSDictionary<K, V>(this); } @Override public NSMutableDictionary<K, V> mutableClone() { return (NSMutableDictionary<K, V>) clone(); } public static final Class _CLASS = _NSUtilitiesExtra._classWithFullySpecifiedNamePrime("com.webobjects.foundation.NSMutableDictionary"); /** * Associate the <tt>value</tt> with <tt>key</tt> in this map. If the * map previously contained a mapping for <tt>key</tt>, the old value * will be replaced by <tt>value</tt>. * * @param key * key to associate value with * @param value * vaue to be associated with key * * @return previous value associated with specified key, or null if there * was no mapping for key. */ @Override public V put(K key, V value) { V temp = objectForKey(key); setObjectForKey(value, key); return temp; } /** * Remove mapping for <tt>key</tt> from this map if it is present. * * @param key * key whose mapping is to be removed from the map. * * @return previous value associated with key, or null if there was no * mapping for key. */ @Override public V remove(Object key) { V temp = objectForKey(key); removeObjectForKey(key); return temp; } /** * Copy all mappings from <tt>m</tt> to this map. * * @param m * Mappings to be stored in this map. */ @Override public void putAll(Map<? extends K, ? extends V> m) { addEntriesFromDictionary(new NSDictionary(m, IgnoreNull)); } /** * Remove all mappings from this map. */ @Override public void clear() { removeAllObjects(); } /** * Return a collection view of the values contained in this map. */ @Override public Collection<V> values() { return allValues(); } }