package com.m.support.cache;
import java.io.File;
import java.io.Serializable;
import android.text.TextUtils;
import com.alibaba.fastjson.JSON;
import com.m.common.context.GlobalContext;
import com.m.common.params.Params;
import com.m.common.settings.Setting;
import com.m.common.settings.SettingUtil;
import com.m.common.settings.SettingUtility;
import com.m.common.utils.DateUtils;
import com.m.common.utils.FileUtility;
import com.m.common.utils.KeyGenerator;
import com.m.common.utils.Logger;
import com.m.common.utils.ObjectUtil;
import com.m.common.utils.SystemUtility;
import com.m.support.sqlite.SqliteUtility;
import com.m.support.sqlite.annotation.Id;
import com.m.support.sqlite.property.Extra;
/**
* 2013-12-24--->在不影响中行上线版本的基础上,将文件有效期写入db
*
* @author wangdan
*
*/
public class FileCacheUtility implements ICacheUtility {
private static final String TAG = FileCacheUtility.class.getSimpleName();
private final String cachePath;// sdcard可用,就使用配置路径,否则使用程序缓存目录
private static FileCacheManager cacheManager;
public FileCacheUtility() {
if (SystemUtility.hasSdcardAndCanWrite()) {
cachePath = SystemUtility.getSdcardPath() + File.separator + SettingUtility.getStringSetting("root_path") + File.separator
+ SettingUtility.getPermanentSettingAsStr("com_m_common_json", "json");
} else {
cachePath = GlobalContext.getInstance().getCacheDir().getAbsolutePath() + File.separator
+ SettingUtility.getPermanentSettingAsStr("com_m_common_json", "json");
}
if (cacheManager == null)
cacheManager = new FileCacheManager(cachePath);
}
@Override
public <T> Cache<T> findCacheData(Setting actionSetting, Params params, Class<T> responseCls) {
// 重置参数
if (params != null) {
params = ObjectUtil.cloneObject(params);
params.remove("mac");
}
String action = actionSetting.getValue();
String key = KeyGenerator.generateMD5(action, params);
T data = null;
File file = cacheManager.get(key);
if (file != null && file.exists()) {
String readContent = FileUtility.readFileToString(file);
if (!TextUtils.isEmpty(readContent))
data = JSON.parseObject(readContent, responseCls);
} else {
Logger.v(TAG, String.format("key=%s has not cache file", key));
}
if (data != null) {
// 默认缓存未过期
boolean isDue = false;
CacheTime cacheTime = SqliteUtility.getInstance().selectById(new Extra(key), CacheTime.class);
Logger.w(TAG, cacheTime);
if (cacheTime != null) {
long currentTime = System.currentTimeMillis();
long saveTime = cacheTime.getTime();
long validTime = SettingUtil.getValidTime(actionSetting);
if (validTime != Integer.MAX_VALUE)
validTime = validTime * 1000;
Logger.d(
TAG,
String.format("缓存保存时间为%s,当前时间为%s, 缓存有效时间为%s秒", DateUtils.formatDate(saveTime, DateUtils.TYPE_01),
DateUtils.formatDate(currentTime, DateUtils.TYPE_01), validTime / 1000));
isDue = currentTime < saveTime + validTime ? false : true;
} else {
SqliteUtility.getInstance().insert(null, new CacheTime(key, System.currentTimeMillis()));
}
return new Cache<T>(data, isDue);
}
return null;
}
@Override
public void addCacheData(Setting actionSetting, Params params, Object responseObj) {
if (params != null) {
params = ObjectUtil.cloneObject(params);
params.remove("mac");
}
String action = actionSetting.getValue();
String key = KeyGenerator.generateMD5(action, params);
if (!cacheManager.add(key, responseObj)) {
cacheManager.delete(actionSetting, params);
} else {
// 更新缓存保存时间
CacheTime cacheTime = new CacheTime();
cacheTime.setKey(key);
cacheTime.setTime(System.currentTimeMillis());
SqliteUtility.getInstance().insert(null, cacheTime);
}
}
private static class FileCacheManager {
private final String cacheDir;
private final String fileHz = "";
FileCacheManager(String cacheDir) {
this.cacheDir = cacheDir;
Logger.v(TAG, String.format("FileCacheDir's path = %s", cacheDir));
File rootFile = new File(cacheDir);
if (!rootFile.exists())
rootFile.mkdirs();
// calculateCacheSize();
}
// private void calculateCacheSize() {
// new Thread(new Runnable() {
// @Override
// public void run() {
// File[] cachedFiles = cacheDir.listFiles();
// if (cachedFiles != null) {
// for (File cachedFile : cachedFiles) {
// if (cachedFile.getName().indexOf(fileHz) == -1 || cachedFile.isDirectory())
// continue;
//
// Logger.i(TAG, cachedFile.getAbsolutePath());
//
// cacheFiles.put(getFileRealName(cachedFile), cachedFile);
// }
// }
// }
// }).start();
// }
private File newFile(String key) {
String fileName = key + fileHz;
Logger.d(TAG, String.format("add file to cache, key=%s, fileName=%s", key, fileName));
File file = new File(cacheDir + File.separator + fileName);
return file;
}
private File getFile(String key) {
String fileName = key + fileHz;
File file = new File(cacheDir + File.separator + fileName);
if (file.exists()) {
Logger.d(TAG, String.format("load file, key=%s, fileName=%s", key, fileName));
return file;
}
return null;
}
public File get(String key) {
return getFile(key);
}
/**
*
* @param key
* @param data
* @return false-保存失败
*/
public boolean add(String key, Object data) {
File file = newFile(key);
return FileUtility.writeFile(file, JSON.toJSONString(data));
}
public void delete(Setting setting, Params params) {
// 重置参数
params = ObjectUtil.cloneObject(params);
params.remove("mac");
String action = setting.getValue();
String key = KeyGenerator.generateMD5(action, params);
File file = getFile(key);
try {
file.delete();
SqliteUtility.getInstance().delete(null, CacheTime.class, key);
} catch (Exception e) {
}
}
}
public static class CacheTime implements Serializable {
private static final long serialVersionUID = 5651724383844501761L;
@Id(column = "id")
private String key;
private long time;
public CacheTime() {
}
public CacheTime(String key, long time) {
this.key = key;
this.time = time;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
}
}