001 package railo.runtime.type.scope.storage; 002 003 import railo.commons.io.IOUtil; 004 import railo.commons.io.log.Log; 005 import railo.commons.io.res.Resource; 006 import railo.commons.io.res.util.ResourceUtil; 007 import railo.commons.lang.StringUtil; 008 import railo.runtime.PageContext; 009 import railo.runtime.config.Config; 010 import railo.runtime.config.ConfigImpl; 011 import railo.runtime.config.ConfigWeb; 012 import railo.runtime.converter.ScriptConverter; 013 import railo.runtime.interpreter.CFMLExpressionInterpreter; 014 import railo.runtime.op.Caster; 015 import railo.runtime.type.Struct; 016 import railo.runtime.type.StructImpl; 017 import railo.runtime.type.dt.DateTime; 018 import railo.runtime.type.dt.DateTimeImpl; 019 import railo.runtime.type.scope.ScopeContext; 020 021 /** 022 * client scope that store it's data in a resource 023 */ 024 public abstract class StorageScopeFile extends StorageScopeImpl { 025 026 private static final long serialVersionUID = -7519591903822909934L; 027 028 public static final String STORAGE_TYPE = "File"; 029 030 private static ScriptConverter serializer=new ScriptConverter(); 031 protected static CFMLExpressionInterpreter evaluator=new CFMLExpressionInterpreter(); 032 033 private Resource res; 034 035 /** 036 * Constructor of the class 037 * @param pc 038 * @param name 039 * @param sct 040 */ 041 protected StorageScopeFile(PageContext pc,Resource res,String strType,int type,Struct sct) { 042 super( 043 sct==null?(sct=new StructImpl()):sct, 044 doNowIfNull(pc,Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)), 045 doNowIfNull(pc,Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)), 046 -1, 047 type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):0, 048 strType,type); 049 050 this.res =res;// pc.getConfig().getClientScopeDir().getRealResource(name+"-"+pc.getCFID()+".script"); 051 052 } 053 private static DateTime doNowIfNull(PageContext pc,DateTime dt) { 054 if(dt==null)return new DateTimeImpl(pc.getConfig()); 055 return dt; 056 } 057 058 /** 059 * Constructor of the class, clone existing 060 * @param other 061 */ 062 protected StorageScopeFile(StorageScopeFile other,boolean deepCopy) { 063 super(other,deepCopy); 064 this.res=other.res; 065 } 066 067 @Override 068 public void touchBeforeRequest(PageContext pc) { 069 setTimeSpan(pc); 070 super.touchBeforeRequest(pc); 071 } 072 073 @Override 074 public void touchAfterRequest(PageContext pc) { 075 setTimeSpan(pc); 076 super.touchAfterRequest(pc); 077 store(pc.getConfig()); 078 } 079 080 081 082 @Override 083 public void store(Config config) { 084 //if(!super.hasContent()) return; 085 try { 086 if(!res.exists())ResourceUtil.createFileEL(res, true); 087 IOUtil.write(res, (getTimeSpan()+System.currentTimeMillis())+":"+serializer.serializeStruct(sct, ignoreSet), "UTF-8", false); 088 } 089 catch (Throwable t) {} 090 } 091 092 protected static Struct _loadData(PageContext pc,Resource res, Log log) { 093 if(res.exists()) { 094 try { 095 String str=IOUtil.toString(res,"UTF-8"); 096 int index=str.indexOf(':'); 097 if(index!=-1){ 098 long expires=Caster.toLongValue(str.substring(0,index),-1L); 099 // check is for backward compatibility, old files have no expires date inside. they do ot expire 100 if(expires!=-1) { 101 str=str.substring(index+1); 102 /*if(checkExpires && expires<System.currentTimeMillis()){ 103 print.o("expired("+new Date(expires)+"):"+res); 104 return null; 105 } 106 else { 107 str=str.substring(index+1); 108 print.o("not expired("+new Date(expires)+"):"+res); 109 print.o(str); 110 }*/ 111 } 112 } 113 Struct s = (Struct) evaluator.interpret(pc,str); 114 ScopeContext.info(log,"load existing file storage ["+res+"]"); 115 return s; 116 } 117 catch (Throwable t) { 118 ScopeContext.error(log, t); 119 } 120 } 121 ScopeContext.info(log,"create new file storage ["+res+"]"); 122 return null; 123 } 124 125 126 127 public void unstore(Config config) { 128 try { 129 if(!res.exists())return; 130 res.remove(true); 131 } 132 catch (Throwable t) {} 133 } 134 135 protected static Resource _loadResource(ConfigWeb config, int type,String name, String cfid) { 136 ConfigImpl ci = (ConfigImpl)config; 137 Resource dir= type==SCOPE_CLIENT?ci.getClientScopeDir():ci.getSessionScopeDir(); 138 return dir.getRealResource(getFolderName(name,cfid,true)); 139 } 140 141 142 143 /** 144 * return a folder name that match given input 145 * @param name 146 * @param cfid 147 * @param addExtension 148 * @return 149 */ 150 public static String getFolderName(String name, String cfid,boolean addExtension) { 151 if(addExtension) return getFolderName(name, cfid, false)+".scpt"; 152 if(!StringUtil.isEmpty(name)) 153 name=encode(name);//StringUtil.toVariableName(StringUtil.toLowerCase(name)); 154 else 155 name="__empty__"; 156 return name+"/"+cfid.substring(0,2)+"/"+cfid.substring(2); 157 } 158 159 160 @Override 161 public String getStorageType() { 162 return STORAGE_TYPE; 163 } 164 165 166 }