Created
December 17, 2020 02:34
-
-
Save stbischof/943a8ed64470a385d8224313289568ad to your computer and use it in GitHub Desktop.
ServiceReferenceAsDictionary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) OSGi Alliance (2018, 2020). All Rights Reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.osgi.test.common.dictionary; | |
import static java.util.Objects.requireNonNull; | |
import java.util.AbstractMap; | |
import java.util.AbstractSet; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Dictionary; | |
import java.util.Enumeration; | |
import java.util.Iterator; | |
import java.util.LinkedHashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Objects; | |
import java.util.Set; | |
import java.util.function.Supplier; | |
import java.util.stream.Collector; | |
import java.util.stream.Collectors; | |
import org.osgi.framework.ServiceReference; | |
import org.osgi.test.common.stream.MapStream; | |
public class Dictionaries { | |
private Dictionaries() {} | |
/** | |
* Return a Map wrapper around a Dictionary. | |
* | |
* @param <K> The type of the key. | |
* @param <V> The type of the value. | |
* @param dictionary The dictionary to wrap. | |
* @return A Map object which wraps the specified dictionary. If the | |
* specified dictionary can be cast to a Map, then the specified | |
* dictionary is returned. | |
*/ | |
public static <K, V> Map<K, V> asMap(Dictionary<? extends K, ? extends V> dictionary) { | |
if (dictionary instanceof Map) { | |
@SuppressWarnings("unchecked") | |
Map<K, V> coerced = (Map<K, V>) dictionary; | |
return coerced; | |
} | |
return new DictionaryAsMap<>(dictionary); | |
} | |
private static class DictionaryAsMap<K, V> extends AbstractMap<K, V> { | |
private final Dictionary<K, V> dict; | |
@SuppressWarnings("unchecked") | |
DictionaryAsMap(Dictionary<? extends K, ? extends V> dict) { | |
this.dict = (Dictionary<K, V>) requireNonNull(dict); | |
} | |
Iterator<K> keys() { | |
List<K> keys = new ArrayList<>(dict.size()); | |
for (Enumeration<K> e = dict.keys(); e.hasMoreElements();) { | |
keys.add(e.nextElement()); | |
} | |
return keys.iterator(); | |
} | |
@Override | |
public int size() { | |
return dict.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return dict.isEmpty(); | |
} | |
@Override | |
public boolean containsKey(Object key) { | |
if (key == null) { | |
return false; | |
} | |
return dict.get(key) != null; | |
} | |
@Override | |
public V get(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return dict.get(key); | |
} | |
@Override | |
public V put(K key, V value) { | |
return dict.put(requireNonNull(key, "a Dictionary cannot contain a null key"), | |
requireNonNull(value, "a Dictionary cannot contain a null value")); | |
} | |
@Override | |
public V remove(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return dict.remove(key); | |
} | |
@Override | |
public void clear() { | |
for (Iterator<K> iter = keys(); iter.hasNext();) { | |
dict.remove(iter.next()); | |
} | |
} | |
@Override | |
public Set<K> keySet() { | |
return new KeySet(); | |
} | |
@Override | |
public Set<Map.Entry<K, V>> entrySet() { | |
return new EntrySet(); | |
} | |
@Override | |
public String toString() { | |
return dict.toString(); | |
} | |
final class KeySet extends AbstractSet<K> { | |
@Override | |
public Iterator<K> iterator() { | |
return new KeyIterator(); | |
} | |
@Override | |
public int size() { | |
return DictionaryAsMap.this.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return DictionaryAsMap.this.isEmpty(); | |
} | |
@Override | |
public boolean contains(Object key) { | |
return DictionaryAsMap.this.containsKey(key); | |
} | |
@Override | |
public boolean remove(Object key) { | |
return DictionaryAsMap.this.remove(key) != null; | |
} | |
@Override | |
public void clear() { | |
DictionaryAsMap.this.clear(); | |
} | |
} | |
final class KeyIterator implements Iterator<K> { | |
private final Iterator<K> keys = DictionaryAsMap.this.keys(); | |
private K key = null; | |
@Override | |
public boolean hasNext() { | |
return keys.hasNext(); | |
} | |
@Override | |
public K next() { | |
return key = keys.next(); | |
} | |
@Override | |
public void remove() { | |
if (key == null) { | |
throw new IllegalStateException(); | |
} | |
DictionaryAsMap.this.remove(key); | |
key = null; | |
} | |
} | |
final class EntrySet extends AbstractSet<Map.Entry<K, V>> { | |
@Override | |
public Iterator<Map.Entry<K, V>> iterator() { | |
return new EntryIterator(); | |
} | |
@Override | |
public int size() { | |
return DictionaryAsMap.this.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return DictionaryAsMap.this.isEmpty(); | |
} | |
@Override | |
public boolean contains(Object o) { | |
if (o instanceof Map.Entry) { | |
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; | |
return containsEntry(e); | |
} | |
return false; | |
} | |
private boolean containsEntry(Map.Entry<?, ?> e) { | |
Object key = e.getKey(); | |
if (key == null) { | |
return false; | |
} | |
Object value = e.getValue(); | |
if (value == null) { | |
return false; | |
} | |
return Objects.equals(DictionaryAsMap.this.get(key), value); | |
} | |
@Override | |
public boolean remove(Object o) { | |
if (o instanceof Map.Entry) { | |
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; | |
if (containsEntry(e)) { | |
DictionaryAsMap.this.remove(e.getKey()); | |
return true; | |
} | |
} | |
return false; | |
} | |
@Override | |
public void clear() { | |
DictionaryAsMap.this.clear(); | |
} | |
} | |
final class EntryIterator implements Iterator<Map.Entry<K, V>> { | |
private final Iterator<K> keys = DictionaryAsMap.this.keys(); | |
private K key = null; | |
@Override | |
public boolean hasNext() { | |
return keys.hasNext(); | |
} | |
@Override | |
public Map.Entry<K, V> next() { | |
return new Entry(key = keys.next()); | |
} | |
@Override | |
public void remove() { | |
if (key == null) { | |
throw new IllegalStateException(); | |
} | |
DictionaryAsMap.this.remove(key); | |
key = null; | |
} | |
} | |
final class Entry extends SimpleEntry<K, V> { | |
private static final long serialVersionUID = 1L; | |
Entry(K key) { | |
super(key, DictionaryAsMap.this.get(key)); | |
} | |
@Override | |
public V setValue(V value) { | |
DictionaryAsMap.this.put(getKey(), value); | |
return super.setValue(value); | |
} | |
} | |
} | |
/** | |
* Return a Dictionary wrapper around a Map. | |
* | |
* @param <K> The type of the key. | |
* @param <V> The type of the value. | |
* @param map The map to wrap. | |
* @return A Dictionary object which wraps the specified map. If the | |
* specified map can be cast to a Dictionary, then the specified map | |
* is returned. | |
*/ | |
public static <K, V> Dictionary<K, V> asDictionary(Map<? extends K, ? extends V> map) { | |
if (map instanceof Dictionary) { | |
@SuppressWarnings("unchecked") | |
Dictionary<K, V> coerced = (Dictionary<K, V>) map; | |
return coerced; | |
} | |
return new MapAsDictionary<>(map); | |
} | |
private static class MapAsDictionary<K, V> extends Dictionary<K, V> implements Map<K, V> { | |
private final Map<K, V> map; | |
@SuppressWarnings("unchecked") | |
MapAsDictionary(Map<? extends K, ? extends V> map) { | |
this.map = (Map<K, V>) requireNonNull(map); | |
boolean nullKey; | |
try { | |
nullKey = map.containsKey(null); | |
} catch (NullPointerException e) { | |
nullKey = false; // map does not allow null key | |
} | |
if (nullKey) { | |
throw new NullPointerException("a Dictionary cannot contain a null key"); | |
} | |
boolean nullValue; | |
try { | |
nullValue = map.containsValue(null); | |
} catch (NullPointerException e) { | |
nullValue = false; // map does not allow null value | |
} | |
if (nullValue) { | |
throw new NullPointerException("a Dictionary cannot contain a null value"); | |
} | |
} | |
@Override | |
public boolean containsKey(Object key) { | |
return map.containsKey(key); | |
} | |
@Override | |
public boolean containsValue(Object value) { | |
return map.containsValue(value); | |
} | |
@Override | |
public void putAll(Map<? extends K, ? extends V> m) { | |
MapStream.of(m) | |
.forEachOrdered(this::put); | |
} | |
@Override | |
public void clear() { | |
map.clear(); | |
} | |
@Override | |
public Set<K> keySet() { | |
return map.keySet(); | |
} | |
@Override | |
public Collection<V> values() { | |
return map.values(); | |
} | |
@Override | |
public Set<Entry<K, V>> entrySet() { | |
return map.entrySet(); | |
} | |
@Override | |
public int size() { | |
return map.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return map.isEmpty(); | |
} | |
@Override | |
public Enumeration<K> keys() { | |
return Collections.enumeration(map.keySet()); | |
} | |
@Override | |
public Enumeration<V> elements() { | |
return Collections.enumeration(map.values()); | |
} | |
@Override | |
public V get(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return map.get(key); | |
} | |
@Override | |
public V put(K key, V value) { | |
return map.put(requireNonNull(key, "a Dictionary cannot contain a null key"), | |
requireNonNull(value, "a Dictionary cannot contain a null value")); | |
} | |
@Override | |
public V remove(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return map.remove(key); | |
} | |
@Override | |
public String toString() { | |
return map.toString(); | |
} | |
} | |
public static <K, V> Dictionary<K, V> dictionaryOf() { | |
return new MapAsDictionary<>(Collections.emptyMap()); | |
} | |
public static <K, V> Dictionary<K, V> dictionaryOf(K k1, V v1) { | |
return MapStream.of(k1, v1) | |
.collect(toDictionary()); | |
} | |
public static <K, V> Dictionary<K, V> dictionaryOf(K k1, V v1, K k2, V v2) { | |
return MapStream.of(k1, v1, k2, v2) | |
.collect(toDictionary()); | |
} | |
public static <K, V> Dictionary<K, V> dictionaryOf(K k1, V v1, K k2, V v2, K k3, V v3) { | |
return MapStream.of(k1, v1, k2, v2, k3, v3) | |
.collect(toDictionary()); | |
} | |
public static <K, V> Dictionary<K, V> dictionaryOf(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { | |
return MapStream.of(k1, v1, k2, v2, k3, v3, k4, v4) | |
.collect(toDictionary()); | |
} | |
private static class ServiceReferenceAsDictionary extends Dictionary<String, Object> { | |
private final ServiceReference<?> serviceReference; | |
@SuppressWarnings("unchecked") | |
ServiceReferenceAsDictionary(ServiceReference<?> serviceReference) { | |
this.serviceReference = requireNonNull(serviceReference); | |
boolean nullKey = keysInternal().contains(null); | |
if (nullKey) { | |
throw new NullPointerException("a Dictionary cannot contain a null key"); | |
} | |
boolean nullValue = false; | |
for (String key : keysInternal()) { | |
if (Objects.isNull(serviceReference.getProperty(key))) { | |
nullValue = true; | |
break; | |
} | |
} | |
if (nullValue) { | |
throw new NullPointerException("a Dictionary cannot contain a null value"); | |
} | |
} | |
private List<String> keysInternal() { | |
String[] keys = serviceReference.getPropertyKeys(); | |
return Objects.isNull(keys) ? Collections.EMPTY_LIST : Arrays.asList(keys); | |
} | |
@Override | |
public int size() { | |
return keysInternal().size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return keysInternal().isEmpty(); | |
} | |
@Override | |
public Enumeration<String> keys() { | |
return Collections.enumeration(keysInternal()); | |
} | |
@Override | |
public Enumeration<Object> elements() { | |
List<Object> values = new ArrayList<>(); | |
for (String key : keysInternal()) { | |
values.add(serviceReference.getProperty(key)); | |
} | |
return Collections.enumeration(values); | |
} | |
@Override | |
public Object get(Object key) { | |
if (key instanceof String || key == null) { | |
return serviceReference.getProperty((String) key); | |
} | |
throw new IllegalArgumentException(); | |
} | |
@Override | |
public Object put(String key, Object value) { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public Object remove(Object key) { | |
throw new UnsupportedOperationException(); | |
} | |
} | |
public static <K, V> Dictionary<String, Object> asDictionary(ServiceReference<?> serviceReference) { | |
return new ServiceReferenceAsDictionary(serviceReference); | |
} | |
private static <K, V> Collector<? super Map.Entry<? extends K, ? extends V>, ?, Dictionary<K, V>> toDictionary() { | |
return Collectors.collectingAndThen(MapStream.toMap((u, v) -> { | |
throw new IllegalArgumentException("duplicate keys"); | |
}, (Supplier<Map<K, V>>) LinkedHashMap::new), map -> new MapAsDictionary<>(Collections.unmodifiableMap(map))); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.osgi.test.common.dictionary; | |
import static org.assertj.core.api.Assertions.assertThat; | |
import static org.assertj.core.api.Assertions.assertThatCode; | |
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | |
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; | |
import static org.assertj.core.api.Assertions.assertThatIllegalStateException; | |
import static org.assertj.core.api.Assertions.assertThatNullPointerException; | |
import static org.assertj.core.api.Assertions.assertThatThrownBy; | |
import static org.mockito.Mockito.mock; | |
import static org.mockito.Mockito.when; | |
import java.util.AbstractMap.SimpleEntry; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.Dictionary; | |
import java.util.Enumeration; | |
import java.util.HashMap; | |
import java.util.Hashtable; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.NoSuchElementException; | |
import java.util.Set; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.util.function.Supplier; | |
import org.junit.jupiter.api.BeforeEach; | |
import org.junit.jupiter.api.Test; | |
import org.osgi.framework.ServiceReference; | |
public class DictionariesTestCase { | |
Dictionary<String, String> dict; | |
Dictionary<String, String> asDictionary; | |
Dictionary<String, Object> asDictionarySr; | |
Map<String, String> map; | |
Map<String, String> asMap; | |
Hashtable<String, String> hashtable; | |
ServiceReference<?> sr; | |
Map<String, String> asMapEmpty; | |
Dictionary<String, String> asDictionaryEmpty; | |
List<String> srKeys; | |
List<String> srValues; | |
@BeforeEach | |
public void setUp() throws Exception { | |
dict = new TestDictionary<>(); | |
dict.put("key1", "value1"); | |
dict.put("key2", "value2"); | |
dict.put("key3", "value3"); | |
dict.put("key4", "value4"); | |
dict.put("key5", "value5"); | |
map = new HashMap<>(); | |
map.put("key1", "value1"); | |
map.put("key2", "value2"); | |
map.put("key3", "value3"); | |
map.put("key4", "value4"); | |
map.put("key5", "value5"); | |
sr = mock(ServiceReference.class); | |
srKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); | |
srValues = Arrays.asList("value1", "value2", "value3", "value4", "value5"); | |
when(sr.getPropertyKeys()).thenReturn(map.keySet() | |
.stream() | |
.toArray(String[]::new)); | |
for (Entry<String, String> entry : map.entrySet()) { | |
when(sr.getProperty(entry.getKey())).thenReturn(entry.getValue()); | |
} | |
hashtable = new Hashtable<>(map); | |
asMap = Dictionaries.asMap(dict); | |
asDictionary = Dictionaries.asDictionary(map); | |
asDictionarySr = Dictionaries.asDictionary(sr); | |
asMapEmpty = Dictionaries.asMap(new TestDictionary<>()); | |
asDictionaryEmpty = Dictionaries.asDictionary(new HashMap<>()); | |
} | |
@Test | |
public void not_same_as() { | |
assertThat(asDictionary).isNotSameAs(map); | |
assertThat(asMap).isNotSameAs(dict); | |
assertThat(asDictionarySr).isNotSameAs(sr); | |
} | |
@Test | |
public void same_as() { | |
assertThat(Dictionaries.asDictionary(hashtable)).isSameAs(hashtable); | |
assertThat(Dictionaries.asMap(hashtable)).isSameAs(hashtable); | |
} | |
@Test | |
public void keys() { | |
assertThat(asMap.keySet() | |
.isEmpty()).isEqualTo(dict.isEmpty()); | |
assertThat(asMap.keySet() | |
.size()).isEqualTo(dict.size()); | |
assertThat(asMap.keySet()).containsExactlyInAnyOrderElementsOf(Collections.list(dict.keys())); | |
assertThat(Collections.list(asDictionary.keys())).hasSize(map.size()) | |
.containsExactlyInAnyOrderElementsOf(map.keySet()); | |
assertThat(Collections.list(asDictionarySr.keys())).hasSize(map.size()) | |
.containsExactlyInAnyOrderElementsOf(map.keySet()); | |
} | |
@Test | |
public void values() { | |
assertThat(asMap.values() | |
.isEmpty()).isEqualTo(dict.isEmpty()); | |
assertThat(asMap.values() | |
.size()).isEqualTo(dict.size()); | |
assertThat(asMap.values()).containsExactlyInAnyOrderElementsOf(Collections.list(dict.elements())); | |
assertThat(Collections.list(asDictionary.elements())).hasSize(map.size()) | |
.containsExactlyInAnyOrderElementsOf(map.values()); | |
assertThat(Collections.list(asDictionarySr.elements())).hasSize(map.size()) | |
.containsExactlyInAnyOrderElementsOf(map.values()); | |
} | |
@Test | |
public void empty() { | |
assertThat(asMap.isEmpty()).isEqualTo(dict.isEmpty()); | |
assertThat(asMapEmpty.isEmpty()).isTrue(); | |
assertThat(asDictionary.isEmpty()).isEqualTo(map.isEmpty()); | |
assertThat(asDictionarySr.isEmpty()).isEqualTo(map.isEmpty()); | |
assertThat(asDictionaryEmpty.isEmpty()).isTrue(); | |
} | |
@Test | |
public void size() { | |
assertThat(asMap.size()).isEqualTo(dict.size()); | |
assertThat(asMapEmpty.size()).isZero(); | |
assertThat(asDictionary.size()).isEqualTo(map.size()); | |
assertThat(asDictionarySr.size()).isEqualTo(map.size()); | |
assertThat(asDictionaryEmpty.size()).isZero(); | |
} | |
@Test | |
public void get() { | |
assertThat(asMap.get("foo")).isNull(); | |
assertThat(asMapEmpty.get("foo")).isNull(); | |
for (String key : Collections.list(dict.keys())) { | |
assertThat(asMap.get(key)).isSameAs(dict.get(key)); | |
} | |
assertThat(asDictionary.get("foo")).isNull(); | |
assertThat(asDictionarySr.get("foo")).isNull(); | |
assertThat(asDictionaryEmpty.get("foo")).isNull(); | |
for (String key : map.keySet()) { | |
assertThat(asDictionary.get(key)).isSameAs(map.get(key)); | |
assertThat(asDictionarySr.get(key)).isSameAs(map.get(key)); | |
} | |
} | |
@Test | |
public void put() { | |
int size = dict.size(); | |
String value = dict.get("key1"); | |
assertThat(asMap.put("key1", "value11")).isSameAs(value); | |
assertThat(asMap.get("key1")).isSameAs(dict.get("key1")) | |
.isEqualTo("value11"); | |
assertThat(asMap.size()).isEqualTo(dict.size()) | |
.isEqualTo(size); | |
assertThat(asMap.put("key6", "value6")).isNull(); | |
assertThat(asMap.get("key6")).isSameAs(dict.get("key6")) | |
.isEqualTo("value6"); | |
assertThat(asMap.size()).isEqualTo(dict.size()) | |
.isEqualTo(size + 1); | |
size = map.size(); | |
value = map.get("key1"); | |
assertThat(asDictionary.put("key1", "value11")).isSameAs(value); | |
assertThat(asDictionary.get("key1")).isSameAs(map.get("key1")) | |
.isEqualTo("value11"); | |
assertThat(asDictionary.size()).isEqualTo(map.size()) | |
.isEqualTo(size); | |
assertThat(asDictionary.put("key6", "value6")).isNull(); | |
assertThat(asDictionary.get("key6")).isSameAs(map.get("key6")) | |
.isEqualTo("value6"); | |
assertThat(asDictionary.size()).isEqualTo(map.size()) | |
.isEqualTo(size + 1); | |
assertThatThrownBy(() -> { | |
asDictionarySr.put("key6", "value6"); | |
}).isInstanceOf(UnsupportedOperationException.class); | |
} | |
@Test | |
public void remove() { | |
assertThat(asMap.remove("foo")).isNull(); | |
assertThat(asMapEmpty.remove("foo")).isNull(); | |
for (String key : Collections.list(dict.keys())) { | |
String value = dict.get(key); | |
assertThat(asMap.remove(key)).isEqualTo(value); | |
assertThat(asMap.containsKey(key)).isFalse(); | |
assertThat(asMap.size()).isEqualTo(dict.size()); | |
assertThat(dict.get(key)).isNull(); | |
} | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asDictionary.remove("foo")).isNull(); | |
assertThat(asDictionaryEmpty.remove("foo")).isNull(); | |
for (String key : new ArrayList<>(map.keySet())) { | |
String value = map.get(key); | |
assertThat(asDictionary.remove(key)).isEqualTo(value); | |
assertThat(asDictionary.get(key)).isNull(); | |
assertThat(asDictionary.size()).isEqualTo(map.size()); | |
assertThat(map.containsKey(key)).isFalse(); | |
} | |
assertThat(asDictionary.isEmpty()).isTrue(); | |
assertThat(asDictionary.size()).isZero(); | |
assertThatThrownBy(() -> { | |
asDictionarySr.remove("key1"); | |
}).isInstanceOf(UnsupportedOperationException.class); | |
} | |
@Test | |
public void null_checks() { | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.asMap(null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.asDictionary((Map<?, ?>) null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.asDictionary((ServiceReference<?>) null); | |
}); | |
Map<String, String> nullKeyMap = new HashMap<>(); | |
nullKeyMap.put(null, "value"); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.asDictionary(nullKeyMap); | |
}); | |
Map<String, String> nullValueMap = new HashMap<>(); | |
nullValueMap.put("key", null); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.asDictionary(nullValueMap); | |
}); | |
assertThat(asMap.containsKey(null)).isFalse(); | |
assertThat(asMap.get(null)).isNull(); | |
assertThat(asMap.remove(null)).isNull(); | |
assertThat(asDictionary.get(null)).isNull(); | |
assertThat(asDictionary.remove(null)).isNull(); | |
assertThat(asDictionarySr.get(null)).isNull(); | |
assertThatNullPointerException().isThrownBy(() -> { | |
asMap.put(null, "value1"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
asMap.put("key1", null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
asDictionary.put(null, "value1"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
asDictionary.put("key1", null); | |
}); | |
Entry<String, String> nullKeyEntry = new SimpleEntry<>(null, "value"); | |
assertThat(asMap.entrySet() | |
.contains(nullKeyEntry)).isFalse(); | |
assertThat(asMap.entrySet() | |
.remove(nullKeyEntry)).isFalse(); | |
Entry<String, String> nullValueEntry = new SimpleEntry<>("key", null); | |
assertThat(asMap.entrySet() | |
.contains(nullValueEntry)).isFalse(); | |
assertThat(asMap.entrySet() | |
.remove(nullValueEntry)).isFalse(); | |
Entry<String, String> entry = asMap.entrySet() | |
.iterator() | |
.next(); | |
assertThatNullPointerException().isThrownBy(() -> { | |
entry.setValue(null); | |
}); | |
} | |
@Test | |
public void no_null_key_or_value_map() { | |
Map<String, String> noNullKeyValueMap = new ConcurrentHashMap<>(); | |
assertThatNullPointerException().isThrownBy(() -> { | |
noNullKeyValueMap.containsKey(null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
noNullKeyValueMap.containsValue(null); | |
}); | |
assertThatCode(() -> { | |
Dictionaries.asDictionary(noNullKeyValueMap); | |
}).doesNotThrowAnyException(); | |
} | |
@Test | |
public void containsKey() { | |
Object o = Integer.valueOf(1); | |
assertThat(asMap.containsKey(o)).isFalse(); | |
assertThat(asMap.containsKey("foo")).isFalse(); | |
for (String key : Collections.list(dict.keys())) { | |
assertThat(asMap.containsKey(key)).isTrue(); | |
} | |
} | |
@Test | |
public void containsValue() { | |
Object o = Integer.valueOf(1); | |
assertThat(asMap.containsValue(o)).isFalse(); | |
assertThat(asMap.containsValue("foo")).isFalse(); | |
for (String value : Collections.list(dict.elements())) { | |
assertThat(asMap.containsValue(value)).isTrue(); | |
} | |
} | |
@Test | |
public void clear() { | |
asMap.clear(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(dict.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void entrySet() { | |
assertThat(asMap.entrySet() | |
.isEmpty()).isEqualTo(dict.isEmpty()); | |
assertThat(asMap.entrySet() | |
.size()).isEqualTo(dict.size()); | |
assertThat(asMap.entrySet()).allMatch(entry -> dict.get(entry.getKey()) == entry.getValue()); | |
assertThat(asMap.entrySet()).extracting(Entry::getKey) | |
.containsExactlyInAnyOrderElementsOf(Collections.list(dict.keys())); | |
assertThat(asMap.entrySet()).extracting(Entry::getValue) | |
.containsExactlyInAnyOrderElementsOf(Collections.list(dict.elements())); | |
} | |
@Test | |
public void entrySet_contains() { | |
Set<Entry<String, String>> entrySet = asMap.entrySet(); | |
Object o = "foo"; | |
assertThat(entrySet.contains(o)).isFalse(); | |
assertThat(entrySet.contains(new SimpleEntry<>("key", "value"))).isFalse(); | |
for (String key : Collections.list(dict.keys())) { | |
String value = dict.get(key); | |
Entry<String, String> entry = new SimpleEntry<>(key, value); | |
assertThat(entrySet.contains(entry)).isTrue(); | |
} | |
} | |
@Test | |
public void entrySet_remove() { | |
Set<Entry<String, String>> entrySet = asMap.entrySet(); | |
Object o = "foo"; | |
assertThat(entrySet.remove(o)).isFalse(); | |
assertThat(entrySet.remove(new SimpleEntry<>("key", "value"))).isFalse(); | |
for (String key : Collections.list(dict.keys())) { | |
String value = dict.get(key); | |
Entry<String, String> entry = new SimpleEntry<>(key, value); | |
assertThat(entrySet.remove(entry)).isTrue(); | |
assertThat(entrySet.contains(entry)).isFalse(); | |
assertThat(dict.get(key)).isNull(); | |
} | |
assertThat(entrySet.size()).isZero(); | |
assertThat(entrySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void entrySet_clear() { | |
Set<Entry<String, String>> entrySet = asMap.entrySet(); | |
entrySet.clear(); | |
assertThat(entrySet.size()).isZero(); | |
assertThat(entrySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void entrySet_iterator() { | |
Set<Entry<String, String>> entrySet = asMap.entrySet(); | |
Iterator<Entry<String, String>> iterator = entrySet.iterator(); | |
while (iterator.hasNext()) { | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
Entry<String, String> next = iterator.next(); | |
assertThat(dict.get(next.getKey())).isSameAs(next.getValue()); | |
iterator.remove(); | |
assertThat(dict.get(next.getKey())).isNull(); | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
} | |
assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(() -> { | |
iterator.next(); | |
}); | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
assertThat(entrySet.size()).isZero(); | |
assertThat(entrySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void entrySet_setValue() { | |
Set<Entry<String, String>> entrySet = asMap.entrySet(); | |
for (Entry<String, String> entry : entrySet) { | |
String key = entry.getKey(); | |
String value = entry.getValue(); | |
assertThat(value).isSameAs(dict.get(key)); | |
String newValue = value + key; | |
entry.setValue(newValue); | |
assertThat(entry.getValue()).isSameAs(newValue) | |
.isSameAs(dict.get(key)); | |
} | |
} | |
@Test | |
public void keySet_contains() { | |
Set<String> keySet = asMap.keySet(); | |
Object o = Integer.valueOf(1); | |
assertThat(keySet.contains(o)).isFalse(); | |
assertThat(keySet.contains("foo")).isFalse(); | |
for (String key : Collections.list(dict.keys())) { | |
assertThat(keySet.contains(key)).isTrue(); | |
} | |
} | |
@Test | |
public void keySet_remove() { | |
Set<String> keySet = asMap.keySet(); | |
Object o = Integer.valueOf(1); | |
assertThat(keySet.remove(o)).isFalse(); | |
assertThat(keySet.remove("foo")).isFalse(); | |
for (String key : Collections.list(dict.keys())) { | |
assertThat(keySet.remove(key)).isTrue(); | |
assertThat(keySet.contains(key)).isFalse(); | |
assertThat(dict.get(key)).isNull(); | |
} | |
assertThat(keySet.size()).isZero(); | |
assertThat(keySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void keySet_clear() { | |
Set<String> keySet = asMap.keySet(); | |
keySet.clear(); | |
assertThat(keySet.size()).isZero(); | |
assertThat(keySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void keySet_iterator() { | |
Set<String> keySet = asMap.keySet(); | |
Iterator<String> iterator = keySet.iterator(); | |
while (iterator.hasNext()) { | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
String next = iterator.next(); | |
assertThat(dict.get(next)).isNotNull(); | |
iterator.remove(); | |
assertThat(dict.get(next)).isNull(); | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
} | |
assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(() -> { | |
iterator.next(); | |
}); | |
assertThatIllegalStateException().isThrownBy(() -> { | |
iterator.remove(); | |
}); | |
assertThat(keySet.size()).isZero(); | |
assertThat(keySet.isEmpty()).isTrue(); | |
assertThat(asMap.size()).isZero(); | |
assertThat(asMap.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
assertThat(dict.isEmpty()).isTrue(); | |
} | |
@Test | |
public void dictionaryOf_exceptions() { | |
Supplier<Dictionary<String, String>> supplier = () -> Dictionaries.dictionaryOf("key1", "value1"); | |
assertThat(supplier.get()).isNotNull(); | |
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> { | |
supplier.get() | |
.remove("key1"); | |
}); | |
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> { | |
supplier.get() | |
.put("key2", "value2"); | |
}); | |
assertThatIllegalArgumentException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key1", "value2"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf(null, "value1"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", null, "value2"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key2", null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", null, "value3"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", "key3", null); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", "key3", "value3", null, "value4"); | |
}); | |
assertThatNullPointerException().isThrownBy(() -> { | |
Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", "key3", "value3", "key4", null); | |
}); | |
} | |
@Test | |
public void dictionaryOf_empty() { | |
Dictionary<String, String> dict = Dictionaries.dictionaryOf(); | |
assertThat(dict).isNotNull() | |
.isInstanceOf(Map.class); | |
assertThat(dict.isEmpty()).isTrue(); | |
assertThat(dict.size()).isZero(); | |
} | |
@Test | |
public void dictionaryOf_1() { | |
Dictionary<String, String> dict = Dictionaries.dictionaryOf("key1", "value1"); | |
assertThat(dict).isNotNull() | |
.isInstanceOf(Map.class); | |
assertThat(dict.isEmpty()).isFalse(); | |
assertThat(dict.size()).isEqualTo(1); | |
assertThat(dict.get("key1")).isEqualTo("value1"); | |
assertThat(Collections.list(dict.keys())).hasSize(1) | |
.containsExactly("key1"); | |
assertThat(Collections.list(dict.elements())).hasSize(1) | |
.containsExactly("value1"); | |
} | |
@Test | |
public void dictionaryOf_2() { | |
Dictionary<String, String> dict = Dictionaries.dictionaryOf("key1", "value1", "key2", "value2"); | |
assertThat(dict).isNotNull() | |
.isInstanceOf(Map.class); | |
assertThat(dict.isEmpty()).isFalse(); | |
assertThat(dict.size()).isEqualTo(2); | |
assertThat(dict.get("key1")).isEqualTo("value1"); | |
assertThat(dict.get("key2")).isEqualTo("value2"); | |
assertThat(Collections.list(dict.keys())).hasSize(2) | |
.containsExactly("key1", "key2"); | |
assertThat(Collections.list(dict.elements())).hasSize(2) | |
.containsExactly("value1", "value2"); | |
} | |
@Test | |
public void dictionaryOf_3() { | |
Dictionary<String, String> dict = Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", "key3", | |
"value3"); | |
assertThat(dict).isNotNull() | |
.isInstanceOf(Map.class); | |
assertThat(dict.isEmpty()).isFalse(); | |
assertThat(dict.size()).isEqualTo(3); | |
assertThat(dict.get("key1")).isEqualTo("value1"); | |
assertThat(dict.get("key2")).isEqualTo("value2"); | |
assertThat(dict.get("key3")).isEqualTo("value3"); | |
assertThat(Collections.list(dict.keys())).hasSize(3) | |
.containsExactly("key1", "key2", "key3"); | |
assertThat(Collections.list(dict.elements())).hasSize(3) | |
.containsExactly("value1", "value2", "value3"); | |
} | |
@Test | |
public void dictionaryOf_4() { | |
Dictionary<String, String> dict = Dictionaries.dictionaryOf("key1", "value1", "key2", "value2", "key3", | |
"value3", "key4", "value4"); | |
assertThat(dict).isNotNull() | |
.isInstanceOf(Map.class); | |
assertThat(dict.isEmpty()).isFalse(); | |
assertThat(dict.size()).isEqualTo(4); | |
assertThat(dict.get("key1")).isEqualTo("value1"); | |
assertThat(dict.get("key2")).isEqualTo("value2"); | |
assertThat(dict.get("key3")).isEqualTo("value3"); | |
assertThat(dict.get("key4")).isEqualTo("value4"); | |
assertThat(Collections.list(dict.keys())).hasSize(4) | |
.containsExactly("key1", "key2", "key3", "key4"); | |
assertThat(Collections.list(dict.elements())).hasSize(4) | |
.containsExactly("value1", "value2", "value3", "value4"); | |
} | |
public static class TestDictionary<K, V> extends Dictionary<K, V> { | |
private final Map<K, V> map; | |
public TestDictionary() { | |
this.map = new HashMap<>(); | |
} | |
@Override | |
public int size() { | |
return map.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return map.isEmpty(); | |
} | |
@Override | |
public Enumeration<K> keys() { | |
return Collections.enumeration(map.keySet()); | |
} | |
@Override | |
public Enumeration<V> elements() { | |
return Collections.enumeration(map.values()); | |
} | |
@Override | |
public V get(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return map.get(key); | |
} | |
@Override | |
public V put(K key, V value) { | |
if ((key == null) || (value == null)) { | |
throw new NullPointerException(); | |
} | |
return map.put(key, value); | |
} | |
@Override | |
public V remove(Object key) { | |
if (key == null) { | |
return null; | |
} | |
return map.remove(key); | |
} | |
@Override | |
public String toString() { | |
return map.toString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment