Wrote some helper functions to convert subtask trees between local and remote ids (could be useful for syncing)

pull/14/head
Sam Bosley 13 years ago
parent 0ad805648f
commit 7130547bef

@ -31,7 +31,7 @@ public abstract class AstridOrderedListUpdater<LIST> {
}
public static class Node {
public final long taskId;
public long taskId;
public Node parent;
public int indent;
public final ArrayList<Node> children = new ArrayList<Node>();
@ -63,7 +63,12 @@ public abstract class AstridOrderedListUpdater<LIST> {
}
public void initializeFromSerializedTree(LIST list, Filter filter, String serializedTree) {
treeRoot = buildTreeModel(serializedTree);
treeRoot = buildTreeModel(serializedTree, new JSONTreeModelBuilder() {
@Override
public void afterAddNode(Node node) {
idToNode.put(node.taskId, node);
}
});
verifyTreeModel(list, filter);
}
@ -303,44 +308,54 @@ public abstract class AstridOrderedListUpdater<LIST> {
applyToFilter(filter);
}
private Node buildTreeModel(String serializedTree) {
private interface JSONTreeModelBuilder {
void afterAddNode(Node node);
}
public static Node buildTreeModel(String serializedTree, JSONTreeModelBuilder callback) {
Node root = new Node(-1, null, -1);
try {
JSONArray tree = new JSONArray(serializedTree);
recursivelyBuildChildren(root, tree);
recursivelyBuildChildren(root, tree, callback);
} catch (JSONException e) {
Log.e("OrderedListUpdater", "Error building tree model", e); //$NON-NLS-1$//$NON-NLS-2$
}
return root;
}
private void recursivelyBuildChildren(Node node, JSONArray children) throws JSONException {
private static void recursivelyBuildChildren(Node node, JSONArray children, JSONTreeModelBuilder callback) throws JSONException {
for (int i = 1; i < children.length(); i++) {
JSONArray subarray = children.optJSONArray(i);
if (subarray == null) {
Long id = children.getLong(i);
Node child = new Node(id, node, node.indent + 1);
node.children.add(child);
idToNode.put(id, child);
if (callback != null)
callback.afterAddNode(child);
} else {
Long id = subarray.getLong(0);
Node child = new Node(id, node, node.indent + 1);
recursivelyBuildChildren(child, subarray);
recursivelyBuildChildren(child, subarray, callback);
node.children.add(child);
idToNode.put(id, child);
if (callback != null)
callback.afterAddNode(child);
}
}
}
protected String serializeTree() {
return serializeTree(treeRoot);
}
public static String serializeTree(Node root) {
JSONArray tree = new JSONArray();
if (treeRoot == null) {
if (root == null) {
return tree.toString();
}
try {
tree.put(-1L);
recursivelySerialize(treeRoot, tree);
recursivelySerialize(root, tree);
} catch (JSONException e) {
Log.e("OrderedListUpdater", "Error serializing tree model", e); //$NON-NLS-1$//$NON-NLS-2$
}

@ -1,13 +1,16 @@
package com.todoroo.astrid.subtasks;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.TagViewFragment;
import com.todoroo.astrid.api.Filter;
@ -18,6 +21,7 @@ import com.todoroo.astrid.core.SortHelper;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.subtasks.AstridOrderedListUpdater.Node;
import com.todoroo.astrid.utility.AstridPreferences;
public class SubtasksHelper {
@ -75,12 +79,11 @@ public class SubtasksHelper {
else
serialized = Preferences.getStringValue(SubtasksUpdater.ACTIVE_TASKS_ORDER);
ArrayList<Long> ids = getIdArray(serialized);
return AstridOrderedListUpdater.buildOrderString(ids.toArray(new Long[ids.size()]));
return AstridOrderedListUpdater.buildOrderString(getIdArray(serialized));
}
@SuppressWarnings("nls")
private static ArrayList<Long> getIdArray(String serializedTree) {
public static Long[] getIdArray(String serializedTree) {
ArrayList<Long> ids = new ArrayList<Long>();
String[] digitsOnly = serializedTree.split("\\D+");
for (String idString : digitsOnly) {
@ -91,7 +94,74 @@ public class SubtasksHelper {
Log.e("widget-subtasks", "error parsing id " + idString, e);
}
}
return ids;
return ids.toArray(new Long[ids.size()]);
}
public static String convertTreeToRemoteIds(String localTree) {
return convertIdTree(localTree, true);
}
public static String convertTreeToLocalIds(String remoteTree) {
return convertIdTree(remoteTree, false);
}
private static String convertIdTree(String treeString, boolean localToRemote) {
Long[] ids = getIdArray(treeString);
HashMap<Long, Long> idMap = buildIdMap(ids, localToRemote);
Node tree = AstridOrderedListUpdater.buildTreeModel(treeString, null);
remapTree(tree, idMap);
return AstridOrderedListUpdater.serializeTree(tree);
}
private static void remapTree(Node root, HashMap<Long, Long> idMap) {
ArrayList<Node> children = root.children;
for (int i = 0; i < children.size(); i++) {
Node child = children.get(i);
Long remoteId = idMap.get(child.taskId);
if (remoteId == null || remoteId <= 0) {
children.remove(i);
i--;
} else {
child.taskId = remoteId;
remapTree(child, idMap);
}
}
}
private static HashMap<Long, Long> buildIdMap(Long[] localIds, boolean localToRemote) { // If localToRemote is true, keys are local ids. If false. keys are remtoe ids
HashMap<Long, Long> map = new HashMap<Long, Long>();
Criterion criterion;
if (localToRemote)
criterion = Task.ID.in(localIds);
else
criterion = Task.REMOTE_ID.in(localIds);
TodorooCursor<Task> tasks = PluginServices.getTaskService().query(Query.select(Task.ID, Task.REMOTE_ID).where(criterion));
try {
Task t = new Task();
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
t.clear();
t.readFromCursor(tasks);
if (t.containsNonNullValue(Task.REMOTE_ID)) {
Long key;
Long value;
if (localToRemote) {
key = t.getId();
value = t.getValue(Task.REMOTE_ID);
} else {
key = t.getValue(Task.REMOTE_ID);
value = t.getId();
}
map.put(key, value);
}
}
} finally {
tasks.close();
}
return map;
}
}

Loading…
Cancel
Save