package com.revolsys.beans; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; public class ClassRegistry<T> { /** The cache for super class matches. */ private final Map<Class<?>, T> findCache = new WeakHashMap<>(); /** The registry of classes to values. */ private final Map<Class<?>, T> registry = new HashMap<>(); /** * Clear the cache used by the {@link ClassRegistry#find(Class)} method. */ private void clearFindCache() { this.findCache.clear(); } /** * Find the value by class. If no direct match was found, a match for the * super class will be found until a match is found. Returns null if no match * was found on any super class. * * @param clazz The class. * @return The class if a match was found for this class or one of the super * classes or null if no match was found. */ public T find(final Class<?> clazz) { T value = this.findCache.get(clazz); if (value == null) { value = findDo(clazz); if (value == null) { for (final Class<?> interfaceClass : Classes.getInterfaces(clazz)) { value = find(interfaceClass); if (value != null) { return value; } } } if (value != null) { this.findCache.put(clazz, value); } } return value; } public T find(final Object object) { if (object == null) { return null; } else { final Class<?> clazz = object.getClass(); return find(clazz); } } protected T findDo(final Class<?> clazz) { if (clazz == null) { return null; } else { T value = get(clazz); if (value == null) { value = this.findCache.get(clazz); if (value == null) { final Class<?> superClass = clazz.getSuperclass(); value = find(superClass); if (value != null) { this.findCache.put(clazz, value); } } } return value; } } /** * Get the value from the registry using the key. Returns null if an exact * match by class is not found. * * @param clazz The class. * @return The value, or null if no value has been registered for this class. */ public T get(final Class<?> clazz) { return this.registry.get(clazz); } /** * Register the value for the specified class. * * @param clazz The class. * @param value The value. */ public void put(final Class<?> clazz, final T value) { if (get(clazz) != value) { this.registry.put(clazz, value); clearFindCache(); } } }