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 type==SCOPE_CLIENT?doNowIfNull(pc.getConfig(),Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)):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 /** 079 * @see railo.runtime.type.SharedScope#release(railo.runtime.PageContext) 080 */ 081 public void touchAfterRequest(PageContext pc) { 082 setTimeSpan(pc); 083 super.touchAfterRequest(pc); 084 //if(super.hasContent()) 085 store(pc.getConfig()); 086 } 087 088 /** 089 * @see railo.runtime.type.scope.storage.StorageScope#getStorageType() 090 */ 091 public String getStorageType() { 092 return "Cache"; 093 } 094 095 /** 096 * 097 * @see railo.runtime.type.scope.ClientSupportOld#initialize(railo.runtime.PageContext) 098 */ 099 public void touchBeforeRequest(PageContext pc) { 100 setTimeSpan(pc); 101 super.touchBeforeRequest(pc); 102 } 103 104 protected static Struct _loadData(PageContext pc, String cacheName, String appName, String strType, Log log) throws PageException { 105 Cache cache = getCache(pc.getConfig(),cacheName); 106 String key=getKey(pc.getCFID(),appName,strType); 107 108 Struct s = (Struct) cache.getValue(key,null); 109 110 if(s!=null) 111 ScopeContext.info(log,"load existing data from cache ["+cacheName+"] to create "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()); 112 else 113 ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()+" in cache ["+cacheName+"]"); 114 115 return s; 116 } 117 118 public void store(Config config) { 119 try { 120 Cache cache = getCache(config, cacheName); 121 /*if(cache instanceof CacheEvent) { 122 CacheEvent ce=(CacheEvent) cache; 123 ce.register(new SessionEndCacheEvent()); 124 }*/ 125 String key=getKey(cfid, appName, getTypeAsString()); 126 cache.put(key, sct,new Long(getTimeSpan()), null); 127 } 128 catch (PageException pe) {} 129 } 130 131 public void unstore(Config config) { 132 try { 133 Cache cache = getCache(config, cacheName); 134 String key=getKey(cfid, appName, getTypeAsString()); 135 cache.remove(key); 136 } 137 catch (PageException pe) {} 138 } 139 140 141 private static Cache getCache(Config config, String cacheName) throws PageException { 142 try { 143 CacheConnection cc = Util.getCacheConnection(config,cacheName); 144 if(!cc.isStorage()) 145 throw new ApplicationException("storage usage for this cache is disabled, you can enable this in the railo administrator."); 146 return cc.getInstance(config); 147 } catch (IOException e) { 148 throw Caster.toPageException(e); 149 } 150 } 151 152 153 public static String getKey(String cfid, String appName, String type) { 154 return new StringBuilder("railo-storage:").append(type).append(":").append(cfid).append(":").append(appName).toString(); 155 } 156 157 /*private void setTimeSpan(PageContext pc) { 158 ApplicationContextPro ac=(ApplicationContextPro) pc.getApplicationContext(); 159 timespan = (getType()==SCOPE_CLIENT?ac.getClientTimeout().getMillis():ac.getSessionTimeout().getMillis())+(expiresControlFromOutside?SAVE_EXPIRES_OFFSET:0L); 160 161 }*/ 162 }