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.ApplicationContextPro;
011    import railo.runtime.op.Caster;
012    import railo.runtime.type.Struct;
013    import railo.runtime.type.StructImpl;
014    import railo.runtime.type.dt.DateTime;
015    import railo.runtime.type.dt.DateTimeImpl;
016    import railo.runtime.type.dt.TimeSpan;
017    import railo.runtime.type.scope.Cookie;
018    import railo.runtime.type.scope.ScopeContext;
019    
020    /**
021     * client scope that store it's data in the cookie of the client
022     */
023    public abstract class StorageScopeCookie extends StorageScopeImpl {
024    
025            private static final long serialVersionUID = -3509170569488448183L;
026            
027            private static ScriptConverter serializer=new ScriptConverter();
028            protected static CFMLExpressionInterpreter evaluator=new CFMLExpressionInterpreter();
029            //private Cookie cookie;
030            private String cookieName;
031    
032            //private TimeSpan timeout;
033            
034            
035            static {
036                    ignoreSet.add("cfid");
037                    ignoreSet.add("cftoken");
038                    ignoreSet.add("urltoken");
039                    ignoreSet.add("lastvisit");
040                    ignoreSet.add("hitcount");
041                    ignoreSet.add("timecreated");
042            }
043            
044    
045            
046            /**
047             * Constructor of the class
048             * @param pc
049             * @param name
050             * @param sct
051             */
052            protected StorageScopeCookie(PageContext pc,String cookieName,String strType,int type,Struct sct) {
053                    super(
054                                    sct,
055                                    type==SCOPE_CLIENT?doNowIfNull(pc,Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)):null,
056                                    doNowIfNull(pc,Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)),
057                                    -1,
058                                    type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):0,
059                                    strType,type);
060                    this.cookieName=cookieName;     
061            }
062    
063            /**
064             * Constructor of the class, clone existing
065             * @param other
066             */
067            protected StorageScopeCookie(StorageScopeCookie other,boolean deepCopy) {
068                    super(other,deepCopy);
069                    cookieName=other.cookieName;
070            }
071            
072            private static DateTime doNowIfNull(PageContext pc,DateTime dt) {
073                    if(dt==null)return new DateTimeImpl(pc.getConfig());
074                    return dt;
075            }
076            
077            public void touchAfterRequest(PageContext pc) {
078                    boolean _isInit=isinit;
079                    super.touchAfterRequest(pc);
080                    if(!_isInit) return;
081                    
082                    ApplicationContextPro ac=(ApplicationContextPro) pc.getApplicationContext();
083                    TimeSpan timespan=(getType()==SCOPE_CLIENT)?ac.getClientTimeout():ac.getSessionTimeout();
084                    Cookie cookie = pc.cookieScope();
085                    
086                    
087                    Date exp = new DateTimeImpl(pc,System.currentTimeMillis()+timespan.getMillis(),true);
088                    try {
089                            String ser=serializer.serializeStruct(sct, ignoreSet);
090                            if(hasChanges()){
091                                    cookie.setCookie(cookieName, ser,exp, false, "/", null);
092                            }
093                            cookie.setCookie(cookieName+"_LV", Caster.toString(_lastvisit.getTime()), exp, false, "/", null);
094                            
095                            if(getType()==SCOPE_CLIENT){
096                                    cookie.setCookie(cookieName+"_TC", Caster.toString(timecreated.getTime()),exp, false, "/", null);
097                                    cookie.setCookie(cookieName+"_HC", Caster.toString(sct.get(HITCOUNT,"")), exp, false, "/", null);
098                            }
099                            
100                    } 
101                    catch (Throwable t) {}
102            }
103            
104            /**
105             * @see railo.runtime.type.scope.storage.StorageScope#getStorageType()
106             */
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    }