All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bson.util.ClassMap Maven / Gradle / Ivy

Go to download

The MongoDB Java Driver uber-artifact, containing the legacy driver, the mongodb-driver, mongodb-driver-core, and bson

There is a newer version: 3.12.14
Show newest version
/*
 * 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 */ 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(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy