/* FileCacheController.java Copyright (c) 2014 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.event.cache; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.StreamCorruptedException; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.deviceconnect.android.event.Event; import org.deviceconnect.android.event.EventError; import android.content.Context; /** * イベントデータをファイルに保存し、キャッシュの操作機能を提供する. データはメモリにキャッシュし、flushすることでファイルに書き出す。 * * * @author NTT DOCOMO, INC. */ public class FileCacheController extends MemoryCacheController { /** * コンテキストオブジェクト. ファイル操作に利用する。 */ private Context mContext; /** * キャッシュファイル名. */ private static final String CACHE_FILE_NAME = "org_deviceconnect_android_event_cache.dat"; /** * ロガー. */ private Logger mLogger = Logger.getLogger("org.deviceconnect.dplugin"); /** * 自動フラッシュフラグ. */ private boolean mAutoFlush; /** * 自動フラッシュフラグを指定してFileCacheControllerのインスタンスを生成する. * * @param context コンテキストオブジェクト * @param autoFlush * trueの場合、追加、削除系の操作を行う度に自動でflush()を実行する。 * falseの場合は明示的に呼び出すまでflush()しない。 */ public FileCacheController(final Context context, final boolean autoFlush) { if (context == null) { throw new IllegalArgumentException("Context is null."); } mContext = context; mAutoFlush = autoFlush; load(); } /** * コンテキストを指定してファイルキャッシュコントローラーのインスタンスを生成する. * 自動フラッシュ機能はオフの状態になる。 * * @param context コンテキストオブジェクト */ public FileCacheController(final Context context) { this(context, false); } @Override public synchronized void flush() { FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = mContext.openFileOutput(CACHE_FILE_NAME, Context.MODE_PRIVATE); oos = new ObjectOutputStream(fos); oos.writeObject(getCache()); } catch (FileNotFoundException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } catch (IOException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } finally { try { if (oos != null) { oos.close(); } else if (fos != null) { fos.close(); } } catch (IOException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } } } /** * データをファイルからロードする. */ @SuppressWarnings("unchecked") private void load() { Map<String, Map<String, List<Event>>> cache = null; FileInputStream fis = null; ObjectInputStream ois = null; try { fis = mContext.openFileInput(CACHE_FILE_NAME); ois = new ObjectInputStream(fis); cache = (Map<String, Map<String, List<Event>>>) ois.readObject(); setCache(cache); } catch (FileNotFoundException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } catch (StreamCorruptedException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } catch (IOException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } catch (ClassNotFoundException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } catch (ClassCastException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } finally { try { if (ois != null) { ois.close(); } else if (fis != null) { fis.close(); } } catch (IOException e) { mLogger.severe("Exception occurred in FileCacheController. " + e.getMessage()); } } } @Override public synchronized EventError addEvent(final Event event) { EventError error = super.addEvent(event); if (error == EventError.NONE && mAutoFlush) { flush(); } return error; } @Override public synchronized EventError removeEvent(final Event event) { EventError error = super.removeEvent(event); if (error == EventError.NONE && mAutoFlush) { flush(); } return error; } @Override public synchronized boolean removeAll() { boolean result = super.removeAll(); if (mAutoFlush) { flush(); } return result; } @Override public synchronized boolean removeEvents(final String sessionKey) { boolean result = super.removeEvents(sessionKey); if (mAutoFlush) { flush(); } return result; } }