| 1 | <!----------------------------------------------------------------------- |
|---|
| 2 | ******************************************************************************** |
|---|
| 3 | Copyright 2005-2008 ColdBox Framework by Luis Majano and Ortus Solutions, Corp |
|---|
| 4 | www.coldboxframework.com | www.luismajano.com | www.ortussolutions.com |
|---|
| 5 | ******************************************************************************** |
|---|
| 6 | |
|---|
| 7 | Author : Luis Majano |
|---|
| 8 | Date : January 18, 2007 |
|---|
| 9 | Description : |
|---|
| 10 | This is an object cache pool. |
|---|
| 11 | |
|---|
| 12 | Modification History: |
|---|
| 13 | 01/18/2007 - Created |
|---|
| 14 | -----------------------------------------------------------------------> |
|---|
| 15 | <cfcomponent name="ObjectPool" hint="I manage persistance for objects." output="false"> |
|---|
| 16 | |
|---|
| 17 | <!------------------------------------------- CONSTRUCTOR -------------------------------------------> |
|---|
| 18 | |
|---|
| 19 | <cffunction name="init" access="public" output="false" returntype="ObjectPool" hint="Constructor"> |
|---|
| 20 | <cfscript> |
|---|
| 21 | var Collections = createObject("java", "java.util.Collections"); |
|---|
| 22 | /* Create the reference maps */ |
|---|
| 23 | var Map = CreateObject("java","java.util.HashMap").init(); |
|---|
| 24 | var MetadataMap = CreateObject("java","java.util.HashMap").init(); |
|---|
| 25 | var SoftRefKeyMap = CreateObject("java","java.util.HashMap").init(); |
|---|
| 26 | |
|---|
| 27 | /* Prepare instance */ |
|---|
| 28 | variables.instance = structnew(); |
|---|
| 29 | |
|---|
| 30 | /* Instantiate object pools */ |
|---|
| 31 | setpool( Collections.synchronizedMap( Map ) ); |
|---|
| 32 | setpool_metadata( Collections.synchronizedMap( MetadataMap ) ); |
|---|
| 33 | setSoftRefKeyMap( Collections.synchronizedMap(SoftRefKeyMap) ); |
|---|
| 34 | |
|---|
| 35 | /* Register the reference queue for our soft references */ |
|---|
| 36 | setReferenceQueue( CreateObject("java","java.lang.ref.ReferenceQueue").init() ); |
|---|
| 37 | |
|---|
| 38 | /* Return pool */ |
|---|
| 39 | return this; |
|---|
| 40 | </cfscript> |
|---|
| 41 | </cffunction> |
|---|
| 42 | |
|---|
| 43 | <!------------------------------------------- PUBLIC -------------------------------------------> |
|---|
| 44 | |
|---|
| 45 | <!--- Get/Set the Ref Queue ---> |
|---|
| 46 | <cffunction name="getReferenceQueue" access="public" output="false" returntype="any" hint="Get ReferenceQueue"> |
|---|
| 47 | <cfreturn instance.ReferenceQueue/> |
|---|
| 48 | </cffunction> |
|---|
| 49 | |
|---|
| 50 | <!--- Get/Set Soft Reference KeyMap ---> |
|---|
| 51 | <cffunction name="getSoftRefKeyMap" access="public" output="false" returntype="any" hint="Get SoftRefKeyMap"> |
|---|
| 52 | <cfreturn instance.SoftRefKeyMap/> |
|---|
| 53 | </cffunction> |
|---|
| 54 | |
|---|
| 55 | <!--- Check if the soft reference exists ---> |
|---|
| 56 | <cffunction name="softRefLookup" access="public" returntype="boolean" hint="See if the soft reference is in the key map" output="false" > |
|---|
| 57 | <cfargument name="softRef" required="true" type="any" hint="The soft reference to check"> |
|---|
| 58 | <cfreturn structKeyExists(getSoftRefKeyMap(),arguments.softRef)> |
|---|
| 59 | </cffunction> |
|---|
| 60 | |
|---|
| 61 | <!--- Get the ref key ---> |
|---|
| 62 | <cffunction name="getSoftRefKey" access="public" returntype="any" hint="Get the soft reference's key from the soft reference lookback map" output="false" > |
|---|
| 63 | <cfargument name="softRef" required="true" type="any" hint="The soft reference to check"> |
|---|
| 64 | <cfscript> |
|---|
| 65 | var keyMap = getSoftRefKeyMap(); |
|---|
| 66 | if( structKeyExists(keyMap,arguments.softRef) ){ |
|---|
| 67 | return keyMap[arguments.softRef]; |
|---|
| 68 | } |
|---|
| 69 | else{ |
|---|
| 70 | return "NOT_FOUND"; |
|---|
| 71 | } |
|---|
| 72 | </cfscript> |
|---|
| 73 | </cffunction> |
|---|
| 74 | |
|---|
| 75 | <!--- Getter/Setter For pool ---> |
|---|
| 76 | <cffunction name="getpool" access="public" returntype="any" output="false" hint="Get the cache pool"> |
|---|
| 77 | <cfreturn instance.pool> |
|---|
| 78 | </cffunction> |
|---|
| 79 | |
|---|
| 80 | <!--- Getter/Setter for Pool Metdata ---> |
|---|
| 81 | <cffunction name="getpool_metadata" access="public" returntype="any" output="false" hint="Get the cache pool metadata"> |
|---|
| 82 | <cfreturn instance.pool_metadata > |
|---|
| 83 | </cffunction> |
|---|
| 84 | |
|---|
| 85 | <!--- Setter/Getter metdata property ---> |
|---|
| 86 | <cffunction name="getObjectMetadata" access="public" returntype="any" output="false" hint="Get a metadata entry for a specific cache entry"> |
|---|
| 87 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 88 | <cfreturn instance.pool_metadata[arguments.objectKey] > |
|---|
| 89 | </cffunction> |
|---|
| 90 | <cffunction name="setObjectMetadata" access="public" returntype="void" output="false" hint="Set the metadata entry for a specific cache entry"> |
|---|
| 91 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 92 | <cfargument name="metadata" type="any" required="true"> |
|---|
| 93 | <cfset instance.pool_metadata[arguments.objectKey] = arguments.metadata> |
|---|
| 94 | </cffunction> |
|---|
| 95 | <cffunction name="getMetadataProperty" access="public" returntype="any" output="false" hint="Get a metadata property for a specific cache entry"> |
|---|
| 96 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 97 | <cfargument name="property" type="any" required="true"> |
|---|
| 98 | <cfreturn instance.pool_metadata[arguments.objectKey][arguments.property] > |
|---|
| 99 | </cffunction> |
|---|
| 100 | <cffunction name="setMetadataProperty" access="public" returntype="void" output="false" hint="Set a metadata property for a specific cache entry"> |
|---|
| 101 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 102 | <cfargument name="property" type="any" required="true"> |
|---|
| 103 | <cfargument name="value" type="any" required="true"> |
|---|
| 104 | <cfset instance.pool_metadata[arguments.objectKey][arguments.property] = arguments.value > |
|---|
| 105 | </cffunction> |
|---|
| 106 | |
|---|
| 107 | <!--- Simple Object Lookup ---> |
|---|
| 108 | <cffunction name="lookup" access="public" output="false" returntype="boolean" hint="Check if an object is in cache, it doesn't tell you if the soft reference expired or not"> |
|---|
| 109 | <!--- ************************************************************* ---> |
|---|
| 110 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 111 | <!--- ************************************************************* ---> |
|---|
| 112 | <!--- Check for Object in Cache. ---> |
|---|
| 113 | <cfreturn structKeyExists(instance.pool, arguments.objectKey) > |
|---|
| 114 | </cffunction> |
|---|
| 115 | |
|---|
| 116 | <!--- Get an object from the pool ---> |
|---|
| 117 | <cffunction name="get" access="public" output="false" returntype="any" hint="Get an object from cache. If its a soft reference object it might return a null value."> |
|---|
| 118 | <!--- ************************************************************* ---> |
|---|
| 119 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 120 | <!--- ************************************************************* ---> |
|---|
| 121 | <cfscript> |
|---|
| 122 | var tmpObj = 0; |
|---|
| 123 | |
|---|
| 124 | /* Record Metadata Access */ |
|---|
| 125 | setMetadataProperty(arguments.objectKey,"hits", getMetaDataProperty(arguments.objectKey,"hits")+1); |
|---|
| 126 | setMetadataProperty(arguments.objectKey,"lastAccesed", now()); |
|---|
| 127 | |
|---|
| 128 | /* Get Object */ |
|---|
| 129 | tmpObj = instance.pool[arguments.objectKey]; |
|---|
| 130 | |
|---|
| 131 | /* Validate if SR or eternal */ |
|---|
| 132 | if( isSoftReference(tmpObj) ){ |
|---|
| 133 | return tmpObj.get(); |
|---|
| 134 | } |
|---|
| 135 | else{ |
|---|
| 136 | return tmpObj; |
|---|
| 137 | } |
|---|
| 138 | </cfscript> |
|---|
| 139 | </cffunction> |
|---|
| 140 | |
|---|
| 141 | <!--- Set an Object in the pool ---> |
|---|
| 142 | <cffunction name="set" access="public" output="false" returntype="void" hint="sets an object in cache."> |
|---|
| 143 | <!--- ************************************************************* ---> |
|---|
| 144 | <cfargument name="objectKey" type="any" required="true"> |
|---|
| 145 | <cfargument name="MyObject" type="any" required="true"> |
|---|
| 146 | <cfargument name="Timeout" type="any" required="false" default="" hint="Timeout in minutes. If timeout = 0 then object never times out. If timeout is blank, then timeout will be inherited from framework."> |
|---|
| 147 | <cfargument name="LastAccessTimeout" type="any" required="false" default="" hint="Timeout in minutes. If timeout is blank, then timeout will be inherited from framework."> |
|---|
| 148 | <!--- ************************************************************* ---> |
|---|
| 149 | <cfscript> |
|---|
| 150 | var MetaData = structnew(); |
|---|
| 151 | var targetObj = 0; |
|---|
| 152 | |
|---|
| 153 | /* Check for eternal object */ |
|---|
| 154 | if( arguments.timeout neq 0 ){ |
|---|
| 155 | /* Cache as soft reference not an eternal object */ |
|---|
| 156 | targetObj = createSoftReference(arguments.objectKey,arguments.MyObject); |
|---|
| 157 | } |
|---|
| 158 | else{ |
|---|
| 159 | targetObj = arguments.MyObject; |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | /* Set new Object into cache pool */ |
|---|
| 163 | instance.pool[arguments.objectKey] = targetObj; |
|---|
| 164 | |
|---|
| 165 | /* Create object's metdata */ |
|---|
| 166 | MetaData.hits = 1; |
|---|
| 167 | MetaData.Timeout = arguments.timeout; |
|---|
| 168 | MetaData.LastAccessTimeout = arguments.LastAccessTimeout; |
|---|
| 169 | MetaData.Created = now(); |
|---|
| 170 | MetaData.LastAccesed = now(); |
|---|
| 171 | |
|---|
| 172 | /* Save the metadata */ |
|---|
| 173 | setObjectMetaData(arguments.objectkey,MetaData); |
|---|
| 174 | </cfscript> |
|---|
| 175 | </cffunction> |
|---|
| 176 | |
|---|
| 177 | <!--- Clear an object from the pool ---> |
|---|
| 178 | <cffunction name="clearKey" access="public" output="false" returntype="boolean" hint="Clears a key from the cache."> |
|---|
| 179 | <!--- ************************************************************* ---> |
|---|
| 180 | <cfargument name="objectKey" type="string" required="true"> |
|---|
| 181 | <!--- ************************************************************* ---> |
|---|
| 182 | <cfscript> |
|---|
| 183 | var Results = false; |
|---|
| 184 | var softRef = ""; |
|---|
| 185 | |
|---|
| 186 | try{ |
|---|
| 187 | /* Is this a soft Ref */ |
|---|
| 188 | softRef = instance.pool[arguments.objectKey]; |
|---|
| 189 | /* Removal of Soft Ref Lookup */ |
|---|
| 190 | if( isSoftReference(softRef) ){ |
|---|
| 191 | structDelete(getSoftRefKeyMap(),softRef); |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | /* Remove Normal Cache Entries */ |
|---|
| 195 | structDelete(getPool(),arguments.objectKey); |
|---|
| 196 | structDelete(getpool_metadata(),arguments.objectKey); |
|---|
| 197 | |
|---|
| 198 | /* Removed */ |
|---|
| 199 | Results = true; |
|---|
| 200 | } |
|---|
| 201 | catch(Any e){ |
|---|
| 202 | //Nothing; |
|---|
| 203 | } |
|---|
| 204 | return Results; |
|---|
| 205 | </cfscript> |
|---|
| 206 | </cffunction> |
|---|
| 207 | |
|---|
| 208 | <!--- Get the size of the pool ---> |
|---|
| 209 | <cffunction name="getSize" access="public" output="false" returntype="numeric" hint="Get the cache's size in items"> |
|---|
| 210 | <cfreturn StructCount(getPool())> |
|---|
| 211 | </cffunction> |
|---|
| 212 | |
|---|
| 213 | <!--- Get the itemList ---> |
|---|
| 214 | <cffunction name="getObjectsKeyList" access="public" output="false" returntype="string" hint="Get the cache's object entries listing."> |
|---|
| 215 | <cfreturn structKeyList(getPool())> |
|---|
| 216 | </cffunction> |
|---|
| 217 | |
|---|
| 218 | <!------------------------------------------- PRIVATE -------------------------------------------> |
|---|
| 219 | |
|---|
| 220 | <!--- Set the pool_metadata ---> |
|---|
| 221 | <cffunction name="setpool_metadata" access="public" returntype="void" output="false" hint="Set the cache pool metadata"> |
|---|
| 222 | <cfargument name="pool_metadata" type="struct" required="true"> |
|---|
| 223 | <cfset instance.pool_metadata = arguments.pool_metadata> |
|---|
| 224 | </cffunction> |
|---|
| 225 | |
|---|
| 226 | <!--- Set the object pool ---> |
|---|
| 227 | <cffunction name="setpool" access="private" returntype="void" output="false" hint="Set the cache pool"> |
|---|
| 228 | <cfargument name="pool" type="struct" required="true"> |
|---|
| 229 | <cfset instance.pool = arguments.pool> |
|---|
| 230 | </cffunction> |
|---|
| 231 | |
|---|
| 232 | <!--- Set the reference queue ---> |
|---|
| 233 | <cffunction name="setReferenceQueue" access="private" output="false" returntype="void" hint="Set ReferenceQueue"> |
|---|
| 234 | <cfargument name="ReferenceQueue" type="any" required="true"/> |
|---|
| 235 | <cfset instance.ReferenceQueue = arguments.ReferenceQueue/> |
|---|
| 236 | </cffunction> |
|---|
| 237 | |
|---|
| 238 | <!--- Set the soft ref key map ---> |
|---|
| 239 | <cffunction name="setSoftRefKeyMap" access="private" output="false" returntype="void" hint="Set SoftRefKeyMap"> |
|---|
| 240 | <cfargument name="SoftRefKeyMap" type="any" required="true"/> |
|---|
| 241 | <cfset instance.SoftRefKeyMap = arguments.SoftRefKeyMap/> |
|---|
| 242 | </cffunction> |
|---|
| 243 | |
|---|
| 244 | <!--- Create a soft referenec ---> |
|---|
| 245 | <cffunction name="createSoftReference" access="private" returntype="any" hint="Create SR, register cached object and reference" output="false" > |
|---|
| 246 | <!--- ************************************************************* ---> |
|---|
| 247 | <cfargument name="objectKey" type="any" required="true" hint="The value of the key pair"> |
|---|
| 248 | <cfargument name="MyObject" type="any" required="true" hint="The object to wrap"> |
|---|
| 249 | <!--- ************************************************************* ---> |
|---|
| 250 | <cfscript> |
|---|
| 251 | /* Create Soft Reference Wrapper and register with Queue */ |
|---|
| 252 | var softRef = CreateObject("java","java.lang.ref.SoftReference").init(arguments.MyObject,getReferenceQueue()); |
|---|
| 253 | var RefKeyMap = getSoftRefKeyMap(); |
|---|
| 254 | |
|---|
| 255 | /* Create Reverse Mapping */ |
|---|
| 256 | RefKeyMap[softRef] = arguments.objectKey; |
|---|
| 257 | |
|---|
| 258 | /* Return object */ |
|---|
| 259 | return softRef; |
|---|
| 260 | </cfscript> |
|---|
| 261 | </cffunction> |
|---|
| 262 | |
|---|
| 263 | <!--- Check if this is a soft referene ---> |
|---|
| 264 | <cffunction name="isSoftReference" access="private" returntype="boolean" hint="Whether the passed object is a soft reference" output="false" > |
|---|
| 265 | <cfargument name="MyObject" type="any" required="true" hint="The object to test"> |
|---|
| 266 | <cfscript> |
|---|
| 267 | if( isObject(arguments.myObject) and getMetaData(arguments.MyObject).name eq "java.lang.ref.SoftReference" ){ |
|---|
| 268 | return true; |
|---|
| 269 | } |
|---|
| 270 | else{ |
|---|
| 271 | return false; |
|---|
| 272 | } |
|---|
| 273 | </cfscript> |
|---|
| 274 | </cffunction> |
|---|
| 275 | |
|---|
| 276 | </cfcomponent> |
|---|