/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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 com.queplix.core.utils.cache;

import java.util.Collection;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * <p>Tree cache</p>
 *
 * @author [ALB] Baranov Andrey
 * @version 1.0
 */

public class TreeCache
        extends AbstractCache {

    // Map to store cached data.
    private SortedMap map;

    //
    // Constructor.
    //

    public TreeCache() {
        map = new TreeMap();
    }

    /*
     * No javadoc
     * @see Cache#get
     */
    public Object get(Object key) {
        if(map.isEmpty()) {
            return null;
        }
        return map.get(key);
    }

    /*
     * No javadoc
     * @see Cache#headMap
     */
    public SortedMap headMap(Comparable toKey) {
        if(map.isEmpty()) {
            return null;
        }
        SortedMap ret = map.headMap(toKey);
        if(ret.isEmpty()) {
            return null;
        } else {
            return new TreeMap(ret);
        }
    }

    /*
     * No javadoc
     * @see Cache#subMap
     */
    public SortedMap subMap(Comparable fromKey, Comparable toKey) {
        if(map.isEmpty()) {
            return null;
        }
        SortedMap ret = map.subMap(fromKey, toKey);
        if(ret.isEmpty()) {
            return null;
        } else {
            return new TreeMap(ret);
        }
    }

    /*
     * No javadoc
     * @see Cache#tailMap
     */
    public SortedMap tailMap(Comparable fromKey) {
        if(map.isEmpty()) {
            return null;
        }
        SortedMap ret = map.tailMap(fromKey);
        if(ret.isEmpty()) {
            return null;
        } else {
            return new TreeMap(ret);
        }
    }

    /*
     * No javadoc
     * @see Cache#toMap
     */
    public SortedMap toMap() {
        if(map.isEmpty()) {
            return null;
        }
        return new TreeMap(map);
    }

    /*
     * No javadoc
     * @see Cache#containsKey
     */
    public boolean containsKey(Object key) {
        if(map.isEmpty()) {
            return false;
        }
        return map.containsKey(key);
    }

    /*
     * No javadoc
     * @see Cache#keys
     */
    public Collection keys() {
        if(map.isEmpty()) {
            return null;
        }
        return map.keySet();
    }

    /*
     * No javadoc
     * @see Cache#getLastKey
     */
    public Object getLastKey() {
        if(map.isEmpty()) {
            return null;
        }
        return map.lastKey();
    }

    /*
     * No javadoc
     * @see Cache#getFirstKey
     */
    public Object getFirstKey() {
        if(map.isEmpty()) {
            return null;
        }
        return map.firstKey();
    }

    /*
     * No javadoc
     * @see Cache#values
     */
    public Collection values() {
        if(map.isEmpty()) {
            return null;
        }
        return map.values();
    }

    /*
     * No javadoc
     * @see Cache#put(Object, Object)
     */
    public void put(Object key, Object o) {
        if(!isOpen()) {
            throw new IllegalStateException("Cache closed");
        }
        map.put(key, o);
    }

    /*
     * No javadoc
     * @see Cache#put(Map)
     */
    public void put(Map _map) {
        if(!isOpen()) {
            throw new IllegalStateException("Cache closed");
        }
        map.putAll(_map);
    }

    /*
     * No javadoc
     * @see Cache#remove
     */
    public void remove(Object key) {
        if(!isOpen()) {
            throw new IllegalStateException("Cache closed");
        }
        if(!map.isEmpty()) {
            map.remove(key);
        }
    }

    /*
     * No javadoc
     * @see Cache#clear
     */
    public void clear() {
        super.clear();
        if(!map.isEmpty()) {
            map.clear();
        }
    }

    /*
     * No javadoc
     * @see Cache#isEmpty
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

    // Get string.
    public String toString() {
        return "TreeCache: keys= " + keys() + "; open=" + isOpen();
    }
}
