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