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.type.scope.storage.clean; 020 021import java.io.IOException; 022 023import lucee.commons.io.IOUtil; 024import lucee.commons.io.res.Resource; 025import lucee.commons.io.res.filter.AndResourceFilter; 026import lucee.commons.io.res.filter.DirectoryResourceFilter; 027import lucee.commons.io.res.filter.ExtensionResourceFilter; 028import lucee.commons.io.res.filter.ResourceFilter; 029import lucee.commons.io.res.util.ResourceUtil; 030import lucee.commons.lang.ExceptionUtil; 031import lucee.runtime.config.ConfigWebImpl; 032import lucee.runtime.op.Caster; 033import lucee.runtime.type.dt.DateTimeImpl; 034import lucee.runtime.type.scope.Scope; 035import lucee.runtime.type.scope.storage.StorageScopeEngine; 036import lucee.runtime.type.scope.storage.StorageScopeFile; 037import lucee.runtime.type.scope.storage.StorageScopeListener; 038 039public class FileStorageScopeCleaner extends StorageScopeCleanerSupport { 040 041 private static final ResourceFilter DIR_FILTER = new DirectoryResourceFilter(); 042 private static ExtensionResourceFilter EXT_FILTER = new ExtensionResourceFilter(".scpt",true); 043 044 045 046 047 048 public FileStorageScopeCleaner(int type,StorageScopeListener listener) { 049 super(type,listener,INTERVALL_DAY); 050 } 051 052 @Override 053 public void init(StorageScopeEngine engine){ 054 super.init(engine); 055 } 056 057 @Override 058 protected void _clean() { 059 ConfigWebImpl cwi=(ConfigWebImpl) engine.getFactory().getConfig(); 060 Resource dir=type==Scope.SCOPE_CLIENT?cwi.getClientScopeDir():cwi.getSessionScopeDir(); 061 062 // for old files only the defintion from admin can be used 063 long timeout=type==Scope.SCOPE_CLIENT?cwi.getClientTimeout().getMillis():cwi.getSessionTimeout().getMillis(); 064 long time = new DateTimeImpl(cwi).getTime()-timeout; 065 066 try { 067 // delete files that has expired 068 AndResourceFilter andFilter = new AndResourceFilter(new ResourceFilter[]{EXT_FILTER,new ExpiresFilter(time,true)}); 069 String appName,cfid2,cfid; 070 Resource[] apps = dir.listResources(DIR_FILTER),cfidDir,files; 071 072 if(apps!=null)for(int a=0;a<apps.length;a++){ 073 appName=StorageScopeFile.decode(apps[a].getName()); 074 cfidDir=apps[a].listResources(DIR_FILTER); 075 if(cfidDir!=null)for(int b=0;b<cfidDir.length;b++){ 076 cfid2=cfidDir[b].getName(); 077 files=cfidDir[b].listResources(andFilter); 078 if(files!=null){ 079 for(int c=0;c<files.length;c++){ 080 cfid=files[c].getName(); 081 cfid=cfid2+cfid.substring(0,cfid.length()-5); 082 083 if(listener!=null)listener.doEnd(engine,this, appName, cfid); 084 085 //info("remove from memory "+appName+"/"+cfid); 086 engine.remove(type,appName,cfid); 087 088 info("remove file "+files[c]); 089 files[c].delete(); 090 } 091 } 092 } 093 } 094 095 ResourceUtil.removeEmptyFolders(dir,null); 096 097 } catch (Throwable t) { 098 ExceptionUtil.rethrowIfNecessary(t); 099 error(t); 100 } 101 102 103 //long maxSize = type==Scope.SCOPE_CLIENT?cwi.getClientScopeDirSize():cwi.getSessionScopeDirSize(); 104 //checkSize(config,dir,maxSize,extfilter); 105 } 106 107 108 static class ExpiresFilter implements ResourceFilter { 109 110 private long time; 111 private boolean allowDir; 112 113 public ExpiresFilter(long time, boolean allowDir) { 114 this.allowDir=allowDir; 115 this.time=time; 116 } 117 118 public boolean accept(Resource res) { 119 120 if(res.isDirectory()) return allowDir; 121 122 // load content 123 String str=null; 124 try { 125 str = IOUtil.toString(res,"UTF-8"); 126 } 127 catch (IOException e) { 128 return false; 129 } 130 131 int index=str.indexOf(':'); 132 if(index!=-1){ 133 long expires=Caster.toLongValue(str.substring(0,index),-1L); 134 // check is for backward compatibility, old files have no expires date inside. they do ot expire 135 if(expires!=-1) { 136 if(expires<System.currentTimeMillis()){ 137 return true; 138 } 139 str=str.substring(index+1); 140 return false; 141 } 142 } 143 // old files not having a timestamp inside 144 else if(res.lastModified()<=time) { 145 return true; 146 147 } 148 return false; 149 } 150 151 } 152 153 154}