/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * 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.type.scope.storage.clean; import java.io.IOException; import lucee.commons.io.IOUtil; import lucee.commons.io.res.Resource; import lucee.commons.io.res.filter.AndResourceFilter; import lucee.commons.io.res.filter.DirectoryResourceFilter; import lucee.commons.io.res.filter.ExtensionResourceFilter; import lucee.commons.io.res.filter.ResourceFilter; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.ExceptionUtil; import lucee.runtime.config.ConfigWebImpl; import lucee.runtime.op.Caster; import lucee.runtime.type.dt.DateTimeImpl; import lucee.runtime.type.scope.Scope; import lucee.runtime.type.scope.storage.StorageScopeEngine; import lucee.runtime.type.scope.storage.StorageScopeImpl; import lucee.runtime.type.scope.storage.StorageScopeListener; public class FileStorageScopeCleaner extends StorageScopeCleanerSupport { private static final ResourceFilter DIR_FILTER = new DirectoryResourceFilter(); private static ExtensionResourceFilter EXT_FILTER = new ExtensionResourceFilter(".scpt",true); public FileStorageScopeCleaner(int type,StorageScopeListener listener) { super(type,listener,INTERVALL_DAY); } @Override public void init(StorageScopeEngine engine){ super.init(engine); } @Override protected void _clean() { ConfigWebImpl cwi=(ConfigWebImpl) engine.getFactory().getConfig(); Resource dir=type==Scope.SCOPE_CLIENT?cwi.getClientScopeDir():cwi.getSessionScopeDir(); // for old files only the defintion from admin can be used long timeout=type==Scope.SCOPE_CLIENT?cwi.getClientTimeout().getMillis():cwi.getSessionTimeout().getMillis(); long time = new DateTimeImpl(cwi).getTime()-timeout; try { // delete files that has expired AndResourceFilter andFilter = new AndResourceFilter(new ResourceFilter[]{EXT_FILTER,new ExpiresFilter(time,true)}); String appName,cfid2,cfid; Resource[] apps = dir.listResources(DIR_FILTER),cfidDir,files; if(apps!=null)for(int a=0;a<apps.length;a++){ appName=StorageScopeImpl.decode(apps[a].getName()); cfidDir=apps[a].listResources(DIR_FILTER); if(cfidDir!=null)for(int b=0;b<cfidDir.length;b++){ cfid2=cfidDir[b].getName(); files=cfidDir[b].listResources(andFilter); if(files!=null){ for(int c=0;c<files.length;c++){ cfid=files[c].getName(); cfid=cfid2+cfid.substring(0,cfid.length()-5); if(listener!=null)listener.doEnd(engine,this, appName, cfid); //info("remove from memory "+appName+"/"+cfid); engine.remove(type,appName,cfid); info("remove file "+files[c]); files[c].delete(); } } } } ResourceUtil.deleteEmptyFolders(dir); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);error(t);} //long maxSize = type==Scope.SCOPE_CLIENT?cwi.getClientScopeDirSize():cwi.getSessionScopeDirSize(); //checkSize(config,dir,maxSize,extfilter); } static class ExpiresFilter implements ResourceFilter { private long time; private boolean allowDir; public ExpiresFilter(long time, boolean allowDir) { this.allowDir=allowDir; this.time=time; } @Override public boolean accept(Resource res) { if(res.isDirectory()) return allowDir; // load content String str=null; try { str = IOUtil.toString(res,"UTF-8"); } catch (IOException e) { return false; } int index=str.indexOf(':'); if(index!=-1){ long expires=Caster.toLongValue(str.substring(0,index),-1L); // check is for backward compatibility, old files have no expires date inside. they do ot expire if(expires!=-1) { if(expires<System.currentTimeMillis()){ return true; } str=str.substring(index+1); return false; } } // old files not having a timestamp inside else if(res.lastModified()<=time) { return true; } return false; } } }