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

com.threerings.util.DefaultMap Maven / Gradle / Ivy

//
// ooo-util - a place for OOO utilities
// Copyright (C) 2011 Three Rings Design, Inc., All Rights Reserved
// http://github.com/threerings/ooo-util/blob/master/LICENSE

package com.threerings.util;

import java.lang.reflect.Constructor;

import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.Maps;

/**
 * Provides a map implementation that automatically creates, and inserts into the map, a default
 * value for any value retrieved via the {@link #fetch} method which has no entry for that key.
 */
public class DefaultMap extends ForwardingMap
{
    /**
     * Creates a default map backed by a {@link HashMap} that creates instances of the supplied
     * class (using its no-args constructor) as defaults.
     */
    public static  DefaultMap newInstanceHashMap (Class clazz)
    {
        return newInstanceMap(Maps.newHashMap(), clazz);
    }

    /**
     * Creates a default map backed by the supplied map that creates instances of the supplied
     * class (using its no-args constructor) as defaults.
     */
    public static  DefaultMap newInstanceMap (Map delegate, Class clazz)
    {
        Function creator = newInstanceCreator(clazz);
        return newMap(delegate, creator);
    }

    /**
     * Returns a Function that makes instances of the supplied class (using its no-args
     * constructor) as default values.
     */
    public static  Function newInstanceCreator (Class clazz) {

        final Constructor ctor;
        try {
            ctor = clazz.getConstructor();
        } catch (NoSuchMethodException nsme) {
            throw new IllegalArgumentException(clazz + " must have a no-args constructor.");
        }
        return new Function() {
            public V apply (K key) {
                try {
                    return ctor.newInstance();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    /**
     * Creates a default map backed by a {@link HashMap} using the supplied default creator.
     */
    public static  DefaultMap newHashMap (Function creator)
    {
        return newMap(Maps.newHashMap(), creator);
    }

    /**
     * Creates a default map backed by the supplied map using the supplied default creator.
     */
    public static  DefaultMap newMap (Map delegate, Function creator)
    {
        return new DefaultMap(delegate, creator);
    }

    /**
     * Looks up the supplied key in the map, returning the value to which it is mapped. If the key
     * has no mapping, a default value will be obtained for the requested key and placed into the
     * map. The current and subsequent lookups will return that value.
     */
    public V fetch (K key)
    {
        V value = get(key);
        // null is a valid value, so we check containsKey() before creating a default
        if (value == null && !containsKey(key)) {
            put(key, value = _creator.apply(key));
        }
        return value;
    }

    /**
     * Creates a default map backed by the supplied map using the supplied default creator.
     */
    protected DefaultMap (Map delegate, Function creator)
    {
        _delegate = delegate;
        _creator = creator;
    }

    @Override // from ForwardingMap
    protected Map delegate()
    {
        return _delegate;
    }

    protected final Map _delegate;
    protected final Function _creator;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy