package railo.runtime.type.scope.storage;
import java.io.IOException;
import railo.commons.io.cache.Cache;
import railo.commons.io.log.Log;
import railo.runtime.PageContext;
import railo.runtime.cache.CacheConnection;
import railo.runtime.config.Config;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.PageException;
import railo.runtime.functions.cache.Util;
import railo.runtime.op.Caster;
import railo.runtime.type.Struct;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.scope.ScopeContext;
/**
* client scope that store it's data in a datasource
*/
public abstract class StorageScopeCache extends StorageScopeImpl {
private static final long serialVersionUID = 6234854552927320080L;
public static final long SAVE_EXPIRES_OFFSET = 60*60*1000;
//private static ScriptConverter serializer=new ScriptConverter();
//boolean structOk;
private final String cacheName;
private final String appName;
private final String cfid;
/**
* Constructor of the class
* @param pc
* @param name
* @param sct
* @param b
*/
protected StorageScopeCache(PageContext pc,String cacheName, String appName,String strType,int type,Struct sct) {
// !!! do not store the pagecontext or config object, this object is Serializable !!!
super(
sct,
doNowIfNull(pc.getConfig(),Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)),
doNowIfNull(pc.getConfig(),Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)),
-1,
type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):1
,strType,type);
//this.isNew=isNew;
this.appName=appName;
this.cacheName=cacheName;
this.cfid=pc.getCFID();
}
/**
* Constructor of the class, clone existing
* @param other
*/
protected StorageScopeCache(StorageScopeCache other,boolean deepCopy) {
super(other,deepCopy);
this.appName=other.appName;
this.cacheName=other.cacheName;
this.cfid=other.cfid;
}
private static DateTime doNowIfNull(Config config,DateTime dt) {
if(dt==null)return new DateTimeImpl(config);
return dt;
}
@Override
public void touchAfterRequest(PageContext pc) {
setTimeSpan(pc);
super.touchAfterRequest(pc);
//if(super.hasContent())
store(pc.getConfig());
}
@Override
public String getStorageType() {
return "Cache";
}
@Override
public void touchBeforeRequest(PageContext pc) {
setTimeSpan(pc);
super.touchBeforeRequest(pc);
}
protected static Struct _loadData(PageContext pc, String cacheName, String appName, String strType, Log log) throws PageException {
Cache cache = getCache(pc.getConfig(),cacheName);
String key=getKey(pc.getCFID(),appName,strType);
Struct s = (Struct) cache.getValue(key,null);
if(s!=null)
ScopeContext.info(log,"load existing data from cache ["+cacheName+"] to create "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID());
else
ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()+" in cache ["+cacheName+"]");
return s;
}
public void store(Config config) {
try {
Cache cache = getCache(config, cacheName);
/*if(cache instanceof CacheEvent) {
CacheEvent ce=(CacheEvent) cache;
ce.register(new SessionEndCacheEvent());
}*/
String key=getKey(cfid, appName, getTypeAsString());
cache.put(key, sct,new Long(getTimeSpan()), null);
}
catch (Exception pe) {}
}
public void unstore(Config config) {
try {
Cache cache = getCache(config, cacheName);
String key=getKey(cfid, appName, getTypeAsString());
cache.remove(key);
}
catch (Exception pe) {}
}
private static Cache getCache(Config config, String cacheName) throws PageException {
try {
CacheConnection cc = Util.getCacheConnection(config,cacheName);
if(!cc.isStorage())
throw new ApplicationException("storage usage for this cache is disabled, you can enable this in the railo administrator.");
return cc.getInstance(config);
} catch (IOException e) {
throw Caster.toPageException(e);
}
}
public static String getKey(String cfid, String appName, String type) {
return new StringBuilder("railo-storage:").append(type).append(":").append(cfid).append(":").append(appName).toString();
}
/*private void setTimeSpan(PageContext pc) {
ApplicationContext ac=(ApplicationContext) pc.getApplicationContext();
timespan = (getType()==SCOPE_CLIENT?ac.getClientTimeout().getMillis():ac.getSessionTimeout().getMillis())+(expiresControlFromOutside?SAVE_EXPIRES_OFFSET:0L);
}*/
}