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