/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/urm/org/apache/slide/urm/utils/validatorcache/URMValidatorFifoCache.java,v 1.4 2005/03/02 10:53:36 eckehard Exp $
 * $Revision: 1.4 $
 * $Date: 2005/03/02 10:53:36 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.apache.slide.urm.utils.validatorcache;
import java.util.LinkedList;
import java.util.HashMap;

/**
 * @author eckehard.hermann@softwareag.com
 * @author dieter.kessler@softwareag.com
 * @author zsolt.sasvarie@softwareag.com
 */

public class URMValidatorFifoCache
{
    private int size = 1000;
    private int elemNumber = 0;
    private LinkedList list = null;
    private HashMap map = null;
    
    /**
     * Creates a new cache with the default size (1000)
     *
     *
     */
    public URMValidatorFifoCache() {
        list = new LinkedList();
        map = new HashMap();
    }
    
    /**
     * Creates a new cache with the passed size
     *
     * @param    size      cache size
     *
     */
    public URMValidatorFifoCache(int size) {
        this.size = size;
        list = new LinkedList();
        map = new HashMap();
    }
    
    /**
     * Returns the cache size
     *
     * @return   an int
     *
     */
    public synchronized int getSize() {
        return size;
    }
    
    /**
     * Redefines the cache size. If the size is reduced, the first inserted
     * elments are deleted
     *
     * @param    size                an int
     *
     */
    public synchronized void setSize(int size){
        this.size = size;
    }
    
    /**
     * Adds a new Elment to the cache
     *
     * @param    key                 an Object
     * @param    value               an Object
     *
     */
    public synchronized void add(Object key, Object value) {
        if (list.contains(key)) remove(key);

        if (elemNumber == size) {
            map.remove(list.removeFirst());
            map.put(key, value);
            list.addLast(key);
        } else {
            map.put(key, value);
            list.addLast(key);
            elemNumber++;
        }
    }
    
    /**
     * Removes all elements from the cache
     *
     * @return   a boolean, if successful
     *
     */
    public synchronized boolean clear(){
        list.clear();
        map.clear();
        elemNumber = 0;
        return true;
    }
    
    /**
     * Returns the searched element without removing it from the cache
     *
     * @param    key  of the searched elment
     *
     * @return   value of the element if found, null else
     *
     */
    public synchronized Object get(Object key){
        boolean contained = list.remove(key);
        if (contained) {
            list.addLast(key);
            return map.get(key);
        } else return null;
    }

    /**
     * Removes the first element from the cache
     *
     * @return   value of removed element
     *
     */
    public synchronized Object removeFirst(){
        elemNumber--;
        return  map.remove(list.removeFirst());
    }
    
    /**
     * Removes the element from the cache
     *
     * @param    key  of the elment that should be removed
     *
     * @return   value of removed element
     *
     */
    public synchronized Object remove(Object key){
        elemNumber--;
        list.remove(key);
        return  map.remove(key);
    }
    
    /**
     * returns 'true' if the cache contains the element
     *
     * @return 'true' if the cache contains the element
     */
    public synchronized boolean contains(Object key){
        return list.contains(key);
    }
    
    
}

