chris@1: /* chris@1: * SONEWS News Server chris@1: * see AUTHORS for the list of contributors chris@1: * chris@1: * This program is free software: you can redistribute it and/or modify chris@1: * it under the terms of the GNU General Public License as published by chris@1: * the Free Software Foundation, either version 3 of the License, or chris@1: * (at your option) any later version. chris@1: * chris@1: * This program is distributed in the hope that it will be useful, chris@1: * but WITHOUT ANY WARRANTY; without even the implied warranty of chris@1: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the chris@1: * GNU General Public License for more details. chris@1: * chris@1: * You should have received a copy of the GNU General Public License chris@1: * along with this program. If not, see . chris@1: */ chris@1: chris@1: package org.sonews.util; chris@1: chris@1: import java.util.HashMap; chris@1: import java.util.HashSet; chris@1: import java.util.Map; chris@1: import java.util.Set; chris@1: import java.util.concurrent.ConcurrentHashMap; chris@1: chris@1: /** chris@1: * Implementation of a Map that will loose its stored values after a chris@1: * configurable amount of time. chris@1: * This class may be used to cache config values for example. chris@1: * @author Christian Lins chris@1: * @since sonews/0.5.0 chris@1: */ cli@37: public class TimeoutMap extends ConcurrentHashMap chris@1: { chris@1: cli@37: private static final long serialVersionUID = 453453467700345L; cli@37: private int timeout = 60000; // 60 sec cli@37: private transient Map timeoutMap = new HashMap(); chris@1: cli@37: /** cli@37: * Constructor. cli@37: * @param timeout Timeout in milliseconds cli@37: */ cli@37: public TimeoutMap(final int timeout) cli@37: { cli@37: this.timeout = timeout; cli@37: } chris@1: cli@37: /** cli@37: * Uses default timeout (60 sec). cli@37: */ cli@37: public TimeoutMap() cli@37: { cli@37: } chris@1: cli@37: /** cli@37: * cli@37: * @param key cli@37: * @return true if key is still valid. cli@37: */ cli@37: protected boolean checkTimeOut(Object key) cli@37: { cli@37: synchronized (this.timeoutMap) { cli@37: if (this.timeoutMap.containsKey(key)) { cli@37: long keytime = this.timeoutMap.get(key); cli@37: if ((System.currentTimeMillis() - keytime) < this.timeout) { cli@37: return true; cli@37: } else { cli@37: remove(key); cli@37: return false; cli@37: } cli@37: } else { cli@37: return false; cli@37: } cli@37: } cli@37: } chris@1: cli@37: @Override cli@37: public boolean containsKey(Object key) cli@37: { cli@37: return checkTimeOut(key); cli@37: } cli@37: cli@37: @Override cli@37: public synchronized V get(Object key) cli@37: { cli@37: if (checkTimeOut(key)) { cli@37: return super.get(key); cli@37: } else { cli@37: return null; cli@37: } cli@37: } cli@37: cli@37: @Override cli@37: public V put(K key, V value) cli@37: { cli@37: synchronized (this.timeoutMap) { cli@37: removeStaleKeys(); cli@37: this.timeoutMap.put(key, System.currentTimeMillis()); cli@37: return super.put(key, value); cli@37: } cli@37: } cli@37: cli@37: /** cli@37: * @param arg0 cli@37: * @return cli@37: */ cli@37: @Override cli@37: public V remove(Object arg0) cli@37: { cli@37: synchronized (this.timeoutMap) { cli@37: this.timeoutMap.remove(arg0); cli@37: V val = super.remove(arg0); cli@37: return val; cli@37: } cli@37: } cli@37: cli@37: protected void removeStaleKeys() cli@37: { cli@37: synchronized (this.timeoutMap) { cli@37: Set keySet = new HashSet(this.timeoutMap.keySet()); cli@37: for (Object key : keySet) { cli@37: // The key/value is removed by the checkTimeOut() method if true cli@37: checkTimeOut(key); cli@37: } cli@37: } cli@37: } chris@1: }