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; 020 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.Date; 024import java.util.Iterator; 025import java.util.List; 026 027import lucee.commons.io.cache.Cache; 028import lucee.commons.io.cache.CacheEntry; 029import lucee.commons.io.cache.CacheEntryFilter; 030import lucee.commons.io.cache.CacheKeyFilter; 031import lucee.commons.io.cache.exp.CacheException; 032import lucee.runtime.type.Struct; 033 034public abstract class CacheSupport implements Cache { 035 036 @Override 037 public List<String> keys(CacheKeyFilter filter) throws IOException { 038 boolean all=CacheUtil.allowAll(filter); 039 040 List<String> keys = keys(); 041 List<String> list=new ArrayList<String>(); 042 Iterator<String> it = keys.iterator(); 043 String key; 044 while(it.hasNext()){ 045 key= it.next(); 046 if(all || filter.accept(key))list.add(key); 047 } 048 return list; 049 } 050 051 @Override 052 public List<String> keys(CacheEntryFilter filter) throws IOException { 053 boolean all=CacheUtil.allowAll(filter); 054 055 List<String> keys = keys(); 056 List<String> list=new ArrayList<String>(); 057 Iterator<String> it = keys.iterator(); 058 String key; 059 CacheEntry entry; 060 while(it.hasNext()){ 061 key=it.next(); 062 entry=getQuiet(key,null); 063 if(all || filter.accept(entry))list.add(key); 064 } 065 return list; 066 } 067 068 @Override 069 public List<CacheEntry> entries() throws IOException { 070 List<String> keys = keys(); 071 List<CacheEntry> list=new ArrayList<CacheEntry>(); 072 Iterator<String> it = keys.iterator(); 073 while(it.hasNext()){ 074 list.add(getQuiet(it.next(),null)); 075 } 076 return list; 077 } 078 079 @Override 080 public List<CacheEntry> entries(CacheKeyFilter filter) throws IOException { 081 List<String> keys = keys(); 082 List<CacheEntry> list=new ArrayList<CacheEntry>(); 083 Iterator<String> it = keys.iterator(); 084 String key; 085 while(it.hasNext()){ 086 key=it.next(); 087 if(filter.accept(key))list.add(getQuiet(key,null)); 088 } 089 return list; 090 } 091 092 @Override 093 public List<CacheEntry> entries(CacheEntryFilter filter) throws IOException { 094 List<String> keys = keys(); 095 List<CacheEntry> list=new ArrayList<CacheEntry>(); 096 Iterator<String> it = keys.iterator(); 097 CacheEntry entry; 098 while(it.hasNext()){ 099 entry=getQuiet(it.next(),null); 100 if(filter.accept(entry))list.add(entry); 101 } 102 return list; 103 } 104 105 // there was the wrong generic type defined in the older interface, because of that we do not define a generic type at all here, just to be sure 106 @Override 107 public List values() throws IOException { 108 List<String> keys = keys(); 109 List<Object> list=new ArrayList<Object>(); 110 Iterator<String> it = keys.iterator(); 111 String key; 112 while(it.hasNext()){ 113 key=it.next(); 114 list.add(getQuiet(key,null).getValue()); 115 } 116 return list; 117 } 118 119 // there was the wrong generic type defined in the older interface, because of that we do not define a generic type at all here, just to be sure 120 @Override 121 public List values(CacheEntryFilter filter) throws IOException { 122 if(CacheUtil.allowAll(filter)) return values(); 123 124 List<String> keys = keys(); 125 List<Object> list=new ArrayList<Object>(); 126 Iterator<String> it = keys.iterator(); 127 String key; 128 CacheEntry entry; 129 while(it.hasNext()){ 130 key=it.next(); 131 entry=getQuiet(key,null); 132 if(filter.accept(entry))list.add(entry.getValue()); 133 } 134 return list; 135 } 136 137 // there was the wrong generic type defined in the older interface, because of that we do not define a generic type at all here, just to be sure 138 @Override 139 public List values(CacheKeyFilter filter) throws IOException { 140 if(CacheUtil.allowAll(filter)) return values(); 141 142 List<String> keys = keys(); 143 List<Object> list=new ArrayList<Object>(); 144 Iterator<String> it = keys.iterator(); 145 String key; 146 while(it.hasNext()){ 147 key=it.next(); 148 if(filter.accept(key))list.add(getQuiet(key,null).getValue()); 149 } 150 return list; 151 } 152 153 @Override 154 public int remove(CacheEntryFilter filter) throws IOException { 155 if(CacheUtil.allowAll(filter)) return clear(); 156 157 List<String> keys = keys(); 158 int count=0; 159 Iterator<String> it = keys.iterator(); 160 String key; 161 CacheEntry entry; 162 while(it.hasNext()){ 163 key=it.next(); 164 entry=getQuiet(key,null); 165 if(filter==null || filter.accept(entry)){ 166 remove(key); 167 count++; 168 } 169 } 170 return count; 171 } 172 173 174 @Override 175 public int remove(CacheKeyFilter filter) throws IOException { 176 if(CacheUtil.allowAll(filter)) return clear(); 177 178 179 List<String> keys = keys(); 180 int count=0; 181 Iterator<String> it = keys.iterator(); 182 String key; 183 while(it.hasNext()){ 184 key=it.next(); 185 if(filter==null || filter.accept(key)){ 186 remove(key); 187 count++; 188 } 189 } 190 return count; 191 } 192 193 public Struct getCustomInfo() { 194 return CacheUtil.getInfo(this); 195 } 196 197 198 @Override 199 public Object getValue(String key) throws IOException { 200 return getCacheEntry(key).getValue(); 201 } 202 203 @Override 204 public Object getValue(String key, Object defaultValue) { 205 CacheEntry entry = getCacheEntry(key,null); 206 if(entry==null) return defaultValue; 207 return entry.getValue(); 208 } 209 210 protected static boolean valid(CacheEntry entry) { 211 long now = System.currentTimeMillis(); 212 if(entry.liveTimeSpan()>0 && entry.liveTimeSpan()+getTime(entry.lastModified())<now){ 213 return false; 214 } 215 if(entry.idleTimeSpan()>0 && entry.idleTimeSpan()+getTime(entry.lastHit())<now){ 216 return false; 217 } 218 return true; 219 } 220 221 private static long getTime(Date date) { 222 return date==null?0:date.getTime(); 223 } 224 225 @Override 226 public CacheEntry getCacheEntry(String key) throws IOException { 227 CacheEntry entry = getCacheEntry(key, null); 228 if(entry==null) throw new CacheException("there is no valid cache entry with key ["+key+"]"); 229 return entry; 230 } 231 232 public CacheEntry getQuiet(String key) throws IOException { 233 CacheEntry entry = getQuiet(key, null); 234 if(entry==null) throw new CacheException("there is no valid cache entry with key ["+key+"]"); 235 return entry; 236 } 237 238 public abstract CacheEntry getQuiet(String key, CacheEntry defaultValue); 239 240 /** 241 * remove all entries 242 * @return returns the count of the removal or -1 if this information is not available 243 */ 244 public abstract int clear() throws IOException ; 245 246 247}