// Copyright (c) 2006 Dustin Sallings <dustin@spy.net> package net.spy.factory; import java.util.Timer; import java.util.TimerTask; import net.spy.SpyObject; /** * Cache refresh singleton for scheduling and performing cache clears. */ public class CacheRefresher extends SpyObject { private static CacheRefresher instance=null; private final Timer timer; /** * Constructor for subclasses of CacheRefresher. */ protected CacheRefresher() { super(); timer=new Timer("CacheRefresh timer", true); } /** * Get the singleton cache refresher instance. */ public static synchronized CacheRefresher getInstance() { if(instance == null) { setInstance(new CacheRefresher()); } return(instance); } /** * Set a CacheRefresher instance. */ public static synchronized void setInstance(CacheRefresher to) { if(instance != null) { throw new IllegalStateException( "Attempting to overwrite cache refresher instance"); } instance=to; } /** * Shut down this cache refresher instance. */ public void shutdown() { timer.cancel(); instance=null; } synchronized void performRecache(GenFactoryImpl<?> gf, long when) { if(when > gf.getLastRefresh()) { gf.recache(); } else { getLogger().info("Avoiding unnecessary recache of %s.", gf); } gf.setNextRefresh(null); } /** * Request a recache of the given factory to get data as of the given date * after the given delay. * * @param when the date we requested the data * @param delay how long to wait before refreshing */ public synchronized void recache(final GenFactoryImpl<?> gf, final long when, long delay) { TimerTask nextRefresh=gf.getNextRefresh(); if(nextRefresh != null) { boolean canceled=nextRefresh.cancel(); getLogger().debug("%s next refresh of %s, scheduling a future one.", canceled?"Cancelled":"Did not cancel", gf); nextRefresh=null; } nextRefresh=new TimerTask() { @Override public void run() { performRecache(gf, when); } }; timer.schedule(nextRefresh, delay); gf.setNextRefresh(nextRefresh); } }