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.functions.cache; 020 021import java.io.IOException; 022import java.lang.reflect.InvocationTargetException; 023import java.lang.reflect.Method; 024import java.util.Iterator; 025 026import lucee.commons.io.cache.Cache; 027import lucee.commons.io.cache.CacheEntryFilter; 028import lucee.commons.io.cache.exp.CacheException; 029import lucee.commons.lang.ExceptionUtil; 030import lucee.commons.lang.StringUtil; 031import lucee.runtime.PageContext; 032import lucee.runtime.cache.CacheConnection; 033import lucee.runtime.config.Config; 034import lucee.runtime.config.ConfigImpl; 035import lucee.runtime.config.ConfigWeb; 036import lucee.runtime.engine.ThreadLocalPageContext; 037 038public class Util { 039 040 /** 041 * get the default cache for a certain type, also check definitions in application context (application.cfc/cfapplication) 042 * @param pc current PageContext 043 * @param type default type -> Config.CACHE_DEFAULT_... 044 * @param defaultValue value returned when there is no default cache for this type 045 * @return matching cache 046 */ 047 public static Cache getDefault(PageContext pc, int type,Cache defaultValue) { 048 // get default from application conetx 049 String name=null; 050 if(pc!=null && pc.getApplicationContext()!=null) 051 name=pc.getApplicationContext().getDefaultCacheName(type); 052 Config config=ThreadLocalPageContext.getConfig(pc); 053 if(!StringUtil.isEmpty(name)){ 054 Cache cc = getCache(config, name, null); 055 if(cc!=null) return cc; 056 } 057 058 // get default from config 059 CacheConnection cc= ((ConfigImpl)config).getCacheDefaultConnection(type); 060 if(cc==null) return defaultValue; 061 try { 062 return cc.getInstance(config); 063 } catch (Throwable t) { 064 ExceptionUtil.rethrowIfNecessary(t); 065 return defaultValue; 066 } 067 } 068 069 /** 070 * get the default cache for a certain type, also check definitions in application context (application.cfc/cfapplication) 071 * @param pc current PageContext 072 * @param type default type -> Config.CACHE_DEFAULT_... 073 * @return matching cache 074 * @throws IOException 075 */ 076 public static Cache getDefault(PageContext pc, int type) throws IOException { 077 // get default from application conetx 078 String name=pc!=null?pc.getApplicationContext().getDefaultCacheName(type):null; 079 if(!StringUtil.isEmpty(name)){ 080 Cache cc = getCache(pc.getConfig(), name, null); 081 if(cc!=null) return cc; 082 } 083 084 // get default from config 085 Config config = ThreadLocalPageContext.getConfig(pc); 086 CacheConnection cc= ((ConfigImpl)config).getCacheDefaultConnection(type); 087 if(cc==null) throw new CacheException("there is no default "+toStringType(type,"")+" cache defined, you need to define this default cache in the Lucee Administrator"); 088 return cc.getInstance(config); 089 090 091 } 092 093 public static Cache getCache(PageContext pc,String cacheName, int type) throws IOException { 094 if(StringUtil.isEmpty(cacheName)){ 095 return getDefault(pc, type); 096 } 097 return getCache(ThreadLocalPageContext.getConfig(pc), cacheName); 098 } 099 100 public static Cache getCache(PageContext pc,String cacheName, int type, Cache defaultValue) { 101 if(StringUtil.isEmpty(cacheName)){ 102 return getDefault(pc, type,defaultValue); 103 } 104 return getCache(ThreadLocalPageContext.getConfig(pc), cacheName,defaultValue); 105 } 106 107 108 public static Cache getCache(Config config,String cacheName) throws IOException { 109 CacheConnection cc= config.getCacheConnections().get(cacheName.toLowerCase().trim()); 110 if(cc==null) throw noCache(config,cacheName); 111 return cc.getInstance(config); 112 } 113 114 public static Cache getCache(Config config,String cacheName, Cache defaultValue) { 115 CacheConnection cc= config.getCacheConnections().get(cacheName.toLowerCase().trim()); 116 if(cc==null) return defaultValue; 117 try { 118 return cc.getInstance(config); 119 } catch (Throwable t) { 120 ExceptionUtil.rethrowIfNecessary(t); 121 return defaultValue; 122 } 123 } 124 public static CacheConnection getCacheConnection(Config config,String cacheName) throws IOException { 125 CacheConnection cc= config.getCacheConnections().get(cacheName.toLowerCase().trim()); 126 if(cc==null) throw noCache(config,cacheName); 127 return cc; 128 } 129 130 public static CacheConnection getCacheConnection(Config config,String cacheName, CacheConnection defaultValue) { 131 CacheConnection cc= config.getCacheConnections().get(cacheName.toLowerCase().trim()); 132 if(cc==null) return defaultValue; 133 return cc; 134 } 135 136 137 138 139 140 141 private static CacheException noCache(Config config, String cacheName) { 142 StringBuilder sb=new StringBuilder("there is no cache defined with name [").append(cacheName).append("], available caches are ["); 143 Iterator<String> it = ((ConfigImpl)config).getCacheConnections().keySet().iterator(); 144 if(it.hasNext()){ 145 sb.append(it.next()); 146 } 147 while(it.hasNext()){ 148 sb.append(", ").append(it.next()); 149 } 150 sb.append("]"); 151 152 return new CacheException(sb.toString()); 153 } 154 155 private static String toStringType(int type, String defaultValue) { 156 if(type==ConfigImpl.CACHE_DEFAULT_OBJECT) return "object"; 157 if(type==ConfigImpl.CACHE_DEFAULT_TEMPLATE) return "template"; 158 if(type==ConfigImpl.CACHE_DEFAULT_QUERY) return "query"; 159 if(type==ConfigImpl.CACHE_DEFAULT_RESOURCE) return "resource"; 160 if(type==ConfigImpl.CACHE_DEFAULT_FUNCTION) return "function"; 161 if(type==ConfigImpl.CACHE_DEFAULT_INCLUDE) return "include"; 162 return defaultValue; 163 } 164 165 public static String key(String key) { 166 return key.toUpperCase().trim(); 167 } 168 169 170 public static boolean removeEL(ConfigWeb config, CacheConnection cc) { 171 try { 172 remove(config,cc); 173 return true; 174 } catch (Throwable e) { 175 ExceptionUtil.rethrowIfNecessary(e); 176 return false; 177 } 178 } 179 public static void remove(ConfigWeb config, CacheConnection cc) throws Throwable { 180 Cache c = cc.getInstance(config); 181 // FUTURE no reflection needed 182 183 184 Method remove=null; 185 try{ 186 remove = c.getClass().getMethod("remove", new Class[0]); 187 188 } 189 catch(Exception ioe){ 190 c.remove((CacheEntryFilter)null); 191 return; 192 } 193 194 try { 195 remove.invoke(c, new Object[0]); 196 } 197 catch (InvocationTargetException e) { 198 throw e.getTargetException(); 199 } 200 } 201 202 public static int toType(String type, int defaultValue) { 203 type=type.trim().toLowerCase(); 204 if("object".equals(type)) return ConfigImpl.CACHE_DEFAULT_OBJECT; 205 if("query".equals(type)) return ConfigImpl.CACHE_DEFAULT_QUERY; 206 if("resource".equals(type)) return ConfigImpl.CACHE_DEFAULT_RESOURCE; 207 if("template".equals(type)) return ConfigImpl.CACHE_DEFAULT_TEMPLATE; 208 if("function".equals(type)) return ConfigImpl.CACHE_DEFAULT_FUNCTION; 209 if("include".equals(type)) return ConfigImpl.CACHE_DEFAULT_INCLUDE; 210 return defaultValue; 211 } 212 213 public static String toType(int type, String defaultValue) { 214 if(ConfigImpl.CACHE_DEFAULT_OBJECT==type) return "object"; 215 if(ConfigImpl.CACHE_DEFAULT_QUERY==type) return "query"; 216 if(ConfigImpl.CACHE_DEFAULT_RESOURCE==type) return "resource"; 217 if(ConfigImpl.CACHE_DEFAULT_TEMPLATE==type) return "template"; 218 if(ConfigImpl.CACHE_DEFAULT_FUNCTION==type) return "function"; 219 if(ConfigImpl.CACHE_DEFAULT_INCLUDE==type) return "include"; 220 return defaultValue; 221 } 222}