/******************************************************************************
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is: Jsoda
* The Initial Developer of the Original Code is: William Wong (williamw520@gmail.com)
* Portions created by William Wong are Copyright (C) 2012 William Wong, All Rights Reserved.
*
******************************************************************************/
package wwutil.jsoda;
import java.io.*;
import java.lang.reflect.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import wwutil.model.MemCacheable;
import wwutil.model.MemCacheableNoop;
import wwutil.model.annotation.CachePolicy;
/**
* Perform the generic object caching work.
*/
class ObjCacheMgr
{
private static Log log = LogFactory.getLog(ObjCacheMgr.class);
private Jsoda jsoda;
private MemCacheable memCacheable;
ObjCacheMgr(Jsoda jsoda, MemCacheable memCacheable) {
this.jsoda = jsoda;
setMemCacheable(memCacheable);
}
void shutdown() {
}
void setMemCacheable(MemCacheable memCacheable) {
if (memCacheable == null)
this.memCacheable = new MemCacheableNoop();
else
this.memCacheable = memCacheable;
}
MemCacheable getMemCacheable() {
return memCacheable;
}
private String makeCachePkKey(String modelName, String pkKey) {
String dbId = jsoda.getDb(modelName).getDbTypeId();
return dbId + "/" + modelName + "/pk/" + pkKey;
}
private String makeCacheFieldKey(String modelName, String fieldName, Object fieldValue) {
String dbId = jsoda.getDb(modelName).getDbTypeId();
String valueStr = DataUtil.encodeValueToAttrStr(fieldValue, jsoda.getField(modelName, fieldName).getType());
return dbId + "/" + modelName + "/" + fieldName + "/" + valueStr;
}
private void cachePutObj(String key, int expireInSeconds, Object dataObj) {
try {
memCacheable.put(key, expireInSeconds, (Serializable)dataObj);
} catch(Exception ignored) {
}
}
// Cache by the primary key (id or id/rangekey)
void cachePut(String modelName, Object dataObj) {
int expireInSeconds = jsoda.getCachePolicy(modelName);
if (expireInSeconds < 0)
return;
try {
String cacheKey = makeCachePkKey(modelName, jsoda.makePkKey(modelName, dataObj));
cachePutObj(cacheKey, expireInSeconds, dataObj);
} catch(Exception ignored) {
}
// Cache by the CacheByFields
for (String fieldName : jsoda.getCacheByFields(modelName)) {
try {
Field field = jsoda.getField(modelName, fieldName);
Object fieldValue = field.get(dataObj);
String key = makeCacheFieldKey(modelName, field.getName(), fieldValue);
cachePutObj(key, expireInSeconds, dataObj);
} catch(Exception ignore) {
}
}
}
void cacheDelete(String modelName, Object idValue, Object rangeValue)
{
Object dataObj = cacheGet(modelName, idValue, rangeValue);
if (dataObj != null) {
for (String fieldName : jsoda.getCacheByFields(modelName)) {
try {
Field field = jsoda.getField(modelName, fieldName);
Object fieldValue = field.get(dataObj);
String key = makeCacheFieldKey(modelName, field.getName(), fieldValue);
memCacheable.delete(key);
} catch(Exception ignored) {
}
}
}
String cacheKey = makeCachePkKey(modelName, jsoda.makePkKey(modelName, idValue, rangeValue));
memCacheable.delete(cacheKey);
}
Object cacheGet(String modelName, Object idValue, Object rangeValue) {
// Cache by the primary key (id or id/rangekey)
String cacheKey = makeCachePkKey(modelName, jsoda.makePkKey(modelName, idValue, rangeValue));
return (Object)memCacheable.get(cacheKey);
}
Object cacheGetByField(String modelName, String fieldName, Object fieldValue) {
return (Object)memCacheable.get(makeCacheFieldKey(modelName, fieldName, fieldValue));
}
}