001/* $Id: RuleSetCache.java 992080 2010-09-02 19:46:29Z simonetripodi $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.commons.digester.annotations.internal;
019
020import java.io.Serializable;
021import java.util.LinkedHashMap;
022import java.util.Map;
023
024import org.apache.commons.digester.annotations.FromAnnotationsRuleSet;
025
026/**
027 * Simple in-memory LRU cache implementation.
028 *
029 * @since 2.1
030 */
031public final class RuleSetCache implements Serializable {
032
033    /**
034     * This class serialVersionUID.
035     */
036    private static final long serialVersionUID = 1L;
037
038    /**
039     * The fixed cache size.
040     */
041    private final int cacheSize = 255;
042
043    /**
044     * The fixed cache load facor.
045     */
046    private final float loadFactor = 0.75f;
047
048    /**
049     * The fixed cache capacity.
050     */
051    private final int capacity = (int) Math.ceil(this.cacheSize / this.loadFactor) + 1;
052
053    /**
054     * The map that implements the LRU cache.
055     */
056    private final Map<Class<?>, FromAnnotationsRuleSet> data =
057        new LinkedHashMap<Class<?>, FromAnnotationsRuleSet>(capacity, loadFactor) {
058
059        /**
060         * This class serialVersionUID.
061         */
062        private static final long serialVersionUID = 1L;
063
064        /**
065         * {@inheritDoc}
066         */
067        @Override
068        protected boolean removeEldestEntry(Map.Entry<Class<?>, FromAnnotationsRuleSet> eldest) {
069            return size() > cacheSize;
070        }
071    };
072
073    /**
074     * Returns true if this cache contains a mapping for the specified key.
075     *
076     * @param key key whose presence in this map is to be tested.
077     * @return true if this map contains a mapping for the specified key, false
078     *         otherwise.
079     */
080    public boolean containsKey(Class<?> key) {
081        checkKey(key);
082        return this.data.containsKey(key);
083    }
084
085    /**
086     * Returns the value to which the specified key is cached, or null if this
087     * cache contains no mapping for the key.
088     *
089     * Key parameter must not be null.
090     *
091     * @param key the key has to be checked it is present, it must not be null.
092     * @return the value to which the specified key is cached, null if this
093     *         cache contains no mapping for the key.
094     */
095    public FromAnnotationsRuleSet get(Class<?> key) {
096        checkKey(key);
097        return this.data.get(key);
098    }
099
100    /**
101     * Associates the specified value with the specified key in this cache.
102     *
103     * Key parameter must not be null.
104     *
105     * @param key key with which the specified value is to be associated.
106     * @param value value to be associated with the specified key.
107     */
108    public void put(Class<?> key, FromAnnotationsRuleSet value) {
109        checkKey(key);
110        this.data.put(key, value);
111    }
112
113    /**
114     * Verify that a key is not null.
115     *
116     * @param <T> the generic key type.
117     * @param key the key object.
118     */
119    private static void checkKey(Class<?> key) {
120        if (key == null) {
121            throw new IllegalArgumentException("null keys not supported");
122        }
123    }
124
125}