diff --git a/api/src/main/java/com/todoroo/astrid/core/SearchFilter.java b/api/src/main/java/com/todoroo/astrid/core/SearchFilter.java index e33bf7033..610c280ef 100644 --- a/api/src/main/java/com/todoroo/astrid/core/SearchFilter.java +++ b/api/src/main/java/com/todoroo/astrid/core/SearchFilter.java @@ -28,9 +28,6 @@ public class SearchFilter extends FilterListItem { this.listingTitle = listingTitle; } - /** - * Constructor for creating a new SearchFilter - */ protected SearchFilter() { // } diff --git a/astrid/src/main/java/com/todoroo/astrid/backup/BackupConstants.java b/astrid/src/main/java/com/todoroo/astrid/backup/BackupConstants.java index 16c431085..6967e698d 100644 --- a/astrid/src/main/java/com/todoroo/astrid/backup/BackupConstants.java +++ b/astrid/src/main/java/com/todoroo/astrid/backup/BackupConstants.java @@ -39,6 +39,9 @@ public class BackupConstants { /** Tag containing a metadata item */ public static final String METADATA_TAG = "metadata"; + /** Tag containing a tagdata item */ + public static final String TAGDATA_TAG = "tagdata"; + // --- format 1 public static final String TAG_TAG = "tag"; diff --git a/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java b/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java index 19e70cada..2aff647d0 100644 --- a/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java +++ b/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlExporter.java @@ -27,8 +27,10 @@ import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.dao.Database; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.data.Metadata; +import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.service.MetadataService; +import com.todoroo.astrid.service.TagDataService; import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.utility.AstridPreferences; @@ -63,13 +65,15 @@ public class TasksXmlExporter { // --- implementation - private static final int FORMAT = 2; + // 3 is started on Version 4.6.10 + private static final int FORMAT = 3; private final Context context; private int exportCount = 0; private XmlSerializer xml; private final Database database = PluginServices.getDatabase(); private final TaskService taskService = PluginServices.getTaskService(); + private final TagDataService tagdataService = PluginServices.getTagDataService(); private final MetadataService metadataService = PluginServices.getMetadataService(); private final ExceptionService exceptionService = PluginServices.getExceptionService(); @@ -176,6 +180,7 @@ public class TasksXmlExporter { Integer.toString(FORMAT)); serializeTasks(); + serializeTagDatas(); xml.endTag(null, BackupConstants.ASTRID_TAG); xml.endDocument(); @@ -183,6 +188,30 @@ public class TasksXmlExporter { fos.close(); } + private void serializeTagDatas() throws IOException { + TodorooCursor cursor; + cursor = tagdataService.query(Query.select( + TagData.PROPERTIES).orderBy(Order.asc(TagData.ID))); + + try { + TagData tag = new TagData(); + int length = cursor.getCount(); + for(int i = 0; i < length; i++) { + cursor.moveToNext(); + tag.readFromCursor(cursor); + + //TODO setProgress(i, length); + + xml.startTag(null, BackupConstants.TAGDATA_TAG); + serializeModel(tag, TagData.PROPERTIES, TagData.ID); + xml.endTag(null, BackupConstants.TAGDATA_TAG); + //this.exportCount++; + } + } finally { + cursor.close(); + } + } + private void serializeTasks() throws IOException { TodorooCursor cursor; cursor = taskService.query(Query.select( diff --git a/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java b/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java index 6f040d75f..b45dbb2e4 100644 --- a/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java +++ b/astrid/src/main/java/com/todoroo/astrid/backup/TasksXmlImporter.java @@ -31,14 +31,17 @@ import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.data.Metadata; +import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.legacy.LegacyImportance; import com.todoroo.astrid.legacy.LegacyRepeatInfo; import com.todoroo.astrid.legacy.LegacyRepeatInfo.LegacyRepeatInterval; import com.todoroo.astrid.legacy.LegacyTaskModel; import com.todoroo.astrid.service.MetadataService; +import com.todoroo.astrid.service.TagDataService; import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.tags.TagService; +import com.todoroo.astrid.tags.TaskToTagMetadata; import org.tasks.R; import org.xmlpull.v1.XmlPullParser; @@ -74,6 +77,7 @@ public class TasksXmlImporter { private final Context context; private final TaskService taskService = PluginServices.getTaskService(); private final MetadataService metadataService = PluginServices.getMetadataService(); + private final TagDataService tagdataService = PluginServices.getTagDataService(); private final ExceptionService exceptionService = PluginServices.getExceptionService(); private final ProgressDialog progressDialog; private final Runnable runAfterImport; @@ -148,6 +152,8 @@ public class TasksXmlImporter { new Format1TaskImporter(xpp); } else if(TextUtils.equals(format, FORMAT2)) { new Format2TaskImporter(xpp); + } else if(TextUtils.equals(format, FORMAT3)) { + new Format3TaskImporter(xpp); } else { throw new UnsupportedOperationException( "Did not know how to import tasks with xml format '" + @@ -203,11 +209,13 @@ public class TasksXmlImporter { private static final String FORMAT2 = "2"; //$NON-NLS-1$ private class Format2TaskImporter { - private int version; - private final XmlPullParser xpp; - private final Task currentTask = new Task(); - private final Metadata metadata = new Metadata(); + protected int version; + protected XmlPullParser xpp; + protected Task currentTask = new Task(); + protected Metadata metadata = new Metadata(); + protected TagData tagdata = new TagData(); + public Format2TaskImporter() { } public Format2TaskImporter(XmlPullParser xpp) throws XmlPullParserException, IOException { this.xpp = xpp; @@ -230,7 +238,7 @@ public class TasksXmlImporter { parseTask(); } else if (tag.equals(BackupConstants.METADATA_TAG)) { // Process - parseMetadata(); + parseMetadata(2); } } catch (Exception e) { errorCount++; @@ -241,7 +249,7 @@ public class TasksXmlImporter { } } - private void parseTask() { + protected void parseTask() { taskCount++; setProgressMessage(context.getString(R.string.import_progress_read, taskCount)); @@ -290,7 +298,7 @@ public class TasksXmlImporter { importCount++; } - private void parseMetadata() { + protected void parseMetadata(int format) { if(!currentTask.isSaved()) { return; } @@ -299,12 +307,36 @@ public class TasksXmlImporter { metadata.setId(Metadata.NO_ID); metadata.setValue(Metadata.TASK, currentTask.getId()); metadataService.save(metadata); + + // Construct the TagData from Metadata + // Fix for failed backup, Version before 4.6.10 + if (format == 2) { + String key = metadata.getValue(Metadata.KEY); + String name = metadata.getValue(Metadata.VALUE1); + String uuid = metadata.getValue(Metadata.VALUE2); + // UUID is uniquely for every TagData, so we don't need to test the name + TodorooCursor cursor = tagdataService.query(Query.select(TagData.ID). + where(TagData.UUID.eq(uuid))); + try { + //If you sync with Google tasks it adds some Google task metadata. + //For this metadata we don't create a list! + if(key.equals(TaskToTagMetadata.KEY) && cursor.getCount() == 0) { + tagdata.clear(); + tagdata.setId(TagData.NO_ID); + tagdata.setUuid(uuid); + tagdata.setValue(TagData.NAME, name); + tagdataService.save(tagdata); + } + } finally { + cursor.close(); + } + } } /** * Turn a model into xml attributes */ - private void deserializeModel(AbstractModel model, Property[] properties) { + protected void deserializeModel(AbstractModel model, Property[] properties) { for(Property property : properties) { try { property.accept(xmlReadingVisitor, model); @@ -365,6 +397,50 @@ public class TasksXmlImporter { } } + // =============================================================== FORMAT3 + + private static final String FORMAT3 = "3"; //$NON-NLS-1$ + private class Format3TaskImporter extends Format2TaskImporter { + + public Format3TaskImporter(XmlPullParser xpp) throws XmlPullParserException, IOException { + this.xpp = xpp; + try { + this.version = Integer.parseInt(xpp.getAttributeValue(null, BackupConstants.ASTRID_ATTR_VERSION)); + } catch (NumberFormatException e) { + // can't read version, assume max version + this.version = Integer.MAX_VALUE; + } + + while (xpp.next() != XmlPullParser.END_DOCUMENT) { + String tag = xpp.getName(); + if (tag == null || xpp.getEventType() == XmlPullParser.END_TAG) { + continue; + } + + try { + if (tag.equals(BackupConstants.TASK_TAG)) { + parseTask(); + } else if (tag.equals(BackupConstants.METADATA_TAG)) { + parseMetadata(3); + } else if (tag.equals(BackupConstants.TAGDATA_TAG)) { + parseTagdata(); + } + } catch (Exception e) { + errorCount++; + Log.e("astrid-importer", //$NON-NLS-1$ + "Caught exception while reading from " + //$NON-NLS-1$ + xpp.getText(), e); + } + } + } + + private void parseTagdata() { + tagdata.clear(); + deserializeModel(tagdata, TagData.PROPERTIES); + tagdataService.save(tagdata); + } + } + // =============================================================== FORMAT1 private static final String FORMAT1 = null;