001    package railo.runtime.type.scope.storage;
002    
003    import java.util.Date;
004    
005    import railo.commons.io.log.Log;
006    import railo.commons.lang.StringUtil;
007    import railo.runtime.PageContext;
008    import railo.runtime.converter.ScriptConverter;
009    import railo.runtime.interpreter.CFMLExpressionInterpreter;
010    import railo.runtime.listener.ApplicationContext;
011    import railo.runtime.op.Caster;
012    import railo.runtime.type.KeyImpl;
013    import railo.runtime.type.Struct;
014    import railo.runtime.type.StructImpl;
015    import railo.runtime.type.dt.DateTime;
016    import railo.runtime.type.dt.DateTimeImpl;
017    import railo.runtime.type.dt.TimeSpan;
018    import railo.runtime.type.scope.Cookie;
019    import railo.runtime.type.scope.ScopeContext;
020    import railo.runtime.type.util.KeyConstants;
021    
022    /**
023     * client scope that store it's data in the cookie of the client
024     */
025    public abstract class StorageScopeCookie extends StorageScopeImpl {
026    
027            private static final long serialVersionUID = -3509170569488448183L;
028            
029            private static ScriptConverter serializer=new ScriptConverter();
030            protected static CFMLExpressionInterpreter evaluator=new CFMLExpressionInterpreter();
031            //private Cookie cookie;
032            private String cookieName;
033    
034            //private TimeSpan timeout;
035            
036            
037            static {
038                    ignoreSet.add(KeyConstants._cfid);
039                    ignoreSet.add(KeyConstants._cftoken);
040                    ignoreSet.add(KeyConstants._urltoken);
041                    ignoreSet.add(KeyConstants._lastvisit);
042                    ignoreSet.add(KeyConstants._hitcount);
043                    ignoreSet.add(KeyConstants._timecreated);
044            }
045            
046    
047            
048            /**
049             * Constructor of the class
050             * @param pc
051             * @param name
052             * @param sct
053             */
054            protected StorageScopeCookie(PageContext pc,String cookieName,String strType,int type,Struct sct) {
055                    super(
056                                    sct,
057                                    doNowIfNull(pc,Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)),
058                                    doNowIfNull(pc,Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)),
059                                    -1,
060                                    type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):0,
061                                    strType,type);
062                    this.cookieName=cookieName;     
063            }
064    
065            /**
066             * Constructor of the class, clone existing
067             * @param other
068             */
069            protected StorageScopeCookie(StorageScopeCookie other,boolean deepCopy) {
070                    super(other,deepCopy);
071                    cookieName=other.cookieName;
072            }
073            
074            private static DateTime doNowIfNull(PageContext pc,DateTime dt) {
075                    if(dt==null)return new DateTimeImpl(pc.getConfig());
076                    return dt;
077            }
078            
079            public void touchAfterRequest(PageContext pc) {
080                    boolean _isInit=isinit;
081                    super.touchAfterRequest(pc);
082                    if(!_isInit) return;
083                    
084                    ApplicationContext ac=pc.getApplicationContext();
085                    TimeSpan timespan=(getType()==SCOPE_CLIENT)?ac.getClientTimeout():ac.getSessionTimeout();
086                    Cookie cookie = pc.cookieScope();
087                    
088                    
089                    Date exp = new DateTimeImpl(pc,System.currentTimeMillis()+timespan.getMillis(),true);
090                    try {
091                            String ser=serializer.serializeStruct(sct, ignoreSet);
092                            if(hasChanges()){
093                                    cookie.setCookie(KeyImpl.init(cookieName), ser,exp, false, "/", null);
094                            }
095                            cookie.setCookie(KeyImpl.init(cookieName+"_LV"), Caster.toString(_lastvisit.getTime()), exp, false, "/", null);
096                            
097                            if(getType()==SCOPE_CLIENT){
098                                    cookie.setCookie(KeyImpl.init(cookieName+"_TC"), Caster.toString(timecreated.getTime()),exp, false, "/", null);
099                                    cookie.setCookie(KeyImpl.init(cookieName+"_HC"), Caster.toString(sct.get(HITCOUNT,"")), exp, false, "/", null);
100                            }
101                            
102                    } 
103                    catch (Throwable t) {}
104            }
105            
106            @Override
107            public String getStorageType() {
108                    return "Cookie";
109            }
110    
111    
112            protected static Struct _loadData(PageContext pc, String cookieName, int type,String strType, Log log) {
113                    String data = (String)pc.cookieScope().get(cookieName,null);
114                    if(data!=null) {                        
115                            try {
116                                    Struct sct = (Struct) evaluator.interpret(pc,data);
117                                    long l;
118                                    String str;
119                                    
120                                    // last visit
121                                    str = (String)pc.cookieScope().get(cookieName+"_LV",null);
122                                    if(!StringUtil.isEmpty(str)) {
123                                            l=Caster.toLongValue(str,0);
124                                            if(l>0)sct.setEL(LASTVISIT, new DateTimeImpl(pc,l,true));
125                                    }
126                                    
127                                    
128                                    if(type==SCOPE_CLIENT){
129                                            // hit count
130                                            str= (String)pc.cookieScope().get(cookieName+"_HC",null);
131                                                    if(!StringUtil.isEmpty(str)) sct.setEL(HITCOUNT, Caster.toDouble(str,null));
132                                            
133                                            // time created
134                                            str = (String)pc.cookieScope().get(cookieName+"_TC",null);
135                                            if(!StringUtil.isEmpty(str)) {
136                                                    l=Caster.toLongValue(str,0);
137                                                    if(l>0)sct.setEL(TIMECREATED, new DateTimeImpl(pc,l,true));
138                                            }
139                                    }
140                                                                    
141                                    ScopeContext.info(log,"load data from cookie for "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID());
142                                    return sct;
143                            } 
144                            catch (Exception e) {
145                                    
146                            }
147                    }
148                    ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID());
149                    
150                    return new StructImpl();
151            }
152            
153            protected static boolean has(PageContext pc, String cookieName, int type,String strType) {
154                    // TODO better impl
155                    String data = (String)pc.cookieScope().get(cookieName,null);
156                    return data!=null;
157                    
158            }
159    }