org.fujion.common.RegistryMap Maven / Gradle / Ivy
/*
* #%L
* fujion
* %%
* Copyright (C) 2018 Fujion Framework
* %%
* 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.
*
* #L%
*/
package org.fujion.common;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Wraps a map, providing the ability to control how duplicate keys are handled.
*
* @param The class of the indexing key.
* @param The class of the stored item.
*/
public class RegistryMap implements Map {
/**
* Possible actions to take when attempting to store a duplicate key.
*/
public enum DuplicateAction {
/**
* Replace existing key value (default).
*/
REPLACE,
/**
* Ignore attempt to replace existing key value.
*/
IGNORE,
/**
* Throw exception on duplicate key.
*/
ERROR
}
private final Map map;
private final DuplicateAction duplicateAction;
/**
* Defaults to concurrent hash map and replaceable keys.
*/
public RegistryMap() {
this(null, null);
}
/**
* Wraps the specified map, allowing replaceable keys.
*
* @param map Map to be wrapped. If null, a concurrent hash map is created and used.
*/
public RegistryMap(Map map) {
this(map, null);
}
/**
* Uses concurrent hash map.
*
* @param duplicateAction Behavior on attempt to replace existing key.
*/
public RegistryMap(DuplicateAction duplicateAction) {
this(null, duplicateAction);
}
/**
* @param map Map to be wrapped. If null, a concurrent hash map is created and used.
* @param duplicateAction Behavior on attempt to replace existing key.
*/
public RegistryMap(Map map, DuplicateAction duplicateAction) {
this.duplicateAction = duplicateAction == null ? DuplicateAction.REPLACE : duplicateAction;
this.map = map == null ? new ConcurrentHashMap<>() : map;
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return map.containsValue(value);
}
@Override
public VALUE get(Object key) {
return map.get(key);
}
@Override
public VALUE put(KEY key, VALUE value) {
VALUE oldValue = null;
if (key != null) {
oldValue = map.get(key);
if (value == null) {
map.remove(key);
return oldValue;
}
if (oldValue == null) {
map.put(key, value);
} else {
switch (duplicateAction) {
case IGNORE:
break;
case REPLACE:
map.put(key, value);
break;
case ERROR:
if (!oldValue.equals(value)) {
throw new IllegalArgumentException("Cannot modify existing entry with the key '" + key + "'.");
}
break;
}
}
}
return oldValue;
}
@Override
public VALUE remove(Object key) {
return map.remove(key);
}
@Override
public void putAll(Map extends KEY, ? extends VALUE> m) {
for (Entry extends KEY, ? extends VALUE> entry : m.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
@Override
public void clear() {
map.clear();
}
@Override
public Set keySet() {
return Collections.unmodifiableSet(map.keySet());
}
@Override
public Collection values() {
return Collections.unmodifiableCollection(map.values());
}
@Override
public Set> entrySet() {
return Collections.unmodifiableSet(map.entrySet());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy