001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.cache.tag.timespan; 020 021import java.io.IOException; 022import java.util.Iterator; 023import java.util.List; 024 025import lucee.commons.io.cache.Cache; 026import lucee.commons.io.cache.CacheEntry; 027import lucee.runtime.PageContext; 028import lucee.runtime.cache.ram.RamCache; 029import lucee.runtime.cache.tag.CacheHandler; 030import lucee.runtime.cache.tag.CacheHandlerFactory; 031import lucee.runtime.cache.tag.CacheHandlerFilter; 032import lucee.runtime.cache.tag.CacheItem; 033import lucee.runtime.cache.tag.query.QueryCacheItem; 034import lucee.runtime.cache.util.CacheKeyFilterAll; 035import lucee.runtime.exp.PageException; 036import lucee.runtime.functions.cache.Util; 037import lucee.runtime.op.Caster; 038import lucee.runtime.op.Decision; 039import lucee.runtime.type.dt.TimeSpan; 040 041public class TimespanCacheHandler implements CacheHandler { 042 043 private int defaultCacheType; 044 private Cache defaultCache; 045 046 public TimespanCacheHandler(int defaultCacheType, Cache defaultCache){ 047 this.defaultCacheType=defaultCacheType; 048 this.defaultCache=defaultCache; 049 } 050 051 @Override 052 public CacheItem get(PageContext pc, String id) { 053 return CacheHandlerFactory.toCacheItem(getCache(pc).getValue(id,null),null); 054 } 055 056 @Override 057 public boolean remove(PageContext pc, String id) { 058 try { 059 return getCache(pc).remove(id); 060 } 061 catch (IOException e) {} 062 return false; 063 } 064 065 066 @Override 067 public void set(PageContext pc, String id, Object cachedWithin, CacheItem value) throws PageException { 068 long timeSpan; 069 if(Decision.isDate(cachedWithin, false) && !(cachedWithin instanceof TimeSpan)) 070 timeSpan=Caster.toDate(cachedWithin, null).getTime()-System.currentTimeMillis(); 071 else 072 timeSpan = Caster.toTimespan(cachedWithin).getMillis(); 073 074 // ignore timespan smaller or equal to 0 075 if(timeSpan<=0) return; 076 077 getCache(pc).put(id, value, Long.valueOf(timeSpan), Long.valueOf(timeSpan)); 078 } 079 080 @Override 081 public void clean(PageContext pc) { 082 try{ 083 Cache c = getCache(pc); 084 List<CacheEntry> entries = c.entries(); 085 if(entries.size()<100) return; 086 087 Iterator<CacheEntry> it = entries.iterator(); 088 while(it.hasNext()){ 089 it.next(); // touch them to makes sure the cache remove them, not really good, cache must do this by itself 090 } 091 } 092 catch(IOException ioe){} 093 } 094 095 096 @Override 097 public void clear(PageContext pc) { 098 try { 099 getCache(pc).remove(CacheKeyFilterAll.getInstance()); 100 } 101 catch (IOException e) {} 102 } 103 104 105 @Override 106 public void clear(PageContext pc, CacheHandlerFilter filter) { 107 clear(pc, getCache(pc), filter); 108 } 109 110 public static void clear(PageContext pc, Cache cache, CacheHandlerFilter filter) { 111 try{ 112 Iterator<CacheEntry> it = cache.entries().iterator(); 113 CacheEntry ce; 114 Object obj; 115 while(it.hasNext()){ 116 ce = it.next(); 117 if(filter==null) { 118 cache.remove(ce.getKey()); 119 continue; 120 } 121 122 obj=ce.getValue(); 123 if(obj instanceof QueryCacheItem) 124 obj=((QueryCacheItem)obj).getQuery(); 125 if(filter.accept(obj)) 126 cache.remove(ce.getKey()); 127 } 128 } 129 catch (IOException e) {} 130 } 131 132 @Override 133 public int size(PageContext pc) { 134 try { 135 return getCache(pc).keys().size(); 136 } 137 catch (IOException e) { 138 return 0; 139 } 140 } 141 142 143 private Cache getCache(PageContext pc) { 144 Cache c = Util.getDefault(pc,defaultCacheType,null); 145 if(c==null) { 146 if(defaultCache==null)defaultCache=new RamCache().init(0, 0, RamCache.DEFAULT_CONTROL_INTERVAL); 147 return defaultCache; 148 } 149 return c; 150 } 151 152 @Override 153 public String label() throws PageException { 154 return "timespan"; 155 } 156 157}