diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksList.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksList.java index 55e302252..13599d5f5 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksList.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksList.java @@ -1,7 +1,6 @@ package com.todoroo.astrid.gtasks; import com.todoroo.andlib.data.Property.IntegerProperty; -import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.astrid.data.StoreObject; @@ -17,7 +16,7 @@ public class GtasksList { public static final String TYPE = "gtasks-list"; //$NON-NLS-1$ /** list id in g-tasks */ - public static final LongProperty REMOTE_ID = new LongProperty(StoreObject.TABLE, + public static final StringProperty REMOTE_ID = new StringProperty(StoreObject.TABLE, StoreObject.ITEM.name); /** list name */ diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java index 1a9748886..69eca6f83 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java @@ -66,7 +66,7 @@ public class GtasksListService { for(int i = 0; i < newLists.length(); i++) { JSONObject remote = newLists.getJSONObject(i); - long id = remote.optLong("id"); + String id = remote.getString("id"); StoreObject local = null; for(StoreObject list : lists) { if(list.getValue(GtasksList.REMOTE_ID).equals(id)) { diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadata.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadata.java index b7eb443a3..801e9b771 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadata.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksMetadata.java @@ -12,7 +12,7 @@ import com.todoroo.astrid.utility.Preferences; */ public class GtasksMetadata { - private static final int ORDERING_UNSET = -1; + private static final int VALUE_UNSET = -1; /** metadata key */ public static final String METADATA_KEY = "gtasks"; //$NON-NLS-1$ @@ -36,11 +36,12 @@ public class GtasksMetadata { public static Metadata createEmptyMetadata() { Metadata metadata = new Metadata(); metadata.setValue(Metadata.KEY, GtasksMetadata.METADATA_KEY); - metadata.setValue(ID, 0L); - metadata.setValue(LIST_ID, Preferences.getLong(GtasksUtilities.PREF_DEFAULT_LIST, 0)); - metadata.setValue(OWNER_ID, 0L); + metadata.setValue(ID, (long)VALUE_UNSET); + metadata.setValue(LIST_ID, Preferences.getLong(GtasksUtilities.PREF_DEFAULT_LIST, + VALUE_UNSET)); + metadata.setValue(OWNER_ID, (long)VALUE_UNSET); metadata.setValue(INDENTATION, 0); - metadata.setValue(ORDERING, ORDERING_UNSET); + metadata.setValue(ORDERING, VALUE_UNSET); return metadata; } diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDependencyInjector.java b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDependencyInjector.java new file mode 100644 index 000000000..3f72cd30c --- /dev/null +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDependencyInjector.java @@ -0,0 +1,56 @@ +/** + * See the file "LICENSE" for the full license governing this code. + */ +package org.weloveastrid.rmilk; + +import org.weloveastrid.rmilk.data.MilkListService; +import org.weloveastrid.rmilk.data.MilkMetadataService; + +import com.todoroo.andlib.service.AbstractDependencyInjector; +import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.andlib.service.ExceptionService.ErrorReporter; + +/** + * RTM Dependency Injection for service classes + * + * @author Tim Su + * + */ +public class MilkDependencyInjector extends AbstractDependencyInjector { + + /** + * variable to prevent multiple copies of this injector to be loaded + */ + private static MilkDependencyInjector instance = null; + + /** + * Initialize list of injectables. Special care must used when + * instantiating classes that themselves depend on dependency injection + * (i.e. {@link ErrorReporter}. + */ + @Override + @SuppressWarnings("nls") + protected void addInjectables() { + injectables.put("milkMetadataService", MilkMetadataService.class); + injectables.put("milkListService", MilkListService.class); + } + + /** + * Install this dependency injector + */ + public static void initialize() { + if(instance != null) + return; + synchronized(MilkDependencyInjector.class) { + if(instance == null) + instance = new MilkDependencyInjector(); + DependencyInjectionService.getInstance().addInjector(instance); + } + } + + MilkDependencyInjector() { + // prevent instantiation + super(); + } + +} diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDetailExposer.java b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDetailExposer.java index c3880a8d7..8a291d788 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDetailExposer.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkDetailExposer.java @@ -3,7 +3,8 @@ */ package org.weloveastrid.rmilk; -import org.weloveastrid.rmilk.data.MilkDataService; +import org.weloveastrid.rmilk.data.MilkListService; +import org.weloveastrid.rmilk.data.MilkMetadataService; import org.weloveastrid.rmilk.data.MilkNoteFields; import org.weloveastrid.rmilk.data.MilkTaskFields; @@ -13,7 +14,9 @@ import android.content.Intent; import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.data.Metadata; @@ -30,6 +33,9 @@ public class MilkDetailExposer extends BroadcastReceiver { public static final String DETAIL_SEPARATOR = " | "; //$NON-NLS-1$ + @Autowired private MilkMetadataService milkMetadataService; + @Autowired private MilkListService milkListService; + @Override public void onReceive(Context context, Intent intent) { ContextManager.setContext(context); @@ -56,7 +62,8 @@ public class MilkDetailExposer extends BroadcastReceiver { } public String getTaskDetails(Context context, long id, boolean extended) { - Metadata metadata = MilkDataService.getInstance(context).getTaskMetadata(id); + DependencyInjectionService.getInstance().inject(this); + Metadata metadata = milkMetadataService.getTaskMetadata(id); if(metadata == null) return null; @@ -64,7 +71,7 @@ public class MilkDetailExposer extends BroadcastReceiver { if(!extended) { long listId = metadata.getValue(MilkTaskFields.LIST_ID); - String listName = MilkDataService.getInstance(context).getListName(listId); + String listName = milkListService.getListName(listId); // RTM list is out of date. don't display RTM stuff if(listName == null) return null; @@ -78,7 +85,7 @@ public class MilkDetailExposer extends BroadcastReceiver { builder.append(context.getString(R.string.rmilk_TLA_repeat)).append(DETAIL_SEPARATOR); } } else { - TodorooCursor notesCursor = MilkDataService.getInstance(context).getTaskNotesCursor(id); + TodorooCursor notesCursor = milkMetadataService.getTaskNotesCursor(id); try { for(notesCursor.moveToFirst(); !notesCursor.isAfterLast(); notesCursor.moveToNext()) { metadata.readFromCursor(notesCursor); diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkFilterExposer.java b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkFilterExposer.java index 422cedbc4..ee52f7461 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkFilterExposer.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkFilterExposer.java @@ -3,8 +3,8 @@ */ package org.weloveastrid.rmilk; -import org.weloveastrid.rmilk.data.MilkDataService; import org.weloveastrid.rmilk.data.MilkListFields; +import org.weloveastrid.rmilk.data.MilkListService; import org.weloveastrid.rmilk.data.MilkTaskFields; import android.content.BroadcastReceiver; @@ -13,7 +13,9 @@ import android.content.Context; import android.content.Intent; import com.timsu.astrid.R; +import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.QueryTemplate; @@ -36,6 +38,8 @@ import com.todoroo.astrid.data.TaskApiDao.TaskCriteria; */ public class MilkFilterExposer extends BroadcastReceiver { + @Autowired private MilkListService milkListService; + private Filter filterFromList(Context context, StoreObject list) { String listName = list.getValue(MilkListFields.NAME); String title = context.getString(R.string.rmilk_FEx_list_title, @@ -64,7 +68,9 @@ public class MilkFilterExposer extends BroadcastReceiver { if(!MilkUtilities.INSTANCE.isLoggedIn()) return; - StoreObject[] lists = MilkDataService.getInstance(context).getLists(); + DependencyInjectionService.getInstance().inject(this); + + StoreObject[] lists = milkListService.getLists(); // If user does not have any tags, don't show this section at all if(lists.length == 0) diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkDataService.java b/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkDataService.java deleted file mode 100644 index 3a8ae31ce..000000000 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkDataService.java +++ /dev/null @@ -1,371 +0,0 @@ -/** - * See the file "LICENSE" for the full license governing this code. - */ -package org.weloveastrid.rmilk.data; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Random; - -import org.weloveastrid.rmilk.MilkUtilities; -import org.weloveastrid.rmilk.api.data.RtmList; -import org.weloveastrid.rmilk.api.data.RtmLists; -import org.weloveastrid.rmilk.sync.MilkTaskContainer; - -import android.content.Context; - -import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.TodorooCursor; -import com.todoroo.andlib.sql.Criterion; -import com.todoroo.andlib.sql.Order; -import com.todoroo.andlib.sql.Query; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.data.MetadataApiDao; -import com.todoroo.astrid.data.StoreObject; -import com.todoroo.astrid.data.StoreObjectApiDao; -import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.data.TaskApiDao; -import com.todoroo.astrid.data.MetadataApiDao.MetadataCriteria; -import com.todoroo.astrid.data.StoreObjectApiDao.StoreObjectCriteria; -import com.todoroo.astrid.data.TaskApiDao.TaskCriteria; - -public final class MilkDataService { - - /** metadata key of tag addon */ - public static final String TAG_KEY = "tags-tag"; //$NON-NLS-1$ - - // --- singleton - - private static MilkDataService instance = null; - - public static synchronized MilkDataService getInstance(Context context) { - if(instance == null) - instance = new MilkDataService(context); - return instance; - } - - // --- instance variables - - private final TaskApiDao taskDao; - private final MetadataApiDao metadataDao; - private final StoreObjectApiDao storeObjectDao; - - static final Random random = new Random(); - - private MilkDataService(Context context) { - // prevent instantiation - taskDao = new TaskApiDao(context); - storeObjectDao = new StoreObjectApiDao(context); - metadataDao = new MetadataApiDao(context); - } - - // --- task and metadata methods - - /** - * Clears RTM metadata information. Used when user logs out of RTM - */ - public void clearMetadata() { - metadataDao.deleteWhere(Metadata.KEY.eq(MilkTaskFields.METADATA_KEY)); - } - - /** - * Gets tasks that were modified since last sync. Used internally to - * support the other methods. - * - * @param properties - * @return cursor - */ - private TodorooCursor getLocallyModifiedHelper(Criterion criterion, Property... properties) { - long lastSyncDate = MilkUtilities.INSTANCE.getLastSyncDate(); - if(lastSyncDate == 0) - return taskDao.query(Query.select(Task.ID).where(criterion).orderBy(Order.asc(Task.ID))); - return - taskDao.query(Query.select(properties).where(Criterion.and(criterion, - Task.MODIFICATION_DATE.gt(lastSyncDate))).orderBy(Order.asc(Task.ID))); - } - - /** - * Gets milk task metadata for joining - * - * @return cursor - */ - private TodorooCursor getMilkTaskMetadata() { - return metadataDao.query(Query.select(Metadata.TASK).where( - MetadataCriteria.withKey(MilkTaskFields.METADATA_KEY)).orderBy(Order.asc(Metadata.TASK))); - } - - /** - * Gets tasks that were created since last sync - * @param properties - * @return - */ - public TodorooCursor getLocallyCreated(Property... properties) { - long lastSyncDate = MilkUtilities.INSTANCE.getLastSyncDate(); - TodorooCursor tasks; - if(lastSyncDate == 0) - tasks = taskDao.query(Query.select(Task.ID).where(TaskCriteria.isActive()).orderBy(Order.asc(Task.ID))); - else - tasks = taskDao.query(Query.select(Task.ID).where(Criterion.and(TaskCriteria.isActive(), - Task.CREATION_DATE.gt(lastSyncDate))).orderBy(Order.asc(Task.ID))); - - try { - TodorooCursor metadata = getMilkTaskMetadata(); - try { - ArrayList matchingRows = new ArrayList(); - joinRows(tasks, metadata, matchingRows, false); - - return - taskDao.query(Query.select(properties).where(Task.ID.in(matchingRows.toArray(new Long[matchingRows.size()])))); - } finally { - metadata.close(); - } - } finally { - tasks.close(); - } - } - - /** - * Gets tasks that were modified since last sync - * @param properties - * @return null if never sync'd - */ - public TodorooCursor getLocallyUpdated(Property... properties) { - TodorooCursor tasks; - long lastSyncDate = MilkUtilities.INSTANCE.getLastSyncDate(); - if(lastSyncDate == 0) - tasks = taskDao.query(Query.select(Task.ID).orderBy(Order.asc(Task.ID))); - else - tasks = taskDao.query(Query.select(Task.ID).where(Task.MODIFICATION_DATE. - gt(lastSyncDate)).orderBy(Order.asc(Task.ID))); - try { - TodorooCursor metadata = getMilkTaskMetadata(); - try { - - ArrayList matchingRows = new ArrayList(); - joinRows(tasks, metadata, matchingRows, true); - - return - taskDao.query(Query.select(properties).where(Task.ID.in(matchingRows.toArray(new Long[matchingRows.size()])))); - } finally { - metadata.close(); - } - } finally { - tasks.close(); - } - } - - /** - * Join rows from two cursors on the first column, assuming its an id column - * @param left - * @param right - * @param matchingRows - * @param both - if false, returns left join, if true, returns both join - */ - private static void joinRows(TodorooCursor left, - TodorooCursor right, ArrayList matchingRows, - boolean both) { - - left.moveToPosition(-1); - right.moveToFirst(); - - while(true) { - left.moveToNext(); - if(left.isAfterLast()) - break; - long leftValue = left.getLong(0); - - // advance right until it is equal or bigger - while(!right.isAfterLast() && right.getLong(0) < leftValue) { - right.moveToNext(); - } - - if(right.isAfterLast()) { - if(!both) - matchingRows.add(leftValue); - continue; - } - - if((right.getLong(0) == leftValue) == both) - matchingRows.add(leftValue); - } - } - - /** - * Searches for a local task with same remote id, updates this task's id - * @param remoteTask - */ - public void findLocalMatch(MilkTaskContainer remoteTask) { - if(remoteTask.task.getId() != Task.NO_ID) - return; - TodorooCursor cursor = metadataDao.query(Query.select(Metadata.TASK). - where(Criterion.and(MetadataCriteria.withKey(MilkTaskFields.METADATA_KEY), - MilkTaskFields.TASK_SERIES_ID.eq(remoteTask.taskSeriesId), - MilkTaskFields.TASK_ID.eq(remoteTask.taskId)))); - try { - if(cursor.getCount() == 0) - return; - cursor.moveToFirst(); - remoteTask.task.setId(cursor.get(Metadata.TASK)); - } finally { - cursor.close(); - } - } - - /** - * Saves a task and its metadata - * @param task - */ - public void saveTaskAndMetadata(MilkTaskContainer task) { - taskDao.save(task.task); - - task.metadata.add(MilkTaskFields.create(task)); - metadataDao.synchronizeMetadata(task.task.getId(), task.metadata, - Criterion.or(MetadataCriteria.withKey(TAG_KEY), - MetadataCriteria.withKey(MilkTaskFields.METADATA_KEY), - MetadataCriteria.withKey(MilkNoteFields.METADATA_KEY))); - } - - /** - * Reads a task and its metadata - * @param task - * @return - */ - public MilkTaskContainer readTaskAndMetadata(TodorooCursor taskCursor) { - Task task = new Task(taskCursor); - - // read tags, notes, etc - ArrayList metadata = new ArrayList(); - TodorooCursor metadataCursor = metadataDao.query(Query.select(Metadata.PROPERTIES). - where(Criterion.and(MetadataCriteria.byTask(task.getId()), - Criterion.or(MetadataCriteria.withKey(TAG_KEY), - MetadataCriteria.withKey(MilkTaskFields.METADATA_KEY), - MetadataCriteria.withKey(MilkNoteFields.METADATA_KEY))))); - try { - for(metadataCursor.moveToFirst(); !metadataCursor.isAfterLast(); metadataCursor.moveToNext()) { - metadata.add(new Metadata(metadataCursor)); - } - } finally { - metadataCursor.close(); - } - - return new MilkTaskContainer(task, metadata); - } - - /** - * Reads metadata out of a task - * @return null if no metadata found - */ - public Metadata getTaskMetadata(long taskId) { - TodorooCursor cursor = metadataDao.query(Query.select( - MilkTaskFields.LIST_ID, MilkTaskFields.TASK_SERIES_ID, MilkTaskFields.TASK_ID, MilkTaskFields.REPEATING).where( - MetadataCriteria.byTaskAndwithKey(taskId, MilkTaskFields.METADATA_KEY))); - try { - if(cursor.getCount() == 0) - return null; - cursor.moveToFirst(); - return new Metadata(cursor); - } finally { - cursor.close(); - } - } - - /** - * Reads task notes out of a task - */ - public TodorooCursor getTaskNotesCursor(long taskId) { - TodorooCursor cursor = metadataDao.query(Query.select(Metadata.PROPERTIES). - where(MetadataCriteria.byTaskAndwithKey(taskId, MilkNoteFields.METADATA_KEY))); - return cursor; - } - - // --- list methods - - private StoreObject[] lists = null; - - /** - * Reads dashboards - */ - private void readLists() { - if(lists != null) - return; - - TodorooCursor cursor = storeObjectDao.query(Query.select(StoreObject.PROPERTIES). - where(StoreObjectCriteria.byType(MilkListFields.TYPE)).orderBy(Order.asc(MilkListFields.POSITION))); - try { - lists = new StoreObject[cursor.getCount()]; - for(int i = 0; i < lists.length; i++) { - cursor.moveToNext(); - StoreObject list = new StoreObject(cursor); - lists[i] = list; - } - } finally { - cursor.close(); - } - } - - /** - * @return a list of lists - */ - public StoreObject[] getLists() { - readLists(); - return lists; - } - - /** - * Clears current cache of RTM lists and loads data from RTM into - * database. Returns the inbox list. - * - * @param remoteLists - * @return list with the name "inbox" - */ - public StoreObject setLists(RtmLists remoteLists) { - readLists(); - - StoreObject inbox = null; - for(Map.Entry remote : remoteLists.getLists().entrySet()) { - if(remote.getValue().isSmart() || "All Tasks".equals(remote.getValue().getName())) //$NON-NLS-1$ - continue; - - long id = Long.parseLong(remote.getValue().getId()); - StoreObject local = null; - for(StoreObject list : lists) { - if(list.getValue(MilkListFields.REMOTE_ID).equals(id)) { - local = list; - break; - } - } - - if(local == null) - local = new StoreObject(); - - local.setValue(StoreObject.TYPE, MilkListFields.TYPE); - local.setValue(MilkListFields.REMOTE_ID, id); - local.setValue(MilkListFields.NAME, remote.getValue().getName()); - local.setValue(MilkListFields.POSITION, remote.getValue().getPosition()); - local.setValue(MilkListFields.ARCHIVED, remote.getValue().isArchived() ? 1 : 0); - storeObjectDao.save(local); - - if(remote.getValue().isInbox()) { - inbox = local; - } - } - - // clear dashboard cache - lists = null; - return inbox; - } - - /** - * Get list name by list id - * @param listId - * @return null if no list by this id exists, otherwise list name - */ - public String getListName(long listId) { - readLists(); - for(StoreObject list : lists) - if(list.getValue(MilkListFields.REMOTE_ID).equals(listId)) - return list.getValue(MilkListFields.NAME); - return null; - } - -} diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkListService.java b/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkListService.java new file mode 100644 index 000000000..cea5620f8 --- /dev/null +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkListService.java @@ -0,0 +1,122 @@ +package org.weloveastrid.rmilk.data; + +import java.util.Map; + +import org.weloveastrid.rmilk.MilkDependencyInjector; +import org.weloveastrid.rmilk.api.data.RtmList; +import org.weloveastrid.rmilk.api.data.RtmLists; + +import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.sql.Order; +import com.todoroo.andlib.sql.Query; +import com.todoroo.astrid.data.StoreObject; +import com.todoroo.astrid.data.StoreObjectApiDao; +import com.todoroo.astrid.data.StoreObjectApiDao.StoreObjectCriteria; + +/** + * Service for reading and writing Milk lists + * + * @author Tim Su + * + */ +public class MilkListService { + + static { + MilkDependencyInjector.initialize(); + } + + private StoreObject[] lists = null; + + private final StoreObjectApiDao storeObjectDao; + + public MilkListService() { + storeObjectDao = new StoreObjectApiDao(ContextManager.getContext()); + } + + /** + * Reads lists + */ + private void readLists() { + if(lists != null) + return; + + TodorooCursor cursor = storeObjectDao.query(Query.select(StoreObject.PROPERTIES). + where(StoreObjectCriteria.byType(MilkListFields.TYPE)).orderBy(Order.asc(MilkListFields.POSITION))); + try { + lists = new StoreObject[cursor.getCount()]; + for(int i = 0; i < lists.length; i++) { + cursor.moveToNext(); + StoreObject list = new StoreObject(cursor); + lists[i] = list; + } + } finally { + cursor.close(); + } + } + + /** + * @return a list of lists + */ + public StoreObject[] getLists() { + readLists(); + return lists; + } + + /** + * Clears current cache of RTM lists and loads data from RTM into + * database. Returns the inbox list. + * + * @param remoteLists + * @return list with the name "inbox" + */ + public StoreObject setLists(RtmLists remoteLists) { + readLists(); + + StoreObject inbox = null; + for(Map.Entry remote : remoteLists.getLists().entrySet()) { + if(remote.getValue().isSmart() || "All Tasks".equals(remote.getValue().getName())) //$NON-NLS-1$ + continue; + + long id = Long.parseLong(remote.getValue().getId()); + StoreObject local = null; + for(StoreObject list : lists) { + if(list.getValue(MilkListFields.REMOTE_ID).equals(id)) { + local = list; + break; + } + } + + if(local == null) + local = new StoreObject(); + + local.setValue(StoreObject.TYPE, MilkListFields.TYPE); + local.setValue(MilkListFields.REMOTE_ID, id); + local.setValue(MilkListFields.NAME, remote.getValue().getName()); + local.setValue(MilkListFields.POSITION, remote.getValue().getPosition()); + local.setValue(MilkListFields.ARCHIVED, remote.getValue().isArchived() ? 1 : 0); + storeObjectDao.save(local); + + if(remote.getValue().isInbox()) { + inbox = local; + } + } + + // clear list cache + lists = null; + return inbox; + } + + /** + * Get list name by list id + * @param listId + * @return null if no list by this id exists, otherwise list name + */ + public String getListName(long listId) { + readLists(); + for(StoreObject list : lists) + if(list.getValue(MilkListFields.REMOTE_ID).equals(listId)) + return list.getValue(MilkListFields.NAME); + return null; + } +} diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkMetadataService.java b/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkMetadataService.java new file mode 100644 index 000000000..fba0fc4ff --- /dev/null +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/data/MilkMetadataService.java @@ -0,0 +1,70 @@ +/** + * See the file "LICENSE" for the full license governing this code. + */ +package org.weloveastrid.rmilk.data; + +import java.util.ArrayList; + +import org.weloveastrid.rmilk.MilkDependencyInjector; +import org.weloveastrid.rmilk.MilkUtilities; +import org.weloveastrid.rmilk.sync.MilkTaskContainer; + +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.astrid.data.Metadata; +import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.data.MetadataApiDao.MetadataCriteria; +import com.todoroo.astrid.sync.SyncMetadataService; +import com.todoroo.astrid.sync.SyncProviderUtilities; + +public final class MilkMetadataService extends SyncMetadataService{ + + static { + MilkDependencyInjector.initialize(); + } + + public MilkMetadataService() { + super(ContextManager.getContext()); + } + + @Override + public MilkTaskContainer createContainerFromLocalTask(Task task, + ArrayList metadata) { + return new MilkTaskContainer(task, metadata); + } + + @Override + public Criterion getLocalMatchCriteria(MilkTaskContainer remoteTask) { + return Criterion.and(MilkTaskFields.TASK_SERIES_ID.eq(remoteTask.taskSeriesId), + MilkTaskFields.TASK_ID.eq(remoteTask.taskId)); + } + + @Override + public Criterion getMetadataCriteria() { + return Criterion.or(MetadataCriteria.withKey(TAG_KEY), + MetadataCriteria.withKey(MilkTaskFields.METADATA_KEY), + MetadataCriteria.withKey(MilkNoteFields.METADATA_KEY)); + } + + @Override + public String getMetadataKey() { + return MilkTaskFields.METADATA_KEY; + } + + @Override + public SyncProviderUtilities getUtilities() { + return MilkUtilities.INSTANCE; + } + + /** + * Reads task notes out of a task + */ + public TodorooCursor getTaskNotesCursor(long taskId) { + TodorooCursor cursor = metadataDao.query(Query.select(Metadata.PROPERTIES). + where(MetadataCriteria.byTaskAndwithKey(taskId, MilkNoteFields.METADATA_KEY))); + return cursor; + } + +} diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkSyncProvider.java b/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkSyncProvider.java index 462713f8f..8e7487e61 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkSyncProvider.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkSyncProvider.java @@ -27,7 +27,8 @@ import org.weloveastrid.rmilk.api.data.RtmTaskSeries; import org.weloveastrid.rmilk.api.data.RtmTasks; import org.weloveastrid.rmilk.api.data.RtmAuth.Perms; import org.weloveastrid.rmilk.api.data.RtmTask.Priority; -import org.weloveastrid.rmilk.data.MilkDataService; +import org.weloveastrid.rmilk.data.MilkListService; +import org.weloveastrid.rmilk.data.MilkMetadataService; import org.weloveastrid.rmilk.data.MilkNoteFields; import android.app.Activity; @@ -44,7 +45,9 @@ import android.util.Log; import com.timsu.astrid.R; import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DialogUtilities; @@ -57,7 +60,9 @@ public class MilkSyncProvider extends SyncProvider { private ServiceImpl rtmService = null; private String timeline = null; - private MilkDataService dataService = null; + + @Autowired private MilkMetadataService milkMetadataService; + @Autowired private MilkListService milkListService; // ---------------------------------------------------------------------- // ------------------------------------------------------- public methods @@ -67,11 +72,12 @@ public class MilkSyncProvider extends SyncProvider { * Sign out of RTM, deleting all synchronization metadata */ public void signOut(Context context) { + ContextManager.setContext(context); MilkUtilities.INSTANCE.setToken(null); MilkUtilities.INSTANCE.clearLastSyncDate(); - dataService = MilkDataService.getInstance(context); - dataService.clearMetadata(); + DependencyInjectionService.getInstance().inject(this); + milkMetadataService.clearMetadata(); } /** @@ -144,7 +150,7 @@ public class MilkSyncProvider extends SyncProvider { @Override @SuppressWarnings("nls") protected void initiateBackground(Service service) { - dataService = MilkDataService.getInstance(service); + DependencyInjectionService.getInstance().inject(this); try { String authToken = MilkUtilities.INSTANCE.getToken(); @@ -247,7 +253,7 @@ public class MilkSyncProvider extends SyncProvider { // load RTM lists RtmLists lists = rtmService.lists_getList(); - dataService.setLists(lists); + milkListService.setLists(lists); // read all tasks ArrayList remoteChanges = new ArrayList(); @@ -324,10 +330,10 @@ public class MilkSyncProvider extends SyncProvider { */ private SyncData populateSyncData(ArrayList remoteTasks) { // fetch locally created tasks - TodorooCursor localCreated = dataService.getLocallyCreated(PROPERTIES); + TodorooCursor localCreated = milkMetadataService.getLocallyCreated(PROPERTIES); // fetch locally updated tasks - TodorooCursor localUpdated = dataService.getLocallyUpdated(PROPERTIES); + TodorooCursor localUpdated = milkMetadataService.getLocallyUpdated(PROPERTIES); return new SyncData(remoteTasks, localCreated, localUpdated); } @@ -344,7 +350,7 @@ public class MilkSyncProvider extends SyncProvider { if(remote.task.hasDueDate() && remote.task.getValue(Task.DUE_DATE) < DateUtilities.now()) remote.task.setFlag(Task.REMINDER_FLAGS, Task.NOTIFY_AFTER_DEADLINE, false); - dataService.findLocalMatch(remote); + milkMetadataService.findLocalMatch(remote); list.add(remote); } } @@ -453,11 +459,11 @@ public class MilkSyncProvider extends SyncProvider { HashSet localTags = new HashSet(); HashSet remoteTags = new HashSet(); for(Metadata item : local.metadata) - if(MilkDataService.TAG_KEY.equals(item.getValue(Metadata.KEY))) + if(MilkMetadataService.TAG_KEY.equals(item.getValue(Metadata.KEY))) localTags.add(item.getValue(Metadata.VALUE1)); if(remote != null && remote.metadata != null) { for(Metadata item : remote.metadata) - if(MilkDataService.TAG_KEY.equals(item.getValue(Metadata.KEY))) + if(MilkMetadataService.TAG_KEY.equals(item.getValue(Metadata.KEY))) remoteTags.add(item.getValue(Metadata.VALUE1)); } if(!localTags.equals(remoteTags)) { @@ -517,7 +523,7 @@ public class MilkSyncProvider extends SyncProvider { if(rtmTaskSeries.getTags() != null) { for(String tag : rtmTaskSeries.getTags()) { Metadata tagData = new Metadata(); - tagData.setValue(Metadata.KEY, MilkDataService.TAG_KEY); + tagData.setValue(Metadata.KEY, MilkMetadataService.TAG_KEY); tagData.setValue(Metadata.VALUE1, tag); metadata.add(tagData); } @@ -558,12 +564,12 @@ public class MilkSyncProvider extends SyncProvider { @Override protected MilkTaskContainer read(TodorooCursor cursor) throws IOException { - return dataService.readTaskAndMetadata(cursor); + return milkMetadataService.readTaskAndMetadata(cursor); } @Override protected void write(MilkTaskContainer task) throws IOException { - dataService.saveTaskAndMetadata(task); + milkMetadataService.saveTaskAndMetadata(task); } // ---------------------------------------------------------------------- diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkTaskContainer.java b/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkTaskContainer.java index 98d02a471..997c47158 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkTaskContainer.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/sync/MilkTaskContainer.java @@ -59,5 +59,10 @@ public class MilkTaskContainer extends SyncContainer { } } + @Override + public void prepareForSaving() { + super.prepareForSaving(); + metadata.add(MilkTaskFields.create(this)); + } } \ No newline at end of file