/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.tag; import java.io.IOException; import lucee.commons.io.cache.Cache; import lucee.commons.io.res.ResourceProvider; import lucee.commons.io.res.ResourcesImpl; import lucee.commons.io.res.type.cache.CacheResourceProvider; import lucee.commons.lang.StringUtil; import lucee.runtime.cache.CacheUtil; import lucee.runtime.cache.tag.CacheHandlerCollection; import lucee.runtime.cache.tag.CacheHandlerCollectionImpl; import lucee.runtime.cache.tag.CacheHandlerFilter; import lucee.runtime.cache.tag.query.QueryCacheHandlerFilter; import lucee.runtime.cache.tag.query.QueryCacheHandlerFilterUDF; import lucee.runtime.cache.util.CacheKeyFilterAll; import lucee.runtime.config.Config; import lucee.runtime.config.Constants; import lucee.runtime.exp.ApplicationException; import lucee.runtime.exp.PageException; import lucee.runtime.ext.tag.TagImpl; import lucee.runtime.op.Caster; import lucee.runtime.type.UDF; /** * Flushes the query cache * * * **/ public final class ObjectCache extends TagImpl { private static final int TYPE_QUERY=1; private static final int TYPE_OBJECT=2; private static final int TYPE_TEMPLATE=3; private static final int TYPE_RESOURCE=4; private static final int TYPE_FUNCTION=5; private static final int TYPE_INCLUDE=6; /** Clears queries from the cache in the Application scope. */ private String action="clear"; private CacheHandlerFilter filter; private String result="cfObjectCache"; private int type=TYPE_QUERY; /** set the value action * Clears queries from the cache in the Application scope. * @param action value to set **/ public void setAction(String action) { this.action=action; } public void setResult(String result) { this.result=result; } public void setType(String strType) throws ApplicationException { if(StringUtil.isEmpty(strType,true)) return; strType=strType.trim().toLowerCase(); if("function".equals(strType)) type=TYPE_FUNCTION; else if("include".equals(strType)) type=TYPE_INCLUDE; else if("object".equals(strType)) type=TYPE_OBJECT; else if("query".equals(strType)) type=TYPE_QUERY; else if("resource".equals(strType)) type=TYPE_RESOURCE; else if("template".equals(strType)) type=TYPE_TEMPLATE; else throw new ApplicationException("invalid type ["+strType+"], valid types are [function, include, object, query, resource, template]"); } public void setFilter(Object filter) throws PageException { this.filter=createFilter(filter, false); } public void setFilter(String filter) throws PageException { this.filter=createFilter(filter, false); } public void setFilterignorecase(String filter) throws PageException { this.filter=createFilter(filter, true); } public static CacheHandlerFilter createFilter(Object filter,boolean ignoreCase) throws PageException { if(filter instanceof UDF) return new QueryCacheHandlerFilterUDF((UDF)filter); String sql=Caster.toString(filter,null); if(!StringUtil.isEmpty(sql,true)) { return new QueryCacheHandlerFilter(sql,ignoreCase); } return null; } /*public static CacheHandlerFilter createFilterx(String sql) { if(!StringUtil.isEmpty(sql,true)) { return new QueryCacheHandlerFilter(sql); } return null; }*/ @Override public int doStartTag() throws PageException { try { _doStartTag(); } catch (IOException e) { throw Caster.toPageException(e); } return SKIP_BODY; } public void _doStartTag() throws PageException, IOException { CacheHandlerCollection factory=null; Cache cache=null; if(type==TYPE_FUNCTION) factory=pageContext.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_FUNCTION,null); else if(type==TYPE_INCLUDE) factory=pageContext.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_INCLUDE,null); else if(type==TYPE_QUERY) factory=pageContext.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_QUERY,null); else if(type==TYPE_RESOURCE) { cache=CacheUtil.getDefault(pageContext,Config.CACHE_TYPE_RESOURCE,null); // no specific cache is defined, get default default cache if(cache==null) { // get cache resource provider CacheResourceProvider crp=null; ResourceProvider[] providers = ResourcesImpl.getGlobal().getResourceProviders(); for(int i=0;i<providers.length;i++){ if(providers[i].getScheme().equals("ram") && providers[i] instanceof CacheResourceProvider) { crp=(CacheResourceProvider) providers[i]; } } if(crp==null) throw new ApplicationException(Constants.NAME+" was not able to load the Ram Resource Provider"); // get cache from resource provider cache = crp.getCache(); } } else if(type==TYPE_OBJECT) { // throws a exception if not explicitly defined cache=CacheUtil.getDefault(pageContext,Config.CACHE_TYPE_OBJECT); } else if(type==TYPE_TEMPLATE) { // throws a exception if not explicitly defined cache=CacheUtil.getDefault(pageContext,Config.CACHE_TYPE_TEMPLATE); } // Clear if(action.equalsIgnoreCase("clear")) { if(filter==null) { if(cache!=null) cache.remove(CacheKeyFilterAll.getInstance()); else factory.clear(pageContext); } else { if(cache!=null) CacheHandlerCollectionImpl.clear(pageContext, cache, filter); else factory.clear(pageContext,filter); } } // Size else if(action.equalsIgnoreCase("size")) { int size=0; if(cache!=null) size=cache.keys().size(); else size=factory.size(pageContext); pageContext.setVariable(result, Caster.toDouble(size)); } else throw new ApplicationException("attribute action has an invalid value ["+action+"], valid is only [clear,size]"); } @Override public int doEndTag() { return EVAL_PAGE; } @Override public void release() { super.release(); action="clear"; result="cfObjectCache"; filter=null; type=TYPE_QUERY; } }