org.bson.util.ClassMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mongo-java-driver Show documentation
Show all versions of mongo-java-driver Show documentation
The MongoDB Java Driver uber-artifact, containing mongodb-driver, mongodb-driver-core, and bson
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.bson.util;
import java.util.List;
import java.util.Map;
/**
* Maps Class objects to values. A ClassMap is different from a regular Map in that {@code get(clazz)} does not only look to see if
* {@code clazz} is a key in the Map, but also walks the up superclass and interface graph of {@code clazz} to find matches. Derived matches
* of this sort are then cached in the registry so that matches are faster on future gets.
*
* This is a very useful class for Class based registries.
*
* Example:
* {@code
* ClassMap m = new ClassMap();
* m.put(Animal.class, "Animal");
* m.put(Fox.class, "Fox");
* m.get(Fox.class) --> "Fox"
* m.get(Dog.class) --> "Animal"
* }
*
* (assuming Dog.class < Animal.class)
*
* @param the type of the value in this map
* @deprecated there is no replacement for this class
*/
@Deprecated
public class ClassMap {
/**
* Helper method that walks superclass and interface graph, superclasses first, then interfaces, to compute an ancestry list. Super
* types are visited left to right. Duplicates are removed such that no Class will appear in the list before one of its subtypes.
*
* @param clazz the class to get the ancestors for
* @param the type of the class modeled by this {@code Class} object.
* @return a list of all the super classes of {@code clazz}, starting with the class, and ending with {@code java.lang.Object}.
*/
public static List> getAncestry(final Class clazz) {
return ClassAncestry.getAncestry(clazz);
}
private final class ComputeFunction implements Function, T> {
@Override
public T apply(final Class> a) {
for (final Class> cls : getAncestry(a)) {
T result = map.get(cls);
if (result != null) {
return result;
}
}
return null;
}
}
private final Map, T> map = CopyOnWriteMap.newHashMap();
private final Map, T> cache = ComputingMap.create(new ComputeFunction());
/**
* Gets the value associated with either this Class or a superclass of this class. If fetching for a super class, it fetches the value
* for the closest superclass. Returns null if the given class and none of its superclasses are in the map.
*
* @param key a {@code Class} to get the value for
* @return the value for either this class or its nearest superclass
*/
public T get(final Object key) {
return cache.get(key);
}
/**
* As per {@code java.util.Map}, associates the specified value with the specified key in this map. If the map previously contained a
* mapping for the key, the old value is replaced by the specified value.
*
* @param key a {@code Class} key
* @param value the value for this class
* @return the previous value associated with {@code key}, or null if there was no mapping for key.
* @see java.util.Map#put(Object, Object)
*/
public T put(final Class> key, final T value) {
try {
return map.put(key, value);
} finally {
cache.clear();
}
}
/**
* As per {@code java.util.Map}, removes the mapping for a key from this map if it is present
*
* @param key a {@code Class} key
* @return the previous value associated with {@code key}, or null if there was no mapping for key.
* @see java.util.Map#remove(Object)
*/
public T remove(final Object key) {
try {
return map.remove(key);
} finally {
cache.clear();
}
}
/**
* As per {@code java.util.Map}, removes all of the mappings from this map (optional operation).
*
* @see java.util.Map#clear()
*/
public void clear() {
map.clear();
cache.clear();
}
/**
* As per {@code java.util.Map}, returns the number of key-value mappings in this map. This will only return the number of keys
* explicitly added to the map, not any cached hierarchy keys.
*
* @return the size of this map
* @see java.util.Map#size()
*/
public int size() {
return map.size();
}
/**
* As per {@code java.util.Map}, returns {@code true} if this map contains no key-value mappings.
*
* @return true if there are no values in the map
* @see java.util.Map#isEmpty()
*/
public boolean isEmpty() {
return map.isEmpty();
}
}