diff --git a/astrid/api-src/com/todoroo/astrid/api/SynchronizationProvider.java b/astrid/api-src/com/todoroo/astrid/api/SynchronizationProvider.java index f2a8b8dcf..13784cbb6 100644 --- a/astrid/api-src/com/todoroo/astrid/api/SynchronizationProvider.java +++ b/astrid/api-src/com/todoroo/astrid/api/SynchronizationProvider.java @@ -93,7 +93,7 @@ public abstract class SynchronizationProvider { * * @param task */ - abstract protected void save(TYPE task) throws IOException; + abstract protected void write(TYPE task) throws IOException; /** * Finds a task in the list with the same remote identifier(s) as @@ -223,7 +223,7 @@ public abstract class SynchronizationProvider { } else { create((TYPE)local); } - save((TYPE)local); + write((TYPE)local); } // 2. UPDATE: for each updated local task @@ -284,7 +284,7 @@ public abstract class SynchronizationProvider { postUpdate(context, r.getString(R.string.SyP_progress_remotetx, remote.task.getValue(Task.TITLE))); - save((TYPE)remote); + write((TYPE)remote); } } diff --git a/astrid/api-src/com/todoroo/astrid/api/TaskContainer.java b/astrid/api-src/com/todoroo/astrid/api/TaskContainer.java index 03da9c61e..a12e08394 100644 --- a/astrid/api-src/com/todoroo/astrid/api/TaskContainer.java +++ b/astrid/api-src/com/todoroo/astrid/api/TaskContainer.java @@ -1,5 +1,7 @@ package com.todoroo.astrid.api; +import java.util.ArrayList; + import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Task; @@ -12,10 +14,5 @@ import com.todoroo.astrid.model.Task; */ public class TaskContainer { public Task task; - public Metadata[] metadata; - - public TaskContainer(Task task, Metadata[] metadata) { - this.task = task; - this.metadata = metadata; - } + public ArrayList metadata; } \ No newline at end of file diff --git a/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java b/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java index 866b89e4c..bd32c7f43 100644 --- a/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java +++ b/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java @@ -33,6 +33,7 @@ import com.todoroo.astrid.rmilk.Utilities; import com.todoroo.astrid.rmilk.Utilities.ListContainer; import com.todoroo.astrid.rmilk.api.data.RtmList; import com.todoroo.astrid.rmilk.api.data.RtmLists; +import com.todoroo.astrid.rmilk.sync.RTMTaskContainer; public final class MilkDataService { @@ -132,20 +133,20 @@ public final class MilkDataService { /** * Searches for a local task with same remote id, updates this task's id - * @param task + * @param remoteTask */ - public void updateFromLocalCopy(Task task) { - if(task.getId() != Task.NO_ID) + public void findLocalMatch(RTMTaskContainer remoteTask) { + if(remoteTask.task.getId() != Task.NO_ID) return; TodorooCursor cursor = taskDao.query(Query.select(Task.ID). join(METADATA_JOIN).where(Criterion.and(MetadataCriteria.withKey(METADATA_KEY), - TASK_SERIES_ID.eq(task.getValue(TASK_SERIES_ID)), - TASK_ID.eq(task.getValue(TASK_ID))))); + TASK_SERIES_ID.eq(remoteTask.taskSeriesId), + TASK_ID.eq(remoteTask.taskId)))); try { if(cursor.getCount() == 0) return; cursor.moveToFirst(); - task.setId(cursor.get(Task.ID)); + remoteTask.task.setId(cursor.get(Task.ID)); } finally { cursor.close(); } @@ -155,25 +156,15 @@ public final class MilkDataService { * Saves a task and its metadata * @param task */ - public void saveTaskAndMetadata(Task task) { - Metadata metadata = new Metadata(); - metadata.setValue(Metadata.KEY, METADATA_KEY); - metadata.setValue(LIST_ID, task.getValue(LIST_ID)); - metadata.setValue(TASK_SERIES_ID, task.getValue(TASK_SERIES_ID)); - metadata.setValue(TASK_ID, task.getValue(TASK_ID)); - metadata.setValue(REPEATING, task.getValue(REPEATING)); - - task.clearValue(LIST_ID); - task.clearValue(TASK_SERIES_ID); - task.clearValue(TASK_ID); - task.clearValue(REPEATING); - - taskDao.save(task, true); - metadata.setValue(Metadata.TASK, task.getId()); - - metadataDao.deleteWhere(MetadataCriteria.byTaskAndwithKey(task.getId(), + public void saveTaskAndMetadata(RTMTaskContainer task) { + taskDao.save(task.task, true); + + metadataDao.deleteWhere(MetadataCriteria.byTaskAndwithKey(task.task.getId(), METADATA_KEY)); - metadataDao.persist(metadata); + for(Metadata metadata : task.metadata) { + metadata.setValue(Metadata.TASK, task.task.getId()); + metadataDao.persist(metadata); + } } /** diff --git a/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMSyncProvider.java index 2d674ddb3..8ada00ae1 100644 --- a/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMSyncProvider.java @@ -27,6 +27,7 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.astrid.api.SynchronizationProvider; import com.todoroo.astrid.api.TaskContainer; +import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Task; import com.todoroo.astrid.rmilk.MilkLoginActivity; import com.todoroo.astrid.rmilk.Utilities; @@ -44,6 +45,7 @@ import com.todoroo.astrid.rmilk.api.data.RtmAuth.Perms; import com.todoroo.astrid.rmilk.api.data.RtmTask.Priority; import com.todoroo.astrid.rmilk.data.MilkDataService; import com.todoroo.astrid.service.AstridDependencyInjector; +import com.todoroo.astrid.tags.TagService; public class RTMSyncProvider extends SynchronizationProvider { @@ -285,14 +287,9 @@ public class RTMSyncProvider extends SynchronizationProvider { } // ---------------------------------------------------------------------- - // ------------------------------------------------------- helper methods + // ------------------------------------------------------------ sync data // ---------------------------------------------------------------------- - @Override - protected String getNotificationTitle(Context context) { - return context.getString(R.string.rmilk_notification_title); - } - // all synchronized properties private static final Property[] PROPERTIES = new Property[] { Task.ID, @@ -323,13 +320,27 @@ public class RTMSyncProvider extends SynchronizationProvider { private void addTasksToList(RtmTasks tasks, ArrayList list) { for (RtmTaskList taskList : tasks.getLists()) { for (RtmTaskSeries taskSeries : taskList.getSeries()) { - TaskContainer remoteTask = parseRemoteTask(taskSeries); - dataService.updateFromLocalCopy(task); + RTMTaskContainer remoteTask = parseRemoteTask(taskSeries); + dataService.findLocalMatch(remoteTask); list.add(remoteTask); } } } + + // ---------------------------------------------------------------------- + // ------------------------------------------------- create / push / pull + // ---------------------------------------------------------------------- + + @Override + protected void create(RTMTaskContainer task) throws IOException { + RtmTaskSeries rtmTask = rtmService.tasks_add(timeline, task.listId, + task.task.getValue(Task.TITLE)); + RTMTaskContainer newRemoteTask = parseRemoteTask(rtmTask); + transferIdentifiers(newRemoteTask, task); + push(task, newRemoteTask); + } + /** * Determine whether this task's property should be transmitted * @param task task to consider @@ -349,15 +360,6 @@ public class RTMSyncProvider extends SynchronizationProvider { remoteTask.task.getValue(property)); } - @Override - protected void create(RTMTaskContainer task) throws IOException { - RtmTaskSeries rtmTask = rtmService.tasks_add(timeline, task.listId, - task.task.getValue(Task.TITLE)); - RTMTaskContainer newRemoteTask = parseRemoteTask(rtmTask); - transferIdentifiers(newRemoteTask, task); - push(task, newRemoteTask); - } - /** * Send changes for the given Task across the wire. If a remoteTask is * supplied, we attempt to intelligently only transmit the values that @@ -371,7 +373,7 @@ public class RTMSyncProvider extends SynchronizationProvider { if(shouldTransmit(local, Task.TITLE, remote)) rtmService.tasks_setName(timeline, local.listId, local.taskSeriesId, - local.taskId, local.getValue(Task.TITLE)); + local.taskId, local.task.getValue(Task.TITLE)); if(shouldTransmit(local, Task.IMPORTANCE, remote)) rtmService.tasks_setPriority(timeline, local.listId, local.taskSeriesId, local.taskId, Priority.values()[local.task.getValue(Task.IMPORTANCE)]); @@ -392,7 +394,7 @@ public class RTMSyncProvider extends SynchronizationProvider { rtmService.tasks_delete(timeline, local.listId, local.taskSeriesId, local.taskId); - // TODO tags, notes, url, ... + // TODO tags, notes if(remote != null && local.listId != null && !AndroidUtilities.equals(local.listId, remote.listId)) @@ -400,23 +402,21 @@ public class RTMSyncProvider extends SynchronizationProvider { local.listId, local.taskSeriesId, local.taskId); } - @Override - protected void save(RTMTaskContainer task) throws IOException { - // if task has no id, try to find a corresponding task - dataService.saveTaskAndMetadata(task); - } /** Create a task proxy for the given RtmTaskSeries */ private RTMTaskContainer parseRemoteTask(RtmTaskSeries rtmTaskSeries) { Task task = new Task(); + RtmTask rtmTask = rtmTaskSeries.getTask(); + ArrayList metadata = new ArrayList(); - task.setValue(MilkDataService.LIST_ID, Long.parseLong(rtmTaskSeries.getList().getId())); - task.setValue(MilkDataService.TASK_SERIES_ID, Long.parseLong(rtmTaskSeries.getId())); - task.setValue(Task.TITLE, rtmTaskSeries.getName()); - task.setValue(MilkDataService.REPEATING, rtmTaskSeries.hasRecurrence() ? 1 : 0); + Metadata rtmMetadata = new Metadata(); + metadata.add(rtmMetadata); + rtmMetadata.setValue(MilkDataService.LIST_ID, Long.parseLong(rtmTaskSeries.getList().getId())); + rtmMetadata.setValue(MilkDataService.TASK_SERIES_ID, Long.parseLong(rtmTaskSeries.getId())); + rtmMetadata.setValue(MilkDataService.REPEATING, rtmTaskSeries.hasRecurrence() ? 1 : 0); + rtmMetadata.setValue(MilkDataService.TASK_ID, Long.parseLong(rtmTask.getId())); - RtmTask rtmTask = rtmTaskSeries.getTask(); - task.setValue(MilkDataService.TASK_ID, Long.parseLong(rtmTask.getId())); + task.setValue(Task.TITLE, rtmTaskSeries.getName()); task.setValue(Task.CREATION_DATE, DateUtilities.dateToUnixtime(rtmTask.getAdded())); task.setValue(Task.COMPLETION_DATE, DateUtilities.dateToUnixtime(rtmTask.getCompleted())); task.setValue(Task.DELETION_DATE, DateUtilities.dateToUnixtime(rtmTask.getDeleted())); @@ -429,40 +429,73 @@ public class RTMSyncProvider extends SynchronizationProvider { } task.setValue(Task.IMPORTANCE, rtmTask.getPriority().ordinal()); - task.setValue(RTM_TAGS, rtmTaskSeries.getTags()); + for(String tag : rtmTaskSeries.getTags()) { + Metadata tagData = new Metadata(); + tagData.setValue(Metadata.KEY, TagService.KEY); + tagData.setValue(TagService.TAG, tag); + metadata.add(tagData); + } + + // TODO notes + + RTMTaskContainer container = new RTMTaskContainer(task, metadata, + rtmTaskSeries.getList().getId(), rtmTaskSeries.getId(), rtmTask.getId()); + return container; + } + + @Override + protected RTMTaskContainer pull(RTMTaskContainer task) throws IOException { + if(task.taskSeriesId == null) + throw new ServiceInternalException("Tried to read an invalid task"); //$NON-NLS-1$ + RtmTaskSeries rtmTask = rtmService.tasks_getTask(task.taskSeriesId, + task.task.getValue(Task.TITLE)); + if(rtmTask != null) + return parseRemoteTask(rtmTask); + return null; + } + + // ---------------------------------------------------------------------- + // --------------------------------------------------------- read / write + // ---------------------------------------------------------------------- + + @Override + protected void write(RTMTaskContainer task) throws IOException { + // if task has no id, try to find a corresponding task + dataService.saveTaskAndMetadata(task); + } - return task; + @Override + protected RTMTaskContainer read(TodorooCursor task) throws IOException { + return null; } + // ---------------------------------------------------------------------- + // --------------------------------------------------------- misc helpers + // ---------------------------------------------------------------------- + @Override protected int matchTask(ArrayList tasks, RTMTaskContainer target) { int length = tasks.size(); for(int i = 0; i < length; i++) { - Task task = tasks.get(i); - if(task.getValue(MilkDataService.LIST_ID).equals(target.getValue(MilkDataService.LIST_ID)) && - task.getValue(MilkDataService.TASK_SERIES_ID).equals(target.getValue(MilkDataService.TASK_SERIES_ID)) && - task.getValue(MilkDataService.TASK_ID).equals(target.getValue(MilkDataService.TASK_ID))) - return task; + RTMTaskContainer task = tasks.get(i); + if(AndroidUtilities.equals(task.listId, target.listId) && + AndroidUtilities.equals(task.taskSeriesId, target.taskSeriesId) && + AndroidUtilities.equals(task.taskId, target.taskId)) + return i; } - return null; + return -1; } @Override - protected RTMTaskContainer pull(RTMTaskContainer task) throws IOException { - if(task.getValue(MilkDataService.TASK_SERIES_ID) == 0) - throw new ServiceInternalException("Tried to read an invalid task"); //$NON-NLS-1$ - RtmTaskSeries rtmTask = rtmService.tasks_getTask(Long.toString(task.getValue(MilkDataService.TASK_SERIES_ID)), - task.getValue(Task.TITLE)); - if(rtmTask != null) - return parseRemoteTask(rtmTask); - return null; + protected String getNotificationTitle(Context context) { + return context.getString(R.string.rmilk_notification_title); } @Override protected void transferIdentifiers(RTMTaskContainer source, RTMTaskContainer destination) { - destination.setValue(MilkDataService.LIST_ID, source.getValue(MilkDataService.LIST_ID)); - destination.setValue(MilkDataService.TASK_SERIES_ID, source.getValue(MilkDataService.TASK_SERIES_ID)); - destination.setValue(MilkDataService.TASK_ID, source.getValue(MilkDataService.TASK_ID)); + destination.listId = source.listId; + destination.taskSeriesId = source.taskSeriesId; + destination.taskId = source.taskId; } // ---------------------------------------------------------------------- diff --git a/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMTaskContainer.java b/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMTaskContainer.java index fd5d48c0b..61ea76454 100644 --- a/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMTaskContainer.java +++ b/astrid/plugin-src/com/todoroo/astrid/rmilk/sync/RTMTaskContainer.java @@ -1,15 +1,18 @@ package com.todoroo.astrid.rmilk.sync; +import java.util.ArrayList; + import com.todoroo.astrid.api.TaskContainer; import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Task; public class RTMTaskContainer extends TaskContainer { - public String listId, taskSeriesId, taskId; + public long listId, taskSeriesId, taskId; - public RTMTaskContainer(Task task, Metadata[] metadata, - String listId, String taskSeriesId, String taskId) { - super(task, metadata); + public RTMTaskContainer(Task task, ArrayList metadata, + long listId, long taskSeriesId, long taskId) { + this.task = task; + this.metadata = metadata; this.listId = listId; this.taskSeriesId = taskSeriesId; this.taskId = taskId;