/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.cache.tag.timespan; import java.io.IOException; import java.util.Iterator; import java.util.List; import lucee.commons.io.cache.Cache; import lucee.commons.io.cache.CacheEntry; import lucee.commons.io.cache.CachePro; import lucee.runtime.PageContext; import lucee.runtime.cache.CacheUtil; import lucee.runtime.cache.ram.RamCache; import lucee.runtime.cache.tag.CacheHandler; import lucee.runtime.cache.tag.CacheHandlerCollectionImpl; import lucee.runtime.cache.tag.CacheHandlerFilter; import lucee.runtime.cache.tag.CacheItem; import lucee.runtime.cache.util.CacheKeyFilterAll; import lucee.runtime.config.ConfigWeb; import lucee.runtime.exp.PageException; import lucee.runtime.op.Caster; import lucee.runtime.op.Decision; import lucee.runtime.type.dt.TimeSpan; public class TimespanCacheHandler implements CacheHandler { private int cacheType; private Cache defaultCache; private String id; public TimespanCacheHandler(){} @Override public void init(ConfigWeb cw,String id,int cacheType){ this.cacheType=cacheType; this.id=id; } public void setDefaultCache(Cache defaultCache){ this.defaultCache=defaultCache; } @Override public CacheItem get(PageContext pc, String id) { return CacheHandlerCollectionImpl.toCacheItem(getCache(pc).getValue(id,null),null); } @Override public boolean remove(PageContext pc, String id) { try { return getCache(pc).remove(id); } catch (IOException e) {} return false; } @Override public void set(PageContext pc, String id, Object cachedWithin, CacheItem value) throws PageException { long timeSpan; if(Decision.isDate(cachedWithin, false) && !(cachedWithin instanceof TimeSpan)) timeSpan=Caster.toDate(cachedWithin, null).getTime()-System.currentTimeMillis(); else timeSpan = Caster.toTimespan(cachedWithin).getMillis(); // clear when timespan smaller or equal to 0 if(timeSpan<=0) { try { getCache(pc).remove(id); } catch (IOException e) { throw Caster.toPageException(e); } return; } try { getCache(pc).put(id, value, Long.valueOf(timeSpan), Long.valueOf(timeSpan)); } catch (IOException e) { throw Caster.toPageException(e); } } @Override public void clean(PageContext pc) { try{ Cache c = getCache(pc); List<CacheEntry> entries = c.entries(); if(entries.size()<100) return; Iterator<CacheEntry> it = entries.iterator(); while(it.hasNext()){ it.next(); // touch them to makes sure the cache remove them, not really good, cache must do this by itself } } catch(IOException ioe){} } @Override public void clear(PageContext pc) { try { getCache(pc).remove(CacheKeyFilterAll.getInstance()); } catch (IOException e) {} } @Override public void clear(PageContext pc, CacheHandlerFilter filter) { CacheHandlerCollectionImpl.clear(pc, getCache(pc), filter); } @Override public int size(PageContext pc) { try { return getCache(pc).keys().size(); } catch (IOException e) { return 0; } } private Cache getCache(PageContext pc) { Cache c = CacheUtil.getDefault(pc,cacheType,null); if(c==null) { if(defaultCache==null){ RamCache rm = new RamCache().init(0, 0, RamCache.DEFAULT_CONTROL_INTERVAL); rm.decouple(); defaultCache=rm; } return defaultCache; } if(c instanceof CachePro) return ((CachePro) c).decouple(); return c; } @Override public String id() { return id; } @Override public void release(PageContext pc) { // to nothing } @Override public boolean acceptCachedWithin(Object cachedWithin) { return Caster.toTimespan(cachedWithin,null)!=null; } @Override public String pattern() { // TODO Auto-generated method stub return "#createTimespan(0,0,0,10)#"; } }