Simplify all command and convert them to Kotlin

pull/699/head
Alinson S. Xavier 5 years ago
parent 373f21e247
commit 0a5622c78e

@ -54,7 +54,7 @@ public class PerformanceTest extends BaseAndroidTest
for (int i = 0; i < 1_000; i++)
{
Habit model = modelFactory.buildHabit();
new CreateHabitCommand(modelFactory, habitList, model).execute();
new CreateHabitCommand(modelFactory, habitList, model).run();
}
db.setTransactionSuccessful();
db.endTransaction();
@ -70,7 +70,7 @@ public class PerformanceTest extends BaseAndroidTest
for (int i = 0; i < 5_000; i++)
{
Timestamp timestamp = new Timestamp(i * DAY_LENGTH);
new CreateRepetitionCommand(habitList, habit, timestamp, 1).execute();
new CreateRepetitionCommand(habitList, habit, timestamp, 1).run();
}
db.setTransactionSuccessful();
db.endTransaction();

@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.habits.edit
import android.annotation.*
import android.content.res.*
import android.graphics.*
import android.os.*
@ -224,9 +225,15 @@ class EditHabitActivity : AppCompatActivity() {
habit.type = habitType
val command = if (habitId >= 0) {
component.editHabitCommandFactory.create(component.habitList, original, habit)
EditHabitCommand(
component.habitList,
habitId,
habit)
} else {
component.createHabitCommandFactory.create(component.habitList, habit)
CreateHabitCommand(
component.modelFactory,
component.habitList,
habit)
}
component.commandRunner.run(command)
finish()
@ -265,6 +272,7 @@ class EditHabitActivity : AppCompatActivity() {
}
}
@SuppressLint("StringFormatMatches")
private fun populateFrequency() {
binding.booleanFrequencyPicker.text = when {
freqNum == 1 && freqDen == 1 -> getString(R.string.every_day)

@ -52,10 +52,6 @@ public interface HabitsApplicationComponent
@AppContext
Context getContext();
CreateHabitCommandFactory getCreateHabitCommandFactory();
EditHabitCommandFactory getEditHabitCommandFactory();
GenericImporter getGenericImporter();
HabitCardListCache getHabitCardListCache();

@ -16,34 +16,16 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
package org.isoron.uhabits.core.commands;
import org.isoron.uhabits.core.models.*
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import java.util.*;
public class UnarchiveHabitsCommand implements Command
{
@NonNull
final HabitList habitList;
@NonNull
final List<Habit> selected;
public UnarchiveHabitsCommand(@NonNull HabitList habitList,
@NonNull List<Habit> selected)
{
this.selected = new LinkedList<>(selected);
this.habitList = habitList;
}
@Override
public void execute()
{
for (Habit h : selected) h.setArchived(false);
habitList.update(selected);
data class ArchiveHabitsCommand(
val habitList: HabitList,
val selected: List<Habit>,
) : Command {
override fun run() {
for (h in selected) h.isArchived = true
habitList.update(selected)
}
}

@ -1,57 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import java.util.*;
/**
* Command to change the color of a list of habits.
*/
public class ChangeHabitColorCommand implements Command
{
@NonNull
final HabitList habitList;
@NonNull
final List<Habit> selected;
@NonNull
final PaletteColor newColor;
public ChangeHabitColorCommand(@NonNull HabitList habitList,
@NonNull List<Habit> selected,
@NonNull PaletteColor newColor)
{
this.habitList = habitList;
this.selected = selected;
this.newColor = newColor;
}
@Override
public void execute()
{
for (Habit h : selected) h.setColor(newColor);
habitList.update(selected);
}
}

@ -16,36 +16,17 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import java.util.*;
/**
* Command to archive a list of habits.
*/
public class ArchiveHabitsCommand implements Command
{
final List<Habit> selected;
final HabitList habitList;
public ArchiveHabitsCommand(@NonNull HabitList habitList,
@NonNull List<Habit> selected)
{
super();
this.habitList = habitList;
this.selected = new LinkedList<>(selected);
}
@Override
public void execute()
{
for (Habit h : selected) h.setArchived(true);
habitList.update(selected);
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class ChangeHabitColorCommand(
val habitList: HabitList,
val selected: List<Habit>,
val newColor: PaletteColor,
) : Command {
override fun run() {
for (h in selected) h.color = newColor
habitList.update(selected)
}
}

@ -16,14 +16,8 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
package org.isoron.uhabits.core.commands;
/**
* A Command represents a desired set of changes that should be performed on the
* models. In general, commands should always be executed by a {@link CommandRunner}.
*/
public interface Command
{
void execute();
}
interface Command {
fun run()
}

@ -33,7 +33,7 @@ open class CommandRunner
open fun run(command: Command) {
taskRunner.execute(object : Task {
override fun doInBackground() {
command.execute()
command.run()
}
override fun onPostExecute() {
notifyListeners(command)

@ -1,54 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import com.google.auto.factory.*;
import org.isoron.uhabits.core.models.*;
@AutoFactory
public class CreateHabitCommand implements Command
{
ModelFactory modelFactory;
HabitList habitList;
@NonNull
Habit model;
public CreateHabitCommand(@Provided @NonNull ModelFactory modelFactory,
@NonNull HabitList habitList,
@NonNull Habit model)
{
this.modelFactory = modelFactory;
this.habitList = habitList;
this.model = model;
}
@Override
public void execute()
{
Habit habit = modelFactory.buildHabit();
habit.copyFrom(model);
habitList.add(habit);
}
}

@ -16,40 +16,18 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import java.util.*;
public class DeleteHabitsCommand implements Command
{
@NonNull
final HabitList habitList;
@NonNull
final List<Habit> selected;
public DeleteHabitsCommand(@NonNull HabitList habitList,
@NonNull List<Habit> selected)
{
this.selected = new LinkedList<>(selected);
this.habitList = habitList;
}
@Override
public void execute()
{
for (Habit h : selected)
habitList.remove(h);
}
public List<Habit> getSelected()
{
return Collections.unmodifiableList(selected);
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class CreateHabitCommand(
val modelFactory: ModelFactory,
val habitList: HabitList,
val model: Habit,
) : Command {
override fun run() {
val habit = modelFactory.buildHabit()
habit.copyFrom(model)
habitList.add(habit)
}
}
}

@ -1,84 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import java.util.*;
public class CreateRepetitionCommand implements Command
{
@NonNull
final Habit habit;
@NonNull
final HabitList habitList;
@NonNull
final Timestamp timestamp;
final int value;
public CreateRepetitionCommand(@NonNull HabitList habitList,
@NonNull Habit habit,
@NonNull Timestamp timestamp,
int value)
{
this.habitList = habitList;
this.timestamp = timestamp;
this.habit = habit;
this.value = value;
}
@Override
public void execute()
{
EntryList entries = habit.getOriginalEntries();
entries.add(new Entry(timestamp, value));
habit.recompute();
habitList.resort();
}
@NonNull
public Habit getHabit()
{
return habit;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CreateRepetitionCommand that = (CreateRepetitionCommand) o;
return value == that.value &&
habit.equals(that.habit) &&
habitList.equals(that.habitList) &&
timestamp.equals(that.timestamp);
}
@Override
public int hashCode()
{
return Objects.hash(habit, habitList, timestamp, value);
}
}

@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class CreateRepetitionCommand(
val habitList: HabitList,
val habit: Habit,
val timestamp: Timestamp,
val value: Int,
) : Command {
override fun run() {
val entries = habit.originalEntries
entries.add(Entry(timestamp, value))
habit.recompute()
habitList.resort()
}
}

@ -0,0 +1,30 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class DeleteHabitsCommand(
val habitList: HabitList,
val selected: List<Habit>,
) : Command {
override fun run() {
for (h in selected) habitList.remove(h)
}
}

@ -1,89 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands;
import androidx.annotation.*;
import com.google.auto.factory.*;
import org.isoron.uhabits.core.models.*;
@AutoFactory
public class EditHabitCommand implements Command
{
@NonNull
final HabitList habitList;
@NonNull
final Habit original;
@NonNull
final Habit modified;
final long savedId;
final boolean hasFrequencyChanged;
final boolean hasTargetChanged;
public EditHabitCommand(@Provided @NonNull ModelFactory modelFactory,
@NonNull HabitList habitList,
@NonNull Habit original,
@NonNull Habit modified)
{
Long habitId = original.getId();
if (habitId == null) throw new RuntimeException("Habit not saved");
this.savedId = habitId;
this.habitList = habitList;
this.modified = modelFactory.buildHabit();
this.original = modelFactory.buildHabit();
this.modified.copyFrom(modified);
this.original.copyFrom(original);
Frequency originalFreq = this.original.getFrequency();
Frequency modifiedFreq = this.modified.getFrequency();
hasFrequencyChanged = (!originalFreq.equals(modifiedFreq));
hasTargetChanged =
(original.getTargetType() != modified.getTargetType() ||
original.getTargetValue() != modified.getTargetValue());
}
@Override
public void execute()
{
copyAttributes(this.modified);
}
private void copyAttributes(Habit model)
{
Habit habit = habitList.getById(savedId);
if (habit == null) throw new RuntimeException("Habit not found");
habit.copyFrom(model);
habitList.update(habit);
habit.getObservable().notifyListeners();
if (hasFrequencyChanged || hasTargetChanged)
habit.recompute();
}
}

@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class EditHabitCommand(
val habitList: HabitList,
val habitId: Long,
val modified: Habit,
) : Command {
override fun run() {
val habit = habitList.getById(habitId) ?: throw HabitNotFoundException()
habit.copyFrom(modified)
habitList.update(habit)
habit.observable.notifyListeners()
habit.recompute()
}
}

@ -0,0 +1,31 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.commands
import org.isoron.uhabits.core.models.*
data class UnarchiveHabitsCommand(
val habitList: HabitList,
val selected: List<Habit>,
) : Command {
override fun run() {
for (h in selected) h.isArchived = false
habitList.update(selected)
}
}

@ -116,15 +116,15 @@ public class LoopDBImporter extends AbstractImporter
habitRecord.id = null;
habitRecord.copyTo(habit);
command = new CreateHabitCommand(modelFactory, habitList, habit);
command.execute();
command.run();
}
else
{
Habit modified = modelFactory.buildHabit();
habitRecord.id = habit.getId();
habitRecord.copyTo(modified);
command = new EditHabitCommand(modelFactory, habitList, habit, modified);
command.execute();
command = new EditHabitCommand(habitList, habit.getId(), modified);
command.run();
}
// Reload saved version of the habit
@ -135,7 +135,7 @@ public class LoopDBImporter extends AbstractImporter
Timestamp t = new Timestamp(r.timestamp);
Entry existingEntry = habit.getOriginalEntries().get(t);
if (existingEntry.getValue() != r.value)
new CreateRepetitionCommand(habitList, habit, t, r.value).execute();
new CreateRepetitionCommand(habitList, habit, t, r.value).run();
}
runner.notifyListeners(command);

@ -27,7 +27,6 @@ import java.util.*;
import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
public class ArchiveHabitsCommandTest extends BaseUnitTest
{
@ -52,7 +51,7 @@ public class ArchiveHabitsCommandTest extends BaseUnitTest
public void testExecute()
{
assertFalse(habit.isArchived());
command.execute();
command.run();
assertTrue(habit.isArchived());
}

@ -57,7 +57,7 @@ public class ChangeHabitColorCommandTest extends BaseUnitTest
public void testExecute()
{
checkOriginalColors();
command.execute();
command.run();
checkNewColors();
}

@ -50,7 +50,7 @@ public class CreateHabitCommandTest extends BaseUnitTest
public void testExecute()
{
assertTrue(habitList.isEmpty());
command.execute();
command.run();
assertThat(habitList.size(), equalTo(1));
Habit habit = habitList.getByPosition(0);
assertThat(habit.getName(), equalTo(model.getName()));

@ -55,7 +55,7 @@ public class CreateRepetitionCommandTest extends BaseUnitTest
Entry entry = entries.get(today);
assertEquals(YES_MANUAL, entry.getValue());
command.execute();
command.run();
entry = entries.get(today);
assertEquals(100, entry.getValue());
}

@ -66,7 +66,7 @@ public class DeleteHabitsCommandTest extends BaseUnitTest
{
assertThat(habitList.size(), equalTo(4));
command.execute();
command.run();
assertThat(habitList.size(), equalTo(1));
assertThat(habitList.getByPosition(0).getName(), equalTo("extra"));
}

@ -54,12 +54,12 @@ public class EditHabitCommandTest extends BaseUnitTest
@Test
public void testExecute()
{
command = new EditHabitCommand(modelFactory, habitList, habit, modified);
command = new EditHabitCommand(habitList, habit.getId(), modified);
double originalScore = habit.getScores().getTodayValue();
assertThat(habit.getName(), equalTo("original"));
command.execute();
command.run();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(), equalTo(originalScore));
}
@ -69,12 +69,12 @@ public class EditHabitCommandTest extends BaseUnitTest
{
modified.setFrequency(Frequency.TWO_TIMES_PER_WEEK);
command =
new EditHabitCommand(modelFactory, habitList, habit, modified);
new EditHabitCommand(habitList, habit.getId(), modified);
double originalScore = habit.getScores().getTodayValue();
assertThat(habit.getName(), equalTo("original"));
command.execute();
command.run();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(),
lessThan(originalScore));

@ -51,7 +51,7 @@ public class UnarchiveHabitsCommandTest extends BaseUnitTest
public void testExecuteUndoRedo()
{
assertTrue(habit.isArchived());
command.execute();
command.run();
assertFalse(habit.isArchived());
}

Loading…
Cancel
Save