package moontime.droid.store; import java.io.IOException; import java.util.List; import moontime.MoonEvent; import moontime.MoonEventType; import moontime.droid.entity.Reminder; import org.codehaus.jackson.annotate.JsonAutoDetect; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.introspect.VisibilityChecker; import org.codehaus.jackson.type.TypeReference; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.util.Log; import com.google.inject.Inject; import com.google.inject.Singleton; @Singleton public class GlobalPreferences { public static final String GLOBAL_PREFERENCES = "moontime.droid.preferences"; private final ObjectMapper _objectMapper = new ObjectMapper(); private final SharedPreferences _preferences; @Inject public GlobalPreferences(SharedPreferences preferences) { _preferences = preferences; _objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); _objectMapper.configure(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, true); _objectMapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility( JsonAutoDetect.Visibility.ANY)); } private static String getRemindersKey(MoonEvent event) { return "reminders." + event.getType().name(); } private static String getRemindersLastUpdated(MoonEventType eventType) { return "reminders." + eventType.name().toLowerCase() + ".last-updated"; } public void resetLastReminderUpdate() { Editor editor = _preferences.edit(); for (MoonEventType moonEventType : MoonEventType.values()) { editor.remove(getRemindersLastUpdated(moonEventType)); } editor.commit(); } public List<Reminder> getReminders(MoonEvent event, boolean checkExpiration) { List<Reminder> reminders = this.<List<Reminder>> loadFromJson(getRemindersKey(event), "[]", new TypeReference<List<Reminder>>() { }); if (checkExpiration && !reminders.isEmpty()) { long eventTime = event.getDate().getTime(); long lastUpdated = _preferences.getLong(getRemindersLastUpdated(event.getType()), eventTime); Log.d("debug", "check expiration: " + lastUpdated + " / " + eventTime); if (Math.abs(eventTime - lastUpdated) > 1000 * 60 * 60 * 24) { Log.d("debug", "expire checked reminders for " + event.getType().getDisplayName()); for (Reminder reminder : reminders) { reminder.setChecked(false); } } } return reminders; } public void saveReminders(MoonEvent event, List<Reminder> reminders) { Editor editor = _preferences.edit(); editor.putLong(getRemindersLastUpdated(event.getType()), event.getDate().getTime()); editor.commit(); storeAsJson(getRemindersKey(event), reminders); } private void storeAsJson(String prefKey, Object prefValue) { try { Editor editor = _preferences.edit(); editor.putString(prefKey, _objectMapper.writeValueAsString(prefValue)); editor.commit(); } catch (IOException e) { throw new RuntimeException(e); } } @SuppressWarnings("unchecked") private <T> T loadFromJson(String preferenceKey, String defaultValue, TypeReference<T> typeReference) { try { String prefValue = _preferences.getString(preferenceKey, defaultValue); return (T) _objectMapper.readValue(prefValue, typeReference); } catch (IOException e) { throw new RuntimeException(e); } } }