001/*
002 *  Copyright 2012 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.core.util;
017
018import java.util.HashMap;
019import java.util.Map;
020import java.util.Timer;
021import java.util.TimerTask;
022
023import org.apache.avalon.framework.activity.Disposable;
024import org.apache.avalon.framework.activity.Initializable;
025
026import org.ametys.runtime.plugin.component.AbstractLogEnabled;
027
028/**
029 * Simple memory cache with a thread clearing the cache every day.
030 * @param <K> the type of keys for caching objects by this component.
031 * @param <V> the type of objects cached by this component.
032 */
033public class CachingComponent<K, V> extends AbstractLogEnabled implements Initializable, Disposable
034{
035    private Map<K, V> _objects = new HashMap<>();
036    private Timer _timer;
037    
038    public void initialize() throws Exception
039    {
040        if (isCacheEnabled())
041        {
042            _timer = new Timer("CachingComponent", true);
043            
044            long period = 1000 * 60 * 60 * 24; // one day
045            _timer.scheduleAtFixedRate(new TimerTask()
046            {
047                @Override
048                public void run()
049                {
050                    clearCache();
051                }
052            }, period, period);
053        }
054    }
055    
056    public void dispose()
057    {
058        if (_timer != null)
059        {
060            _timer.cancel();
061        }
062    }
063    
064    /**
065     * Returns an object from the cache, correspondong to the specified key, or null if none.
066     * @param key the object's key.
067     * @return the object from cache.
068     */
069    protected V getObjectFromCache(K key)
070    {
071        V object = _objects.get(key);
072        
073        getLogger().debug("Getting object {} from cache for key {}", object, key);
074        
075        return object;
076    }
077    
078    /**
079     * Adds a key/object pair in the cache.
080     * @param key the object's key.
081     * @param object the object to be cached.
082     */
083    protected void addObjectInCache(K key, V object)
084    {
085        getLogger().debug("Adding object {} in cache for key {}", object, key);
086        
087        _objects.put(key, object);
088    }
089    
090    /**
091     * Removes a key/object pair in the cache.
092     * @param key the object's key.
093     */
094    protected void removeObjectFromCache(K key)
095    {
096        getLogger().debug("Removing object in cache for key {}", key);
097        
098        _objects.remove(key);
099    }
100    
101    /**
102     * Removes all entries from the cache.
103     */
104    protected void clearCache()
105    {
106        getLogger().debug("Clearing cache");
107        
108        _objects.clear();
109    }
110    
111    /**
112     * Returns true if the cache is enabled.
113     * @return true if the cache is enabled.
114     */
115    protected boolean isCacheEnabled()
116    {
117        return true;
118    }
119}