001 package railo.runtime.type.scope.storage; 002 003 import java.io.IOException; 004 005 import railo.commons.io.cache.Cache; 006 import railo.commons.io.log.Log; 007 import railo.runtime.PageContext; 008 import railo.runtime.cache.CacheConnection; 009 import railo.runtime.config.Config; 010 import railo.runtime.exp.ApplicationException; 011 import railo.runtime.exp.PageException; 012 import railo.runtime.functions.cache.Util; 013 import railo.runtime.op.Caster; 014 import railo.runtime.type.Struct; 015 import railo.runtime.type.dt.DateTime; 016 import railo.runtime.type.dt.DateTimeImpl; 017 import railo.runtime.type.scope.ScopeContext; 018 019 /** 020 * client scope that store it's data in a datasource 021 */ 022 public abstract class StorageScopeCache extends StorageScopeImpl { 023 024 private static final long serialVersionUID = 6234854552927320080L; 025 026 public static final long SAVE_EXPIRES_OFFSET = 60*60*1000; 027 028 //private static ScriptConverter serializer=new ScriptConverter(); 029 //boolean structOk; 030 031 private final String cacheName; 032 private final String appName; 033 private final String cfid; 034 035 036 037 038 /** 039 * Constructor of the class 040 * @param pc 041 * @param name 042 * @param sct 043 * @param b 044 */ 045 protected StorageScopeCache(PageContext pc,String cacheName, String appName,String strType,int type,Struct sct) { 046 // !!! do not store the pagecontext or config object, this object is Serializable !!! 047 super( 048 sct, 049 doNowIfNull(pc.getConfig(),Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)), 050 doNowIfNull(pc.getConfig(),Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)), 051 -1, 052 type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):1 053 ,strType,type); 054 055 //this.isNew=isNew; 056 this.appName=appName; 057 this.cacheName=cacheName; 058 this.cfid=pc.getCFID(); 059 } 060 061 /** 062 * Constructor of the class, clone existing 063 * @param other 064 */ 065 protected StorageScopeCache(StorageScopeCache other,boolean deepCopy) { 066 super(other,deepCopy); 067 068 this.appName=other.appName; 069 this.cacheName=other.cacheName; 070 this.cfid=other.cfid; 071 } 072 073 private static DateTime doNowIfNull(Config config,DateTime dt) { 074 if(dt==null)return new DateTimeImpl(config); 075 return dt; 076 } 077 078 @Override 079 public void touchAfterRequest(PageContext pc) { 080 setTimeSpan(pc); 081 super.touchAfterRequest(pc); 082 //if(super.hasContent()) 083 store(pc.getConfig()); 084 } 085 086 @Override 087 public String getStorageType() { 088 return "Cache"; 089 } 090 091 @Override 092 public void touchBeforeRequest(PageContext pc) { 093 setTimeSpan(pc); 094 super.touchBeforeRequest(pc); 095 } 096 097 protected static Struct _loadData(PageContext pc, String cacheName, String appName, String strType, Log log) throws PageException { 098 Cache cache = getCache(pc.getConfig(),cacheName); 099 String key=getKey(pc.getCFID(),appName,strType); 100 101 Struct s = (Struct) cache.getValue(key,null); 102 103 if(s!=null) 104 ScopeContext.info(log,"load existing data from cache ["+cacheName+"] to create "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()); 105 else 106 ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()+" in cache ["+cacheName+"]"); 107 108 return s; 109 } 110 111 public void store(Config config) { 112 try { 113 Cache cache = getCache(config, cacheName); 114 /*if(cache instanceof CacheEvent) { 115 CacheEvent ce=(CacheEvent) cache; 116 ce.register(new SessionEndCacheEvent()); 117 }*/ 118 String key=getKey(cfid, appName, getTypeAsString()); 119 cache.put(key, sct,new Long(getTimeSpan()), null); 120 } 121 catch (Exception pe) {} 122 } 123 124 public void unstore(Config config) { 125 try { 126 Cache cache = getCache(config, cacheName); 127 String key=getKey(cfid, appName, getTypeAsString()); 128 cache.remove(key); 129 } 130 catch (Exception pe) {} 131 } 132 133 134 private static Cache getCache(Config config, String cacheName) throws PageException { 135 try { 136 CacheConnection cc = Util.getCacheConnection(config,cacheName); 137 if(!cc.isStorage()) 138 throw new ApplicationException("storage usage for this cache is disabled, you can enable this in the railo administrator."); 139 return cc.getInstance(config); 140 } catch (IOException e) { 141 throw Caster.toPageException(e); 142 } 143 } 144 145 146 public static String getKey(String cfid, String appName, String type) { 147 return new StringBuilder("railo-storage:").append(type).append(":").append(cfid).append(":").append(appName).toString(); 148 } 149 150 /*private void setTimeSpan(PageContext pc) { 151 ApplicationContext ac=(ApplicationContext) pc.getApplicationContext(); 152 timespan = (getType()==SCOPE_CLIENT?ac.getClientTimeout().getMillis():ac.getSessionTimeout().getMillis())+(expiresControlFromOutside?SAVE_EXPIRES_OFFSET:0L); 153 154 }*/ 155 }