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.tag; 020 021import java.io.IOException; 022 023import lucee.commons.io.cache.Cache; 024import lucee.commons.io.res.ResourceProvider; 025import lucee.commons.io.res.ResourcesImpl; 026import lucee.commons.io.res.type.cache.CacheResourceProvider; 027import lucee.commons.lang.StringUtil; 028import lucee.runtime.cache.tag.CacheHandlerFactory; 029import lucee.runtime.cache.tag.CacheHandlerFilter; 030import lucee.runtime.cache.tag.query.QueryCacheHandlerFilter; 031import lucee.runtime.cache.tag.query.QueryCacheHandlerFilterUDF; 032import lucee.runtime.cache.tag.timespan.TimespanCacheHandler; 033import lucee.runtime.cache.util.CacheKeyFilterAll; 034import lucee.runtime.config.ConfigImpl; 035import lucee.runtime.config.ConfigWebUtil; 036import lucee.runtime.exp.ApplicationException; 037import lucee.runtime.exp.PageException; 038import lucee.runtime.ext.tag.TagImpl; 039import lucee.runtime.functions.cache.Util; 040import lucee.runtime.op.Caster; 041import lucee.runtime.type.UDF; 042 043import org.apache.oro.text.regex.MalformedPatternException; 044 045/** 046* Flushes the query cache 047* 048* 049* 050**/ 051public final class ObjectCache extends TagImpl { 052 053 private static final int TYPE_QUERY=1; 054 private static final int TYPE_OBJECT=2; 055 private static final int TYPE_TEMPLATE=3; 056 private static final int TYPE_RESOURCE=4; 057 private static final int TYPE_FUNCTION=5; 058 private static final int TYPE_INCLUDE=6; 059 060 /** Clears queries from the cache in the Application scope. */ 061 private String action="clear"; 062 private CacheHandlerFilter filter; 063 private String result="cfObjectCache"; 064 private int type=TYPE_QUERY; 065 066 /** set the value action 067 * Clears queries from the cache in the Application scope. 068 * @param action value to set 069 **/ 070 public void setAction(String action) { 071 this.action=action; 072 } 073 074 public void setResult(String result) { 075 this.result=result; 076 } 077 078 public void setType(String strType) throws ApplicationException { 079 if(StringUtil.isEmpty(strType,true)) return; 080 strType=strType.trim().toLowerCase(); 081 if("function".equals(strType)) type=TYPE_FUNCTION; 082 else if("include".equals(strType)) type=TYPE_INCLUDE; 083 else if("object".equals(strType)) type=TYPE_OBJECT; 084 else if("query".equals(strType)) type=TYPE_QUERY; 085 else if("resource".equals(strType)) type=TYPE_RESOURCE; 086 else if("template".equals(strType)) type=TYPE_TEMPLATE; 087 else 088 throw new ApplicationException("invalid type ["+strType+"], valid types are [function, include, object, query, resource, template]"); 089 090 } 091 092 public void setFilter(Object filter) throws PageException { 093 this.filter=createFilter(filter, false); 094 } 095 096 public void setFilter(String filter) throws PageException { 097 this.filter=createFilter(filter, false); 098 } 099 100 public void setFilterignorecase(String filter) throws PageException { 101 this.filter=createFilter(filter, true); 102 } 103 104 105 106 public static CacheHandlerFilter createFilter(Object filter,boolean ignoreCase) throws PageException { 107 if(filter instanceof UDF) 108 return new QueryCacheHandlerFilterUDF((UDF)filter); 109 String sql=Caster.toString(filter,null); 110 if(!StringUtil.isEmpty(sql,true)) { 111 try { 112 return new QueryCacheHandlerFilter(sql,ignoreCase); 113 } 114 catch (MalformedPatternException e) { 115 throw Caster.toPageException(e); 116 } 117 } 118 return null; 119 } 120 121 /*public static CacheHandlerFilter createFilterx(String sql) { 122 if(!StringUtil.isEmpty(sql,true)) { 123 return new QueryCacheHandlerFilter(sql); 124 } 125 return null; 126 }*/ 127 128 @Override 129 public int doStartTag() throws PageException { 130 try { 131 _doStartTag(); 132 } 133 catch (IOException e) { 134 throw Caster.toPageException(e); 135 } 136 return SKIP_BODY; 137 } 138 public void _doStartTag() throws PageException, IOException { 139 CacheHandlerFactory factory=null; 140 Cache cache=null; 141 142 if(type==TYPE_FUNCTION) factory=ConfigWebUtil.getCacheHandlerFactories(pageContext.getConfig()).function; 143 else if(type==TYPE_INCLUDE) factory=ConfigWebUtil.getCacheHandlerFactories(pageContext.getConfig()).include; 144 else if(type==TYPE_QUERY) factory=ConfigWebUtil.getCacheHandlerFactories(pageContext.getConfig()).query; 145 else if(type==TYPE_RESOURCE) { 146 cache=Util.getDefault(pageContext,ConfigImpl.CACHE_DEFAULT_RESOURCE,null); 147 148 // no specific cache is defined, get default default cache 149 if(cache==null) { 150 // get cache resource provider 151 CacheResourceProvider crp=null; 152 ResourceProvider[] providers = ResourcesImpl.getGlobal().getResourceProviders(); 153 for(int i=0;i<providers.length;i++){ 154 if(providers[i].getScheme().equals("ram") && providers[i] instanceof CacheResourceProvider) { 155 crp=(CacheResourceProvider) providers[i]; 156 } 157 } 158 if(crp==null) throw new ApplicationException("Lucee was not able to load the Ram Resource Provider"); 159 160 // get cache from resource provider 161 cache = crp.getCache(); 162 } 163 } 164 else if(type==TYPE_OBJECT) { 165 // throws a exception if not explicitly defined 166 cache=Util.getDefault(pageContext,ConfigImpl.CACHE_DEFAULT_OBJECT); 167 } 168 else if(type==TYPE_TEMPLATE) { 169 // throws a exception if not explicitly defined 170 cache=Util.getDefault(pageContext,ConfigImpl.CACHE_DEFAULT_TEMPLATE); 171 } 172 173 // Clear 174 if(action.equalsIgnoreCase("clear")) { 175 if(filter==null) { 176 if(cache!=null) cache.remove(CacheKeyFilterAll.getInstance()); 177 else factory.clear(pageContext); 178 } 179 else { 180 if(cache!=null) TimespanCacheHandler.clear(pageContext, cache, filter); 181 else factory.clear(pageContext,filter); 182 } 183 } 184 185 // Size 186 else if(action.equalsIgnoreCase("size")) { 187 int size=0; 188 if(cache!=null) size=cache.keys().size(); 189 else size=factory.size(pageContext); 190 191 pageContext.setVariable(result, Caster.toDouble(size)); 192 } 193 else throw new ApplicationException("attribute action has an invalid value ["+action+"], valid is only [clear,size]"); 194 195 196 197 } 198 199 @Override 200 public int doEndTag() { 201 return EVAL_PAGE; 202 } 203 204 @Override 205 public void release() { 206 super.release(); 207 action="clear"; 208 result="cfObjectCache"; 209 filter=null; 210 type=TYPE_QUERY; 211 } 212}