diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/reminders/CustomRemindersSaverXmlTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/reminders/CustomRemindersSaverXmlTest.java new file mode 100644 index 000000000..ca23c5484 --- /dev/null +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/reminders/CustomRemindersSaverXmlTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.uhabits.reminders; + +import android.support.test.filters.*; +import android.support.test.runner.*; + +import org.isoron.uhabits.*; +import org.junit.*; +import org.junit.runner.*; + +import java.util.*; + +@RunWith(AndroidJUnit4.class) +@MediumTest +public class CustomRemindersSaverXmlTest extends BaseAndroidTest +{ + @Test + public void testSaveLoad() + { + CustomRemindersSaverXml saver = new CustomRemindersSaverXml( targetContext ); + HashMap< Long, Long > map = new HashMap< Long, Long >(); + map.put( 1L, 1L ); + map.put( 2L, 3L ); + map.put( 3L, 1L ); + saver.save( map ); + Map< Long, Long > map2 = saver.load(); + assertEquals( map, map2 ); + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt index df162766c..59f4ec9b2 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.kt @@ -25,6 +25,7 @@ import org.isoron.androidbase.* import org.isoron.uhabits.core.database.* import org.isoron.uhabits.core.reminders.* import org.isoron.uhabits.core.ui.* +import org.isoron.uhabits.reminders.* import org.isoron.uhabits.utils.* import org.isoron.uhabits.widgets.* import java.io.* @@ -64,6 +65,7 @@ class HabitsApplication : Application() { widgetUpdater.startListening() reminderScheduler = component.reminderScheduler + reminderScheduler.setCustomRemindersSaver( CustomRemindersSaverXml( context )) reminderScheduler.startListening() notificationTray = component.notificationTray diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/reminders/CustomRemindersSaverXml.java b/uhabits-android/src/main/java/org/isoron/uhabits/reminders/CustomRemindersSaverXml.java new file mode 100644 index 000000000..b7062c82b --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/reminders/CustomRemindersSaverXml.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.uhabits.reminders; + +import android.content.*; +import android.support.annotation.*; +import android.util.*; + +import org.isoron.uhabits.*; +import org.isoron.uhabits.core.reminders.*; +import org.w3c.dom.*; +import org.xml.sax.*; +import org.xmlpull.v1.*; + +import java.io.*; +import java.util.*; + +import javax.xml.parsers.*; + +public class CustomRemindersSaverXml implements CustomReminders.Saver +{ + private static final String FILENAME_NORMAL = "custom_reminders.xml"; + private static final String FILENAME_DEBUG = "custom_reminders_debug.xml"; + private static final String TAG = "CustomRemindersSaverXml"; + + private Context context; + + private String filename() + { + return HabitsApplication.Companion.isTestMode() ? FILENAME_DEBUG : FILENAME_NORMAL; + } + + public CustomRemindersSaverXml(@NonNull Context context) + { + this.context = context; + } + + @Override + public void save(Map map) + { + StringWriter writer = new StringWriter(); + try + { + XmlSerializer serializer = Xml.newSerializer(); + serializer.setOutput( writer ); + serializer.startDocument("UTF-8", true); + serializer.startTag( "","reminders" ); + for( Map.Entry< Long, Long > entry : map.entrySet()) + { + serializer.startTag( "", "reminder" ); + serializer.attribute( "", "habitId", entry.getKey().toString()); + serializer.attribute( "", "time", entry.getValue().toString()); + serializer.endTag( "", "reminder" ); + } + serializer.endTag( "", "reminders" ); + serializer.endDocument(); + } catch (IOException e) + { + Log.e( TAG, "Error writing XML for custom reminders" ); + context.getFileStreamPath( filename()).delete(); + return; + } + try + { + FileOutputStream out = context.openFileOutput( filename(), Context.MODE_PRIVATE); + out.write( writer.toString().getBytes()); + out.close(); + } + catch (IOException e) + { + Log.e( TAG, "Error creating XML file for custom reminders" ); + context.getFileStreamPath( filename()).delete(); + } + } + + @Override + public Map load() + { + Map< Long, Long > map = new HashMap< Long, Long >(); + try + { + InputStream in = context.openFileInput( filename()); + if( in != null ) + { + try + { + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc = builder.parse( in ); + NodeList nodes = doc.getElementsByTagName( "reminder" ); + for( int i = 0; i < nodes.getLength(); ++i ) + { + Element element = (Element) nodes.item(i); + Long habitId = Long.parseLong(element.getAttribute("habitId")); + Long time = Long.parseLong(element.getAttribute("time")); + map.put(habitId, time); + } + } + catch (SAXException | ParserConfigurationException e) + { + Log.e( TAG, "Error reading custom reminders XML"); + } + in.close(); + } + } + catch (IOException e) + { + Log.d( TAG, "Custom reminders XML file not found"); + } + return map; + } +} diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/CustomReminders.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/CustomReminders.java new file mode 100644 index 000000000..657eed95d --- /dev/null +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/CustomReminders.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.uhabits.core.reminders; + +import android.support.annotation.*; + +import java.util.*; + +public class CustomReminders +{ + private Map< Long, Long > map; // Habit id, Timestamp + + private Saver saver; + + CustomReminders() + { + map = new HashMap< Long, Long >(); + } + + public void setSaver( Saver saver ) + { + this.saver = saver; + if( saver != null ) + map = saver.load(); + } + + public void set(@NonNull Long habitId, @NonNull Long reminderTime) + { + map.put( habitId, reminderTime ); + save(); + } + + public void remove(@NonNull Long habitId ) + { + if( map.remove( habitId ) != null ) + save(); + } + + public Long get( @NonNull Long habitId ) + { + return map.get( habitId ); + } + + private void save() + { + if( saver != null ) + saver.save( map ); + } + + public interface Saver + { + void save( Map< Long, Long > map); + Map< Long, Long > load(); + } +} diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java index ec29328f0..bdc0e738b 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/reminders/ReminderScheduler.java @@ -41,7 +41,7 @@ public class ReminderScheduler implements CommandRunner.Listener private SystemScheduler sys; - private Map< Long, Long > customReminders; // Habit id, Timestamp + private CustomReminders customReminders; @Inject public ReminderScheduler(@NonNull CommandRunner commandRunner, @@ -51,7 +51,12 @@ public class ReminderScheduler implements CommandRunner.Listener this.commandRunner = commandRunner; this.habitList = habitList; this.sys = sys; - customReminders = new HashMap< Long, Long >(); + this.customReminders = new CustomReminders(); + } + + public void setCustomRemindersSaver( CustomReminders.Saver saver ) + { + customReminders.setSaver( saver ); } @Override @@ -81,8 +86,7 @@ public class ReminderScheduler implements CommandRunner.Listener public void scheduleHabit(@NonNull Habit habit) { Long reminderTime = null; - if( customReminders.containsKey( habit.getId())) - reminderTime = customReminders.get( habit.getId()); + reminderTime = customReminders.get( habit.getId()); scheduleInternal(habit, reminderTime); } @@ -94,7 +98,7 @@ public class ReminderScheduler implements CommandRunner.Listener public void scheduleHabitAtCustom(@NonNull Habit habit, @NonNull Long reminderTime) { - customReminders.put( habit.getId(), reminderTime ); + customReminders.set( habit.getId(), reminderTime ); scheduleInternal(habit, reminderTime); } diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/reminders/CustomRemindersTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/reminders/CustomRemindersTest.java new file mode 100644 index 000000000..877f9a291 --- /dev/null +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/reminders/CustomRemindersTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.uhabits.core.reminders; + +import org.hamcrest.*; +import org.isoron.uhabits.core.*; +import org.junit.*; + +import static org.hamcrest.Matchers.*; + +public class CustomRemindersTest extends BaseUnitTest +{ + @Test + public void ModifyTest() + { + CustomReminders reminders = new CustomReminders(); + MatcherAssert.assertThat( reminders.get( 1L ), equalTo( null )); + reminders.set( 1L, 1L ); + MatcherAssert.assertThat( reminders.get( 1L ), equalTo( 1L )); + reminders.set( 2L, 2L ); + MatcherAssert.assertThat( reminders.get( 2L ), equalTo( 2L )); + reminders.set( 1L, 3L ); + MatcherAssert.assertThat( reminders.get( 1L ), equalTo( 3L )); + MatcherAssert.assertThat( reminders.get( 2L ), equalTo( 2L )); + reminders.remove( 1L ); + MatcherAssert.assertThat( reminders.get( 1L ), equalTo( null )); + } +}