001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
015 * Java(TM), hosted at https://github.com/gunterze/dcm4che.
016 *
017 * The Initial Developer of the Original Code is
018 * Agfa Healthcare.
019 * Portions created by the Initial Developer are Copyright (C) 2012
020 * the Initial Developer. All Rights Reserved.
021 *
022 * Contributor(s):
023 * See @authors listed below
024 *
025 * Alternatively, the contents of this file may be used under the terms of
026 * either the GNU General Public License Version 2 or later (the "GPL"), or
027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
028 * in which case the provisions of the GPL or the LGPL are applicable instead
029 * of those above. If you wish to allow use of your version of this file only
030 * under the terms of either the GPL or the LGPL, and not to allow others to
031 * use your version of this file under the terms of the MPL, indicate your
032 * decision by deleting the provisions above and replace them with the notice
033 * and other provisions required by the GPL or the LGPL. If you do not delete
034 * the provisions above, a recipient may use your version of this file under
035 * the terms of any one of the MPL, the GPL or the LGPL.
036 *
037 * ***** END LICENSE BLOCK ***** */
038
039package org.dcm4che3.conf.api;
040
041import org.dcm4che3.conf.core.api.ConfigurationException;
042
043import java.util.HashMap;
044
045/**
046 * @author Gunter Zeilinger <gunterze@gmail.com>
047 */
048public abstract class ConfigurationCache<C,T> {
049
050    private static final class CacheEntry<T> {
051        final T value;
052        final long fetchTime;
053        CacheEntry(T value, long fetchTime) {
054            this.value = value;
055            this.fetchTime = fetchTime;
056        }
057    }
058
059    private final HashMap<String, CacheEntry<T>> cache =
060            new HashMap<String, CacheEntry<T>>();
061    private final C conf;
062    private long staleTimeout;
063
064    public ConfigurationCache(C conf) {
065        if (conf == null)
066            throw new NullPointerException();
067        this.conf = conf;
068    }
069
070    public int getStaleTimeout() {
071        return (int) (staleTimeout / 1000);
072    }
073
074    public void setStaleTimeout(int staleTimeout) {
075        this.staleTimeout = staleTimeout * 1000L;
076    }
077
078    public void clear() {
079        cache.clear();
080    }
081
082
083    public T get(String key) throws ConfigurationException {
084        long now = System.currentTimeMillis();
085        CacheEntry<T> entry = cache.get(key);
086        if (entry == null 
087                || (staleTimeout != 0 && now > entry.fetchTime + staleTimeout)) {
088            T value = null;
089            try {
090                value = find(conf, key);
091            } catch (ConfigurationNotFoundException e) {
092            }
093            entry = new CacheEntry<T>(value, now);
094            cache.put(key, entry);
095        }
096        return entry.value;
097    }
098
099    protected abstract T find(C conf, String key)
100            throws ConfigurationException;
101
102}