/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 net.formio.common.heterog;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/**
* Operations with heterogeneous collections.
* @author Radek Beran
*/
public final class HeterogCollections {
public static <K> HeterogMap<K> unmodifiableMap(HeterogMap<K> c) {
return new UnmodifiableHeterogeneousMap<K>(c);
}
public static <K> HeterogMap<K> synchronizedMap(HeterogMap<K> c) {
return new SynchronizedHeterogeneousMap<K>(c);
}
public static <K> HeterogMap<K> newMap() {
return new DefaultHeterogMap<K>(new HashMap<TypedKey<K, ?>, Object>());
}
public static <K> HeterogMap<K> newConcurrentMap() {
return new DefaultHeterogMap<K>(new ConcurrentHashMap<TypedKey<K, ?>, Object>());
}
public static <K> HeterogMap<K> newLinkedMap() {
return new DefaultHeterogMap<K>(new LinkedHashMap<TypedKey<K, ?>, Object>());
}
public static <K> HeterogMap<K> newUnmodifiableMap() {
return unmodifiableMap(new DefaultHeterogMap<K>(new HashMap<TypedKey<K, ?>, Object>()));
}
public static <K> HeterogMap<K> newSynchronizedMap() {
return synchronizedMap(new DefaultHeterogMap<K>(new HashMap<TypedKey<K, ?>, Object>()));
}
/**
* @serial include
*/
static class UnmodifiableHeterogeneousMap<K> implements HeterogMap<K>, Serializable {
private static final long serialVersionUID = 1820017752578914078L;
final HeterogMap<K> c;
UnmodifiableHeterogeneousMap(HeterogMap<K> c) {
if (c == null) throw new NullPointerException("source container cannot be null");
this.c = c;
}
@Override
public boolean equals(Object o) {return o == this || c.equals(o);}
@Override
public int hashCode() {return c.hashCode();}
@Override
public String toString() {return c.toString();}
@Override
public <T> T putTyped(TypedKey<K, T> key, T value) {
throw new UnsupportedOperationException();
}
@Override
public void putAllFromSource(HeterogMap<K> source) {
throw new UnsupportedOperationException();
}
@Override
public <T> T getTyped(TypedKey<K, T> key) {
return c.getTyped(key);
}
@Override
public <T> T removeTyped(TypedKey<K, T> key) {
throw new UnsupportedOperationException();
}
@Override
public Set<TypedKey<K, ?>> keySet() {
return c.keySet();
}
@Override
public int size() {
return c.size();
}
@Override
public boolean isEmpty() {
return c.isEmpty();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public <T> boolean containsKey(TypedKey<K, T> key) {
return c.containsKey(key);
}
@Override
public Collection<Object> values() {
return c.values();
}
@Override
public Set<Entry<TypedKey<K, ?>, Object>> entrySet() {
return c.entrySet();
}
@Override
public Map<K, Object> asMap() {
return c.asMap();
}
}
/**
* @serial include
*/
static class SynchronizedHeterogeneousMap<K> implements HeterogMap<K>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
private final HeterogMap<K> c; // backing Collection
private final Object mutex; // object on which to synchronize
SynchronizedHeterogeneousMap(HeterogMap<K> c) {
if (c == null) throw new NullPointerException("source container cannot be null");
this.c = c;
mutex = this;
}
SynchronizedHeterogeneousMap(HeterogMap<K> c, Object mutex) {
this.c = c;
this.mutex = mutex;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) { return c.equals(o); }
}
@Override
public int hashCode() {
synchronized (mutex) { return c.hashCode(); }
}
@Override
public String toString() {
synchronized (mutex) { return c.toString(); }
}
@Override
public <T> T putTyped(TypedKey<K, T> key, T value) {
synchronized (mutex) { return c.putTyped(key, value); }
}
@Override
public void putAllFromSource(HeterogMap<K> source) {
synchronized (mutex) { c.putAllFromSource(source); }
}
@Override
public <T> T getTyped(TypedKey<K, T> key) {
synchronized (mutex) { return c.getTyped(key); }
}
@Override
public <T> T removeTyped(TypedKey<K, T> key) {
synchronized (mutex) { return c.removeTyped(key); }
}
@Override
public Set<TypedKey<K, ?>> keySet() {
synchronized (mutex) { return c.keySet(); }
}
@Override
public int size() {
synchronized (mutex) { return c.size(); }
}
@Override
public boolean isEmpty() {
synchronized (mutex) { return c.isEmpty(); }
}
@Override
public void clear() {
synchronized (mutex) { c.clear(); }
}
@Override
public <T> boolean containsKey(TypedKey<K, T> key) {
synchronized (mutex) { return c.containsKey(key); }
}
@Override
public Collection<Object> values() {
synchronized (mutex) { return c.values(); }
}
@Override
public Set<Entry<TypedKey<K, ?>, Object>> entrySet() {
synchronized (mutex) { return c.entrySet(); }
}
@Override
public Map<K, Object> asMap() {
synchronized (mutex) { return c.asMap(); }
}
}
private HeterogCollections() {
throw new AssertionError("Not instantiable, use static members");
}
}