Convert SubtasksHelper to Kotlin

pull/1051/head
Alex Baker 4 years ago
parent 3d917fda62
commit 8487526171

@ -313,8 +313,7 @@ class SubtasksFilterUpdater @Inject constructor(
return serializeTree(treeRoot)
}
class Node internal constructor(@JvmField var uuid: String, var parent: Node?, var indent: Int) {
@JvmField
class Node internal constructor(var uuid: String, var parent: Node?, var indent: Int) {
val children = ArrayList<Node>()
}
@ -322,7 +321,6 @@ class SubtasksFilterUpdater @Inject constructor(
const val ACTIVE_TASKS_ORDER = "active_tasks_order" // $NON-NLS-1$
const val TODAY_TASKS_ORDER = "today_tasks_order" // $NON-NLS-1$
@JvmStatic
fun buildOrderString(ids: Array<String>): String {
val builder = StringBuilder()
if (ids.isEmpty()) {
@ -337,7 +335,6 @@ class SubtasksFilterUpdater @Inject constructor(
return builder.toString()
}
@JvmStatic
fun buildTreeModel(serializedTree: String?, callback: ((Node?) -> Unit)?): Node {
val root = Node("-1", null, -1) // $NON-NLS-1$
try {
@ -367,7 +364,6 @@ class SubtasksFilterUpdater @Inject constructor(
}
}
@JvmStatic
fun serializeTree(root: Node?): String {
val tree = JSONArray()
if (root == null) {

@ -1,165 +0,0 @@
package com.todoroo.astrid.subtasks;
import static org.tasks.Strings.isNullOrEmpty;
import static org.tasks.db.QueryUtils.showHiddenAndCompleted;
import android.content.Context;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.BuiltInFilterExposer;
import com.todoroo.astrid.dao.TaskDaoBlocking;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Node;
import dagger.hilt.android.qualifiers.ApplicationContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.tasks.data.TagData;
import org.tasks.data.TagDataDaoBlocking;
import org.tasks.data.TaskListMetadata;
import org.tasks.data.TaskListMetadataDaoBlocking;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
public class SubtasksHelper {
private final Context context;
private final Preferences preferences;
private final TaskDaoBlocking taskDao;
private final TagDataDaoBlocking tagDataDao;
private final TaskListMetadataDaoBlocking taskListMetadataDao;
@Inject
public SubtasksHelper(
@ApplicationContext Context context,
Preferences preferences,
TaskDaoBlocking taskDao,
TagDataDaoBlocking tagDataDao,
TaskListMetadataDaoBlocking taskListMetadataDao) {
this.context = context;
this.preferences = preferences;
this.taskDao = taskDao;
this.tagDataDao = tagDataDao;
this.taskListMetadataDao = taskListMetadataDao;
}
@Deprecated
private static List<Long> getIdList(String serializedTree) {
ArrayList<Long> ids = new ArrayList<>();
String[] digitsOnly =
serializedTree.split("[\\[\\],\\s]"); // Split on [ ] , or whitespace chars
for (String idString : digitsOnly) {
try {
if (!isNullOrEmpty(idString)) {
ids.add(Long.parseLong(idString));
}
} catch (NumberFormatException e) {
Timber.e(e);
}
}
return ids;
}
static String[] getStringIdArray(String serializedTree) {
ArrayList<String> ids = new ArrayList<>();
String[] values = serializedTree.split("[\\[\\],\"\\s]"); // Split on [ ] , or whitespace chars
for (String idString : values) {
if (!isNullOrEmpty(idString)) {
ids.add(idString);
}
}
return ids.toArray(new String[0]);
}
/** Takes a subtasks string containing local ids and remaps it to one containing UUIDs */
public static String convertTreeToRemoteIds(TaskDaoBlocking taskDao, String localTree) {
List<Long> localIds = getIdList(localTree);
Map<Long, String> idMap = getIdMap(taskDao, localIds);
idMap.put(-1L, "-1"); // $NON-NLS-1$
Node tree = SubtasksFilterUpdater.buildTreeModel(localTree, null);
remapLocalTreeToRemote(tree, idMap);
return SubtasksFilterUpdater.serializeTree(tree);
}
private static void remapTree(Node root, Map<Long, String> idMap, TreeRemapHelper helper) {
ArrayList<Node> children = root.children;
for (int i = 0; i < children.size(); i++) {
Node child = children.get(i);
Long key = helper.getKeyFromOldUuid(child.uuid);
String uuid = idMap.get(key);
if (!Task.isValidUuid(uuid)) {
children.remove(i);
children.addAll(i, child.children);
i--;
} else {
child.uuid = uuid;
remapTree(child, idMap, helper);
}
}
}
private static void remapLocalTreeToRemote(Node root, Map<Long, String> idMap) {
remapTree(
root,
idMap,
uuid -> {
long localId = -1L;
try {
localId = Long.parseLong(uuid);
} catch (NumberFormatException e) {
Timber.e(e);
}
return localId;
});
}
private static Map<Long, String> getIdMap(TaskDaoBlocking taskDao, List<Long> keys) {
List<Task> tasks = taskDao.fetch(keys);
Map<Long, String> map = new HashMap<>();
for (Task task : tasks) {
map.put(task.getId(), task.getUuid());
}
return map;
}
public String applySubtasksToWidgetFilter(Filter filter, String query) {
if (filter.supportsAstridSorting() && preferences.isAstridSort()) {
TagData tagData = tagDataDao.getTagByName(filter.listingTitle);
TaskListMetadata tlm = null;
if (tagData != null) {
tlm = taskListMetadataDao.fetchByTagOrFilter(tagData.getRemoteId());
} else if (BuiltInFilterExposer.isInbox(context, filter)) {
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_ALL);
} else if (BuiltInFilterExposer.isTodayFilter(context, filter)) {
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_TODAY);
}
if (tlm != null) {
query = query.replaceAll("ORDER BY .*", "");
query = query + String.format(" ORDER BY %s", getOrderString(tagData, tlm));
query = showHiddenAndCompleted(query);
filter.setFilterQueryOverride(query);
}
}
return query;
}
private String getOrderString(TagData tagData, TaskListMetadata tlm) {
String serialized;
if (tlm != null) {
serialized = tlm.getTaskIds();
} else if (tagData != null) {
serialized = convertTreeToRemoteIds(taskDao, tagData.getTagOrdering());
} else {
serialized = "[]"; // $NON-NLS-1$
}
return SubtasksFilterUpdater.buildOrderString(getStringIdArray(serialized));
}
interface TreeRemapHelper {
Long getKeyFromOldUuid(String uuid);
}
}

@ -0,0 +1,139 @@
package com.todoroo.astrid.subtasks
import android.content.Context
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isInbox
import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isTodayFilter
import com.todoroo.astrid.dao.TaskDaoBlocking
import com.todoroo.astrid.data.Task.Companion.isValidUuid
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildOrderString
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildTreeModel
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.serializeTree
import dagger.hilt.android.qualifiers.ApplicationContext
import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.TagData
import org.tasks.data.TagDataDaoBlocking
import org.tasks.data.TaskListMetadata
import org.tasks.data.TaskListMetadataDaoBlocking
import org.tasks.db.QueryUtils.showHiddenAndCompleted
import org.tasks.preferences.Preferences
import timber.log.Timber
import java.util.*
import javax.inject.Inject
class SubtasksHelper @Inject constructor(
@param:ApplicationContext private val context: Context,
private val preferences: Preferences,
private val taskDao: TaskDaoBlocking,
private val tagDataDao: TagDataDaoBlocking,
private val taskListMetadataDao: TaskListMetadataDaoBlocking) {
fun applySubtasksToWidgetFilter(filter: Filter, query: String): String {
var query = query
if (filter.supportsAstridSorting() && preferences.isAstridSort) {
val tagData = tagDataDao.getTagByName(filter.listingTitle)
var tlm: TaskListMetadata? = null
if (tagData != null) {
tlm = taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!)
} else if (isInbox(context, filter)) {
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_ALL)
} else if (isTodayFilter(context, filter)) {
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_TODAY)
}
if (tlm != null) {
query = query.replace("ORDER BY .*".toRegex(), "")
query += " ORDER BY ${getOrderString(tagData, tlm)}"
query = showHiddenAndCompleted(query)
filter.setFilterQueryOverride(query)
}
}
return query
}
private fun getOrderString(tagData: TagData?, tlm: TaskListMetadata?): String {
val serialized: String? = when {
tlm != null -> tlm.taskIds
tagData != null -> convertTreeToRemoteIds(taskDao, tagData.tagOrdering)
else -> "[]"
}
return buildOrderString(getStringIdArray(serialized))
}
companion object {
@Deprecated("")
private fun getIdList(serializedTree: String?): List<Long> {
val ids = ArrayList<Long>()
val digitsOnly = serializedTree!!.split("[\\[\\],\\s]".toRegex()).toTypedArray() // Split on [ ] , or whitespace chars
for (idString in digitsOnly) {
try {
if (!isNullOrEmpty(idString)) {
ids.add(idString.toLong())
}
} catch (e: NumberFormatException) {
Timber.e(e)
}
}
return ids
}
fun getStringIdArray(serializedTree: String?): Array<String> {
val ids = ArrayList<String>()
val values = serializedTree!!.split("[\\[\\],\"\\s]".toRegex()).toTypedArray() // Split on [ ] , or whitespace chars
for (idString in values) {
if (!isNullOrEmpty(idString)) {
ids.add(idString)
}
}
return ids.toTypedArray()
}
/** Takes a subtasks string containing local ids and remaps it to one containing UUIDs */
fun convertTreeToRemoteIds(taskDao: TaskDaoBlocking, localTree: String?): String {
val localIds = getIdList(localTree)
val idMap = getIdMap(taskDao, localIds)
idMap[-1L] = "-1" // $NON-NLS-1$
val tree = buildTreeModel(localTree, null)
remapLocalTreeToRemote(tree, idMap)
return serializeTree(tree)
}
private fun remapTree(root: SubtasksFilterUpdater.Node, idMap: Map<Long, String>, helper: (String) -> Long) {
val children = root.children
var i = 0
while (i < children.size) {
val child = children[i]
val key = helper.invoke(child.uuid)
val uuid = idMap[key]
if (!isValidUuid(uuid!!)) {
children.removeAt(i)
children.addAll(i, child.children)
i--
} else {
child.uuid = uuid
remapTree(child, idMap, helper)
}
i++
}
}
private fun remapLocalTreeToRemote(root: SubtasksFilterUpdater.Node, idMap: Map<Long, String>) {
remapTree(root, idMap) { uuid: String ->
var localId = -1L
try {
localId = uuid.toLong()
} catch (e: NumberFormatException) {
Timber.e(e)
}
localId
}
}
private fun getIdMap(taskDao: TaskDaoBlocking, keys: List<Long>): MutableMap<Long, String> {
val tasks = taskDao.fetch(keys)
val map: MutableMap<Long, String> = HashMap()
for (task in tasks) {
map[task.id] = task.uuid
}
return map
}
}
}
Loading…
Cancel
Save