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}