package com.nutiteq.cache; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.content.Context; import com.nutiteq.log.Log; import com.nutiteq.utils.IOUtils; public class AndroidFileSystemCache implements Cache { private final String caheName; private final File cacheDir; private final int cacheSize; private final Context ctx; private final CacheIndexDatabaseHelper database; public AndroidFileSystemCache(final Context ctx, final String caheName, final File cacheDir, final int cacheSize) { this.ctx = ctx; this.caheName = caheName; this.cacheDir = cacheDir; this.cacheSize = cacheSize; database = new CacheIndexDatabaseHelper(ctx, caheName); } public void cache(final String cacheKey, final byte[] data, final int cacheLevel) { if ((cacheLevel & Cache.CACHE_LEVEL_PERSISTENT) == 0) { return; } Log.debug("Cache " + cacheKey + " : " + data.length); final String cacheableKey = normalizeKey(cacheKey); Log.debug("Cache key would be: " + cacheableKey); final File cacheFile = new File(cacheDir, cacheableKey); cacheFile.getParentFile().mkdirs(); FileOutputStream fos = null; final List<String> deletedFiles = new ArrayList<String>(); try { fos = new FileOutputStream(cacheFile); fos.write(data); deletedFiles.addAll(database.addToIndex(cacheKey, cacheableKey, data.length, cacheSize)); deleteFilesFromFileSystem(deletedFiles); } catch (final IOException e) { Log.error("Error writing " + cacheableKey); Log.printStackTrace(e); } finally { IOUtils.closeStream(fos); } } private void deleteFilesFromFileSystem(final List<String> deletedFiles) { for (final String file : deletedFiles) { final File deleted = new File(cacheDir, file); Log.debug("Deleting " + deleted.getAbsolutePath()); if (!deleted.delete()) { Log.debug("No success"); } } } private String normalizeKey(final String cacheKey) { return cacheKey.replaceAll("://", "_").replaceAll("[^a-zA-Z\\d/]", "_"); } public boolean contains(final String cacheKey) { final boolean containsKey = database.containsKey(cacheKey); Log.debug("Contains 1 " + cacheKey + " : " + containsKey); return containsKey; } public boolean contains(final String cacheKey, final int cacheLevel) { final boolean contains = cacheLevel == Cache.CACHE_LEVEL_PERSISTENT && contains(cacheKey); //Log.debug("Contains 2 " + cacheKey + " : " + contains); return contains; } public void deinitialize() { database.close(); } public byte[] get(final String cacheKey) { Log.debug("cache load " + cacheKey); final String fileName = database.getRespourcePathForKey(cacheKey); if ("".equals(fileName)) { return null; } final File resource = new File(cacheDir, fileName); FileInputStream fis; try { fis = new FileInputStream(resource); return IOUtils.readFullyAndClose(fis); } catch (final FileNotFoundException e) { Log.printStackTrace(e); Log.debug("Could not load " + cacheKey); return null; } } public void initialize() { Log.debug("ZZZZZZZZZZZZZZZZZZZZZZZZZ Initialize fs cache"); database.open(); } }