From dd30cc59dd55154eb148e9290d301d3c842c3e76 Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Thu, 1 Nov 2012 11:47:43 -0700 Subject: [PATCH] First draft at a subtasks metadata migration --- .../subtasks/AstridOrderedListUpdater.java | 2 +- .../subtasks/SubtasksMetadataMigration.java | 118 ++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 astrid/plugin-src/com/todoroo/astrid/subtasks/SubtasksMetadataMigration.java diff --git a/astrid/plugin-src/com/todoroo/astrid/subtasks/AstridOrderedListUpdater.java b/astrid/plugin-src/com/todoroo/astrid/subtasks/AstridOrderedListUpdater.java index 62af4b8e1..258bd448d 100644 --- a/astrid/plugin-src/com/todoroo/astrid/subtasks/AstridOrderedListUpdater.java +++ b/astrid/plugin-src/com/todoroo/astrid/subtasks/AstridOrderedListUpdater.java @@ -322,7 +322,7 @@ public abstract class AstridOrderedListUpdater { return tree.toString(); } - private void recursivelySerializeChildren(Node node, JSONArray serializeTo) throws JSONException { + public static void recursivelySerializeChildren(Node node, JSONArray serializeTo) throws JSONException { ArrayList children = node.children; for (Node child : children) { JSONObject childObj = new JSONObject(); diff --git a/astrid/plugin-src/com/todoroo/astrid/subtasks/SubtasksMetadataMigration.java b/astrid/plugin-src/com/todoroo/astrid/subtasks/SubtasksMetadataMigration.java new file mode 100644 index 000000000..62a7c1f9e --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/subtasks/SubtasksMetadataMigration.java @@ -0,0 +1,118 @@ +package com.todoroo.astrid.subtasks; + +import java.util.ArrayList; + +import org.json.JSONArray; +import org.json.JSONException; + +import android.util.Log; + +import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.Autowired; +import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.andlib.sql.Order; +import com.todoroo.andlib.sql.Query; +import com.todoroo.andlib.utility.Preferences; +import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; +import com.todoroo.astrid.data.Metadata; +import com.todoroo.astrid.data.TagData; +import com.todoroo.astrid.service.MetadataService; +import com.todoroo.astrid.service.TagDataService; +import com.todoroo.astrid.subtasks.AstridOrderedListUpdater.Node; + +@SuppressWarnings("deprecation") // Subtasks metadata is deprecated +public class SubtasksMetadataMigration { + + @Autowired + private TagDataService tagDataService; + + @Autowired + private MetadataService metadataService; + + public SubtasksMetadataMigration() { + DependencyInjectionService.getInstance().inject(this); + } + + public void performMigration() { + TodorooCursor subtasksMetadata = metadataService.query(Query.select(Metadata.PROPERTIES) + .where(MetadataCriteria.withKey(SubtasksMetadata.METADATA_KEY)) + .orderBy(Order.asc(SubtasksMetadata.TAG), Order.asc(SubtasksMetadata.ORDER))); + try { + Metadata m = new Metadata(); + for (subtasksMetadata.moveToFirst(); !subtasksMetadata.isAfterLast(); subtasksMetadata.moveToNext()) { + m.readFromCursor(subtasksMetadata); + String tag = m.getValue(SubtasksMetadata.TAG); + processTag(tag, subtasksMetadata); + } + } finally { + subtasksMetadata.close(); + } + } + + @SuppressWarnings("nls") + private void processTag(String tag, TodorooCursor subtasksMetadata) { + Metadata item = new Metadata(); + TagData td = null; + try { + if (!SubtasksMetadata.LIST_ACTIVE_TASKS.equals(tag)) { + String idString = tag.replace("td:", ""); + long id = Long.parseLong(idString); + td = tagDataService.fetchById(id, TagData.ID); + } + } catch (NumberFormatException e) { + Log.e("subtasks-migration", "Could not parse tag id from " + tag, e); + } + + if (td == null && !SubtasksMetadata.LIST_ACTIVE_TASKS.equals(tag)) { + for (; !subtasksMetadata.isAfterLast(); subtasksMetadata.moveToNext()) { + item.readFromCursor(subtasksMetadata); + if (!item.getValue(SubtasksMetadata.TAG).equals(tag)) + break; + } + } else { + String newTree = buildTreeModelFromMetadata(tag, subtasksMetadata); + if (td != null) { + td.setValue(TagData.TAG_ORDERING, newTree); + tagDataService.save(td); + } else { + Preferences.setString(SubtasksUpdater.ACTIVE_TASKS_ORDER, newTree); + } + } + + subtasksMetadata.moveToPrevious(); // Move back one to undo the last iteration of the for loop + } + + private String buildTreeModelFromMetadata(String tag, TodorooCursor cursor) { + Metadata item = new Metadata(); + Node root = new Node(-1, null, -1); + for (; !cursor.isAfterLast(); cursor.moveToNext()) { + item.readFromCursor(cursor); + if (!item.getValue(SubtasksMetadata.TAG).equals(tag)) + break; + + int indent = item.getValue(SubtasksMetadata.INDENT); + Node parent = findNextParentForIndent(root, indent); + Node newNode = new Node(item.getValue(Metadata.TASK), parent, parent.indent + 1); + parent.children.add(newNode); + } + + try { + JSONArray array = new JSONArray(); + AstridOrderedListUpdater.recursivelySerializeChildren(root, new JSONArray()); + return array.toString(); + } catch (JSONException e) { + return "[]"; //$NON-NLS-1$ + } + } + + private Node findNextParentForIndent(Node root, int indent) { + if (indent <= 0) + return root; + + ArrayList children = root.children; + if (children.size() == 0) + return root; + + return findNextParentForIndent(children.get(children.size() - 1), indent - 1); + } +}