/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.chain2.impl;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.chain2.ChainUtil;
import org.apache.commons.chain2.Context;

/**
 * Convenience base class for {@link Context} implementations.
 *
 * @version $Id$
 * @param <K> the type of keys maintained by the context associated with this context
 * @param <V> the type of mapped values
 *
 * @since 2.0
 */
public class ContextMap<K, V> extends ConcurrentHashMap<K, V> implements Context<K, V> {

    /** serialVersionUID */
    private static final long serialVersionUID = 20120724L;

    /**
     * Creates a new, empty Context with a default initial capacity,
     * load factor, and concurrencyLevel.
     */
    public ContextMap() {
        super();
    }

    /**
     * Creates a new, empty Context with the specified initial capacity,
     * and with default load factor and concurrencyLevel
     *
     * @param initialCapacity the initial capacity.
     */
    public ContextMap(final int initialCapacity) {
        super(initialCapacity);
    }

    /**
     * Creates a new, empty Context with the specified initial capacity,
     * load factor, and concurrency level.
     *
     * @param initialCapacity the initial capacity.
     * @param loadFactor the load factor threshold, used to control resizing.
     * @param concurrencyLevel the estimated number of concurrently updating threads.
     */
    public ContextMap(final int initialCapacity,
            final float loadFactor, final int concurrencyLevel) {
        super(initialCapacity, loadFactor, concurrencyLevel);
    }

    /**
     * Creates a new Context with the same mappings as the given map.
     *
     * @param t Map whose key-value pairs are added
     */
    public ContextMap(final Map<? extends K, ? extends V> t) {
        super(t);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <T extends V> T retrieve(final K key) {
        V valueObject = get(key);
        // will throw ClassCastException if type are not assignable anyway
        return ChainUtil.cast(valueObject);
    }

}
