/*
 * 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 get(clazz) does not only look to see if clazz is a key in the Map, but also walks the up superclass and interface graph of 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:


ClassMap<String> m = new ClassMap<String>();
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)
Type parameters:
  • <T> – the type of the value in this map
Deprecated:there is no replacement for this class
/** * <p>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.</p> * * <p>This is a very useful class for Class based registries.</p> * * <p>Example:</p> * <pre>{@code * ClassMap<String> m = new ClassMap<String>(); * m.put(Animal.class, "Animal"); * m.put(Fox.class, "Fox"); * m.get(Fox.class) --> "Fox" * m.get(Dog.class) --> "Animal" * } </pre> * * (assuming Dog.class &lt; Animal.class) * * @param <T> the type of the value in this map * @deprecated there is no replacement for this class */
@Deprecated public class ClassMap<T> {
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.
Params:
  • clazz – the class to get the ancestors for
Type parameters:
  • <T> – the type of the class modeled by this Class object.
Returns:a list of all the super classes of clazz, starting with the class, and ending with java.lang.Object.
/** * 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 <T> 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 <T> List<Class<?>> getAncestry(final Class<T> clazz) { return ClassAncestry.getAncestry(clazz); } private final class ComputeFunction implements Function<Class<?>, 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<Class<?>, T> map = CopyOnWriteMap.newHashMap(); private final Map<Class<?>, 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.
Params:
  • key – a Class to get the value for
Returns:the value for either this class or its nearest superclass
/** * 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 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.
Params:
  • key – a Class key
  • value – the value for this class
See Also:
Returns:the previous value associated with key, or null if there was no mapping for 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 java.util.Map, removes the mapping for a key from this map if it is present
Params:
  • key – a Class key
See Also:
Returns:the previous value associated with key, or null if there was no mapping for key.
/** * 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 java.util.Map, removes all of the mappings from this map (optional operation).
See Also:
/** * 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 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.
See Also:
Returns:the size of this map
/** * 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 java.util.Map, returns true if this map contains no key-value mappings.
See Also:
Returns:true if there are no values in the map
/** * 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(); } }