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}