package railo.runtime.type.scope.storage;
import java.util.Date;
import railo.commons.io.log.Log;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContext;
import railo.runtime.converter.ScriptConverter;
import railo.runtime.interpreter.CFMLExpressionInterpreter;
import railo.runtime.listener.ApplicationContext;
import railo.runtime.op.Caster;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.dt.TimeSpan;
import railo.runtime.type.scope.Cookie;
import railo.runtime.type.scope.ScopeContext;
import railo.runtime.type.util.KeyConstants;
/**
* client scope that store it's data in the cookie of the client
*/
public abstract class StorageScopeCookie extends StorageScopeImpl {
private static final long serialVersionUID = -3509170569488448183L;
private static ScriptConverter serializer=new ScriptConverter();
protected static CFMLExpressionInterpreter evaluator=new CFMLExpressionInterpreter();
//private Cookie cookie;
private String cookieName;
//private TimeSpan timeout;
static {
ignoreSet.add(KeyConstants._cfid);
ignoreSet.add(KeyConstants._cftoken);
ignoreSet.add(KeyConstants._urltoken);
ignoreSet.add(KeyConstants._lastvisit);
ignoreSet.add(KeyConstants._hitcount);
ignoreSet.add(KeyConstants._timecreated);
}
/**
* Constructor of the class
* @param pc
* @param name
* @param sct
*/
protected StorageScopeCookie(PageContext pc,String cookieName,String strType,int type,Struct sct) {
super(
sct,
doNowIfNull(pc,Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)),
doNowIfNull(pc,Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)),
-1,
type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):0,
strType,type);
this.cookieName=cookieName;
}
/**
* Constructor of the class, clone existing
* @param other
*/
protected StorageScopeCookie(StorageScopeCookie other,boolean deepCopy) {
super(other,deepCopy);
cookieName=other.cookieName;
}
private static DateTime doNowIfNull(PageContext pc,DateTime dt) {
if(dt==null)return new DateTimeImpl(pc.getConfig());
return dt;
}
public void touchAfterRequest(PageContext pc) {
boolean _isInit=isinit;
super.touchAfterRequest(pc);
if(!_isInit) return;
ApplicationContext ac=pc.getApplicationContext();
TimeSpan timespan=(getType()==SCOPE_CLIENT)?ac.getClientTimeout():ac.getSessionTimeout();
Cookie cookie = pc.cookieScope();
Date exp = new DateTimeImpl(pc,System.currentTimeMillis()+timespan.getMillis(),true);
try {
String ser=serializer.serializeStruct(sct, ignoreSet);
if(hasChanges()){
cookie.setCookie(KeyImpl.init(cookieName), ser,exp, false, "/", null);
}
cookie.setCookie(KeyImpl.init(cookieName+"_LV"), Caster.toString(_lastvisit.getTime()), exp, false, "/", null);
if(getType()==SCOPE_CLIENT){
cookie.setCookie(KeyImpl.init(cookieName+"_TC"), Caster.toString(timecreated.getTime()),exp, false, "/", null);
cookie.setCookie(KeyImpl.init(cookieName+"_HC"), Caster.toString(sct.get(HITCOUNT,"")), exp, false, "/", null);
}
}
catch (Throwable t) {}
}
@Override
public String getStorageType() {
return "Cookie";
}
protected static Struct _loadData(PageContext pc, String cookieName, int type,String strType, Log log) {
String data = (String)pc.cookieScope().get(cookieName,null);
if(data!=null) {
try {
Struct sct = (Struct) evaluator.interpret(pc,data);
long l;
String str;
// last visit
str = (String)pc.cookieScope().get(cookieName+"_LV",null);
if(!StringUtil.isEmpty(str)) {
l=Caster.toLongValue(str,0);
if(l>0)sct.setEL(LASTVISIT, new DateTimeImpl(pc,l,true));
}
if(type==SCOPE_CLIENT){
// hit count
str= (String)pc.cookieScope().get(cookieName+"_HC",null);
if(!StringUtil.isEmpty(str)) sct.setEL(HITCOUNT, Caster.toDouble(str,null));
// time created
str = (String)pc.cookieScope().get(cookieName+"_TC",null);
if(!StringUtil.isEmpty(str)) {
l=Caster.toLongValue(str,0);
if(l>0)sct.setEL(TIMECREATED, new DateTimeImpl(pc,l,true));
}
}
ScopeContext.info(log,"load data from cookie for "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID());
return sct;
}
catch (Exception e) {
}
}
ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID());
return new StructImpl();
}
protected static boolean has(PageContext pc, String cookieName, int type,String strType) {
// TODO better impl
String data = (String)pc.cookieScope().get(cookieName,null);
return data!=null;
}
}