package com.jdroid.android.http.cache;
import android.content.Context;
import com.jdroid.android.application.AbstractApplication;
import com.jdroid.android.application.AppLaunchStatus;
import com.jdroid.java.collections.Lists;
import com.jdroid.java.http.cache.Cache;
import com.jdroid.java.http.cache.CachedHttpService;
import com.jdroid.java.utils.FileUtils;
import com.jdroid.java.utils.LoggerUtils;
import org.slf4j.Logger;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class CacheManager {
private static final Logger LOGGER = LoggerUtils.getLogger(CacheManager.class);
private static final String CACHE_DIRECTORY_PREFIX = "cache_";
public void initFileSystemCache() {
try {
// Sort the caches by priority
List<Cache> caches = getFileSystemCaches();
Collections.sort(caches, new Comparator<Cache>() {
@Override
public int compare(Cache cache1, Cache cache2) {
return cache2.getPriority().compareTo(cache1.getPriority());
}
});
for (Cache cache : caches) {
populateFileSystemCache(cache);
reduceFileSystemCache(cache);
}
} catch (Exception e) {
AbstractApplication.get().getExceptionHandler().logHandledException(e);
}
}
@SuppressWarnings("resource")
public void populateFileSystemCache(Cache cache) {
if (!AbstractApplication.get().getAppLaunchStatus().equals(AppLaunchStatus.NORMAL)) {
Map<String, String> defaultContent = cache.getDefaultContent();
if ((defaultContent != null) && !defaultContent.isEmpty()) {
for (Map.Entry<String, String> entry : defaultContent.entrySet()) {
InputStream source = AbstractApplication.class.getClassLoader().getResourceAsStream(
"cache/" + entry.getKey());
if (source != null) {
File cacheFile = new File(getFileSystemCacheDirectory(cache),
CachedHttpService.generateCacheFileName(entry.getValue()));
FileUtils.copyStream(source, cacheFile);
LOGGER.debug("Populated " + entry.toString() + " to " + cacheFile.getAbsolutePath());
FileUtils.safeClose(source);
}
}
LOGGER.debug(cache.getName() + " cache populated");
}
}
}
public void reduceFileSystemCache(Cache cache) {
if (cache.getMaximumSize() != null) {
File dir = getFileSystemCacheDirectory(cache);
// Verify if the cache should be clean
if ((dir != null) && dir.exists()) {
float dirSize = FileUtils.getDirectorySizeInMB(dir);
LOGGER.info("Cache " + cache.getName() + " size: " + dirSize + " MB");
if (dirSize > cache.getMaximumSize()) {
// Sort the files by modification date, so we remove the not used files first
List<File> files = Lists.newArrayList(dir.listFiles());
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return Long.valueOf(file1.lastModified()).compareTo(file2.lastModified());
}
});
// Remove the file until the minimum size is achieved
for (File file : files) {
if (dirSize > cache.getMinimumSize()) {
dirSize -= FileUtils.getFileSizeInMB(file);
FileUtils.forceDelete(file);
} else {
break;
}
}
}
}
}
}
protected List<Cache> getFileSystemCaches() {
return Lists.newArrayList();
}
public void cleanFileSystemCache() {
for (Cache each : getFileSystemCaches()) {
cleanFileSystemCache(each);
}
}
public void cleanFileSystemCache(Cache cache) {
FileUtils.forceDelete(getFileSystemCacheDirectory(cache));
}
public File getFileSystemCacheDirectory(Cache cache) {
return AbstractApplication.get().getApplicationContext().getDir(CACHE_DIRECTORY_PREFIX + cache.getName(), Context.MODE_PRIVATE);
}
}