/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.concurrent;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
import com.liferay.portal.kernel.util.SetUtil;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.junit.After;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
/**
* @author Shuyang Zhou
*/
public class ConcurrentMapperHashMapTest {
@ClassRule
public static final CodeCoverageAssertor codeCoverageAssertor =
CodeCoverageAssertor.INSTANCE;
@After
public void tearDown() {
_eventQueue.clear();
}
@Test
public void testClear() {
Assert.assertTrue(_concurrentMap.isEmpty());
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertFalse(_concurrentMap.isEmpty());
_concurrentMap.clear();
Assert.assertTrue(_concurrentMap.isEmpty());
}
@Test
public void testContainsKey() {
try {
_concurrentMap.containsKey(null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
Assert.assertFalse(_concurrentMap.containsKey(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertTrue(_concurrentMap.containsKey(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
}
@Test
public void testContainsValue() {
try {
_concurrentMap.containsValue(null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Value is null", npe.getMessage());
}
Assert.assertFalse(_concurrentMap.containsValue(_testValue));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertTrue(_concurrentMap.containsValue(_testValue));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
}
@Test
public void testEntrySet() {
Set<Map.Entry<Key, Value>> entrySet = _concurrentMap.entrySet();
Assert.assertSame(entrySet, _concurrentMap.entrySet());
Assert.assertTrue(entrySet.isEmpty());
Assert.assertFalse(entrySet.contains(new Object()));
Assert.assertFalse(entrySet.remove(new Object()));
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertEquals(entrySet.toString(), 1, entrySet.size());
Assert.assertTrue(
entrySet.contains(
new SimpleEntry<Key, Value>(_testKey, _testValue)));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertFalse(
entrySet.contains(
new SimpleEntry<Key, Value>(_testKey, new Value(""))));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertFalse(
entrySet.remove(
new SimpleEntry<Key, Value>(_testKey, new Value(""))));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY);
Assert.assertTrue(
entrySet.remove(new SimpleEntry<Key, Value>(_testKey, _testValue)));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY,
Event.UNMAP_VALUE);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Iterator<Map.Entry<Key, Value>> iterator = entrySet.iterator();
Assert.assertTrue(iterator.hasNext());
Map.Entry<Key, Value> entry = iterator.next();
Assert.assertEquals(entry, entry);
Assert.assertNotEquals(entry, new Object());
Assert.assertNotEquals(
entry, new SimpleEntry<Key, Value>(new Key("someKey"), _testValue));
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Assert.assertNotEquals(
entry, new SimpleEntry<Key, Value>(_testKey, new Value("")));
_assertEventQueue(
Event.UNMAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertEquals(
entry, new SimpleEntry<Key, Value>(_testKey, _testValue));
_assertEventQueue(
Event.UNMAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertEquals(
_testKey.hashCode() ^ _testValue.hashCode(), entry.hashCode());
Assert.assertFalse(iterator.hasNext());
Assert.assertSame(_testKey, entry.getKey());
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Assert.assertSame(_testValue, entry.getValue());
_assertEventQueue(Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertTrue(entrySet.contains(entry));
_assertEventQueue(
Event.UNMAP_KEY_FOR_QUERY, Event.MAP_KEY_FOR_QUERY,
Event.UNMAP_VALUE_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
entry.setValue(_testValue2);
_assertEventQueue(
Event.UNMAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY,
Event.UNMAP_VALUE_FOR_QUERY, Event.MAP_KEY, Event.MAP_VALUE,
Event.UNMAP_KEY, Event.UNMAP_VALUE);
Assert.assertSame(_testValue2, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
iterator.remove();
Assert.assertTrue(entrySet.isEmpty());
Assert.assertFalse(entrySet.contains(entry));
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY, Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertEquals(entrySet.toString(), 1, entrySet.size());
entrySet.clear();
Assert.assertTrue(entrySet.isEmpty());
}
@Test
public void testGet() {
try {
_concurrentMap.get(null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
Assert.assertNull(_concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertSame(_testValue, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
}
@Test
public void testKeySet() {
Set<Key> keySet = _concurrentMap.keySet();
Assert.assertSame(keySet, _concurrentMap.keySet());
Assert.assertTrue(keySet.isEmpty());
Assert.assertFalse(keySet.contains(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertFalse(keySet.remove(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
String keySetString = keySet.toString();
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Assert.assertEquals(keySetString, 1, keySet.size());
Assert.assertTrue(keySet.contains(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertTrue(keySet.remove(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
keySetString = keySet.toString();
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Assert.assertEquals(keySetString, 1, keySet.size());
Assert.assertEquals(SetUtil.fromArray(new Key[] {_testKey}), keySet);
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Iterator<Key> iterator = keySet.iterator();
Assert.assertTrue(iterator.hasNext());
Key key = iterator.next();
_assertEventQueue(Event.UNMAP_KEY_FOR_QUERY);
Assert.assertEquals(_testKey, key);
Assert.assertFalse(iterator.hasNext());
Assert.assertTrue(keySet.contains(key));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
iterator.remove();
Assert.assertTrue(keySet.isEmpty());
Assert.assertFalse(keySet.contains(key));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertEquals(keySet.toString(), 1, keySet.size());
keySet.clear();
Assert.assertTrue(_concurrentMap.isEmpty());
}
@Test
public void testPut() {
try {
_concurrentMap.put(null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
try {
_concurrentMap.put(_testKey, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Value is null", npe.getMessage());
}
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertSame(_testValue, _concurrentMap.put(_testKey, _testValue));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE);
Assert.assertSame(
_testValue, _concurrentMap.put(_testKey, _testValue2));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE);
Assert.assertSame(
_testValue2, _concurrentMap.put(_testKey, _testValue2));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE);
Assert.assertSame(_testValue2, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
}
@Test
public void testPutAll() {
Map<Key, Value> map = createDataMap();
_concurrentMap.putAll(map);
Assert.assertEquals(map, _concurrentMap);
}
@Test
public void testPutIfAbsent() {
try {
_concurrentMap.putIfAbsent(null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
try {
_concurrentMap.putIfAbsent(_testKey, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Value is null", npe.getMessage());
}
Assert.assertNull(_concurrentMap.putIfAbsent(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertSame(
_testValue, _concurrentMap.putIfAbsent(_testKey, _testValue));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertSame(
_testValue, _concurrentMap.putIfAbsent(_testKey, _testValue2));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertSame(
_testValue, _concurrentMap.putIfAbsent(_testKey, _testValue2));
_assertEventQueue(
Event.MAP_KEY, Event.MAP_VALUE, Event.UNMAP_KEY, Event.UNMAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertSame(_testValue, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
}
@Test
public void testRemove() {
try {
_concurrentMap.remove(null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
Assert.assertNull(_concurrentMap.remove(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertSame(_testValue, _concurrentMap.remove(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE);
Assert.assertNull(_concurrentMap.remove(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
Assert.assertNull(_concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
}
@Test
public void testRemoveWithValue() {
try {
_concurrentMap.remove(null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
try {
_concurrentMap.remove(_testKey, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Value is null", npe.getMessage());
}
Assert.assertFalse(_concurrentMap.remove(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertFalse(_concurrentMap.remove(_testKey, new Value("")));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY);
Assert.assertTrue(_concurrentMap.remove(_testKey, _testValue));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY,
Event.UNMAP_VALUE);
Assert.assertFalse(_concurrentMap.remove(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY);
Assert.assertNull(_concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY);
}
@Test
public void testRemoveWithValueConcurrentModification() {
ConcurrentMap<Key, Value> concurrentMap =
new ConcurrentTypeReferenceHashMap(
new ConcurrentHashMap<KeyReference, ValueReference>() {
@Override
public ValueReference get(Object key) {
KeyReference keyReference = (KeyReference)key;
ValueReference valueReference = super.get(keyReference);
if (_testKey.equals(keyReference._key)) {
put(
new KeyReference(_testKey),
new ValueReference(_testValue2));
}
return valueReference;
}
});
Assert.assertNull(concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertFalse(concurrentMap.remove(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE_FOR_QUERY);
}
@Test
public void testReplace() {
try {
_concurrentMap.replace(null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
try {
_concurrentMap.replace(_testKey, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Value is null", npe.getMessage());
}
Assert.assertNull(_concurrentMap.replace(_testKey, _testValue));
_assertEventQueue(
Event.MAP_VALUE, Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertSame(
_testValue, _concurrentMap.replace(_testKey, _testValue2));
_assertEventQueue(
Event.MAP_VALUE, Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE);
Assert.assertSame(_testValue2, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
}
@Test
public void testReplaceWithValue() {
try {
_concurrentMap.replace(null, null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Key is null", npe.getMessage());
}
try {
_concurrentMap.replace(_testKey, null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Old value is null", npe.getMessage());
}
try {
_concurrentMap.replace(_testKey, _testValue, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("New value is null", npe.getMessage());
}
Assert.assertFalse(
_concurrentMap.replace(_testKey, _testValue, _testValue2));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE, Event.UNMAP_VALUE);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertTrue(
_concurrentMap.replace(_testKey, _testValue, _testValue2));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY, Event.UNMAP_VALUE);
Assert.assertSame(_testValue2, _concurrentMap.get(_testKey));
_assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertFalse(
_concurrentMap.replace(_testKey, _testValue, _testValue2));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY, Event.UNMAP_VALUE);
}
@Test
public void testReplaceWithValueConcurrentModification() {
ConcurrentMap<Key, Value> concurrentMap =
new ConcurrentTypeReferenceHashMap(
new ConcurrentHashMap<KeyReference, ValueReference>() {
@Override
public ValueReference get(Object key) {
KeyReference keyReference = (KeyReference)key;
ValueReference valueReference = super.get(keyReference);
if (_testKey.equals(keyReference._key)) {
put(
new KeyReference(_testKey),
new ValueReference(_testValue2));
}
return valueReference;
}
});
Assert.assertNull(concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertFalse(
concurrentMap.replace(_testKey, _testValue, _testValue2));
_assertEventQueue(
Event.MAP_KEY_FOR_QUERY, Event.MAP_VALUE,
Event.UNMAP_VALUE_FOR_QUERY, Event.UNMAP_VALUE);
}
@Test
public void testSerialization() throws Exception {
Map<Key, Value> map = createDataMap();
_concurrentMap.putAll(map);
UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
new UnsyncByteArrayOutputStream();
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(
unsyncByteArrayOutputStream)) {
objectOutputStream.writeObject(_concurrentMap);
}
ObjectInputStream objectInputStream = new ObjectInputStream(
new UnsyncByteArrayInputStream(
unsyncByteArrayOutputStream.unsafeGetByteArray(), 0,
unsyncByteArrayOutputStream.size()));
Assert.assertEquals(_concurrentMap, objectInputStream.readObject());
}
@Test
public void testValues() {
Collection<Value> values = _concurrentMap.values();
Assert.assertSame(values, _concurrentMap.values());
Assert.assertTrue(values.isEmpty());
Assert.assertFalse(values.contains(new Value("")));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
Assert.assertFalse(values.remove(new Value("")));
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
String valuesString = values.toString();
_assertEventQueue(Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertEquals(valuesString, 1, values.size());
Assert.assertTrue(values.contains(_testValue));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
Assert.assertFalse(values.contains(_testValue2));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
Assert.assertFalse(values.remove(_testValue2));
_assertEventQueue(Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertTrue(values.remove(_testValue));
_assertEventQueue(Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Iterator<Value> iterator = values.iterator();
Assert.assertTrue(iterator.hasNext());
Value value = iterator.next();
_assertEventQueue(Event.UNMAP_VALUE_FOR_QUERY);
Assert.assertSame(_testValue, value);
Assert.assertFalse(iterator.hasNext());
Assert.assertTrue(values.contains(value));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
iterator.remove();
Assert.assertTrue(values.isEmpty());
Assert.assertFalse(values.contains(value));
_assertEventQueue(Event.MAP_VALUE_FOR_QUERY);
Assert.assertNull(_concurrentMap.put(_testKey, _testValue));
_assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE);
Assert.assertEquals(values.toString(), 1, values.size());
values.clear();
Assert.assertTrue(_concurrentMap.isEmpty());
}
public static class Key implements Serializable {
public Key(String id) {
if (id == null) {
throw new NullPointerException("Id is null");
}
_id = id;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Key)) {
return false;
}
Key key = (Key)obj;
return _id.equals(key._id);
}
@Override
public int hashCode() {
return _id.hashCode();
}
private static final long serialVersionUID = 1L;
private final String _id;
}
public static class KeyReference implements Serializable {
public KeyReference(Key key) {
if (key == null) {
throw new NullPointerException("Type is null");
}
_key = key;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof KeyReference)) {
return false;
}
KeyReference keyReference = (KeyReference)obj;
return _key.equals(keyReference._key);
}
@Override
public int hashCode() {
return _key.hashCode();
}
private static final long serialVersionUID = 1L;
private final Key _key;
}
public static class Value implements Serializable {
public Value(String valueId) {
if (valueId == null) {
throw new NullPointerException("Value id is null");
}
_valueId = valueId;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Value)) {
return false;
}
Value value = (Value)obj;
return _valueId.equals(value._valueId);
}
@Override
public int hashCode() {
return _valueId.hashCode();
}
private static final long serialVersionUID = 1L;
private final String _valueId;
}
public static class ValueReference implements Serializable {
public ValueReference(Value value) {
if (value == null) {
throw new NullPointerException("Value is null");
}
_value = value;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ValueReference)) {
return false;
}
ValueReference valueReference = (ValueReference)obj;
return _value.equals(valueReference._value);
}
@Override
public int hashCode() {
return _value.hashCode();
}
private static final long serialVersionUID = 1L;
private final Value _value;
}
protected Map<Key, Value> createDataMap() {
Map<Key, Value> map = new HashMap<>();
map.put(_testKey, _testValue);
map.put(new Key("testKey2"), _testValue2);
map.put(new Key("testKey3"), new Value("testValue3"));
return map;
}
private void _assertEventQueue(Event... expectedEvents) {
Assert.assertArrayEquals(
_eventQueue.toString(), expectedEvents,
_eventQueue.toArray(new Event[_eventQueue.size()]));
_eventQueue.clear();
}
private static final Queue<Event> _eventQueue = new LinkedList<>();
private final ConcurrentMap<Key, Value> _concurrentMap =
new ConcurrentTypeReferenceHashMap();
private final Key _testKey = new Key("testKey");
private final Value _testValue = new Value("testValue");
private final Value _testValue2 = new Value("testValue2");
private static class ConcurrentTypeReferenceHashMap
extends
ConcurrentMapperHashMap<Key, KeyReference, Value, ValueReference> {
public ConcurrentTypeReferenceHashMap() {
super(new ConcurrentHashMap<KeyReference, ValueReference>());
}
public ConcurrentTypeReferenceHashMap(
ConcurrentMap<KeyReference, ValueReference> innerConcurrentMap) {
super(innerConcurrentMap);
}
@Override
public KeyReference mapKey(Key key) {
_eventQueue.offer(Event.MAP_KEY);
return new KeyReference(key);
}
@Override
public KeyReference mapKeyForQuery(Key key) {
_eventQueue.offer(Event.MAP_KEY_FOR_QUERY);
return new KeyReference(key);
}
@Override
public ValueReference mapValue(Key key, Value value) {
_eventQueue.offer(Event.MAP_VALUE);
return new ValueReference(value);
}
@Override
public ValueReference mapValueForQuery(Value value) {
_eventQueue.offer(Event.MAP_VALUE_FOR_QUERY);
return new ValueReference(value);
}
@Override
public Key unmapKey(KeyReference keyReference) {
_eventQueue.offer(Event.UNMAP_KEY);
return keyReference._key;
}
@Override
public Key unmapKeyForQuery(KeyReference keyReference) {
_eventQueue.offer(Event.UNMAP_KEY_FOR_QUERY);
return keyReference._key;
}
@Override
public Value unmapValue(ValueReference valueReference) {
_eventQueue.offer(Event.UNMAP_VALUE);
return valueReference._value;
}
@Override
public Value unmapValueForQuery(ValueReference valueReference) {
_eventQueue.offer(Event.UNMAP_VALUE_FOR_QUERY);
return valueReference._value;
}
}
private enum Event {
MAP_KEY, MAP_KEY_FOR_QUERY, MAP_VALUE, MAP_VALUE_FOR_QUERY, UNMAP_KEY,
UNMAP_KEY_FOR_QUERY, UNMAP_VALUE, UNMAP_VALUE_FOR_QUERY
}
}