Refactored to create a new gtasks task list updater class for handling task list ops

pull/14/head
Tim Su 15 years ago
parent 248791d378
commit 44920567b0

@ -22,6 +22,7 @@ import com.todoroo.astrid.utility.Flags;
abstract public class GtasksIndentAction extends BroadcastReceiver { abstract public class GtasksIndentAction extends BroadcastReceiver {
@Autowired private GtasksMetadataService gtasksMetadataService; @Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
abstract int getDelta(); abstract int getDelta();
@ -43,7 +44,7 @@ abstract public class GtasksIndentAction extends BroadcastReceiver {
metadata.setValue(GtasksMetadata.INDENT, newIndent); metadata.setValue(GtasksMetadata.INDENT, newIndent);
PluginServices.getMetadataService().save(metadata); PluginServices.getMetadataService().save(metadata);
gtasksMetadataService.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID)); gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
Flags.set(Flags.REFRESH); Flags.set(Flags.REFRESH);
Toast.makeText(context, context.getString(R.string.gtasks_indent_toast, newIndent), Toast.makeText(context, context.getString(R.string.gtasks_indent_toast, newIndent),

@ -4,21 +4,13 @@
package com.todoroo.astrid.gtasks; package com.todoroo.astrid.gtasks;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.sync.GtasksTaskContainer; import com.todoroo.astrid.gtasks.sync.GtasksTaskContainer;
import com.todoroo.astrid.sync.SyncMetadataService; import com.todoroo.astrid.sync.SyncMetadataService;
@ -33,7 +25,6 @@ import com.todoroo.astrid.sync.SyncProviderUtilities;
public final class GtasksMetadataService extends SyncMetadataService<GtasksTaskContainer> { public final class GtasksMetadataService extends SyncMetadataService<GtasksTaskContainer> {
@Autowired private GtasksPreferenceService gtasksPreferenceService; @Autowired private GtasksPreferenceService gtasksPreferenceService;
@Autowired private GtasksListService gtasksListService;
public GtasksMetadataService() { public GtasksMetadataService() {
super(ContextManager.getContext()); super(ContextManager.getContext());
@ -66,113 +57,4 @@ public final class GtasksMetadataService extends SyncMetadataService<GtasksTaskC
return gtasksPreferenceService; return gtasksPreferenceService;
} }
/**
* Update order and parent fields for all tasks in the given list
* @param listId
*/
public void updateMetadataForList(String listId) {
StoreObject list = gtasksListService.getList(listId);
if(list == GtasksListService.LIST_NOT_FOUND_OBJECT)
return;
final ArrayList<Long> ids = new ArrayList<Long>();
final Stack<Long> taskHierarchyStack = new Stack<Long>();
final AtomicInteger order = new AtomicInteger(0);
final AtomicInteger previousIndent = new AtomicInteger(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId) {
ids.add(taskId);
Metadata metadata = getTaskMetadata(taskId);
if(metadata == null)
return;
metadata.setValue(GtasksMetadata.ORDER, order.getAndAdd(1));
int indent = metadata.getValue(GtasksMetadata.INDENT);
for(int i = indent; i <= previousIndent.get(); i++) {
if(!taskHierarchyStack.isEmpty())
taskHierarchyStack.pop();
}
if(indent > 0) {
if(taskHierarchyStack.isEmpty()) {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
metadata.setValue(GtasksMetadata.INDENT, 0);
} else
metadata.setValue(GtasksMetadata.PARENT_TASK, taskHierarchyStack.peek());
} else {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
}
PluginServices.getMetadataService().save(metadata);
taskHierarchyStack.push(taskId);
previousIndent.set(indent);
}
});
PluginServices.getTaskService().clearDetails(Task.ID.in(ids));
}
/**
* Create a local tree of tasks to expedite sibling and parent lookups
*/
public void createParentSiblingMaps() {
final HashMap<Long, Long> parents = new HashMap<Long, Long>();
final HashMap<Long, Long> siblings = new HashMap<Long, Long>();
for(StoreObject list : gtasksListService.getLists()) {
final AtomicLong previousTask = new AtomicLong(-1L);
final AtomicInteger previousIndent = new AtomicInteger(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId) {
Metadata metadata = getTaskMetadata(taskId);
if(metadata == null)
return;
int indent = metadata.getValue(GtasksMetadata.INDENT);
final long parent, sibling;
if(indent > previousIndent.get()) {
parent = previousTask.get();
sibling = -1L;
} else if(indent == previousIndent.get()) {
sibling = previousTask.get();
parent = parents.get(sibling);
} else {
sibling = parents.get(previousTask.get());
parent = parents.get(sibling);
}
parents.put(taskId, parent);
siblings.put(taskId, sibling);
previousTask.set(taskId);
previousIndent.set(indent);
}
});
}
}
private interface ListIterator {
public void processTask(long taskId);
}
private void iterateThroughList(StoreObject list, ListIterator iterator) {
Filter filter = GtasksFilterExposer.filterFromList(list);
TodorooCursor<Task> cursor = PluginServices.getTaskService().fetchFiltered(filter.sqlQuery, null, Task.ID);
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
long taskId = cursor.getLong(0);
iterator.processTask(taskId);
}
} finally {
cursor.close();
}
}
} }

@ -23,6 +23,7 @@ import com.todoroo.astrid.utility.Flags;
abstract public class GtasksOrderAction extends BroadcastReceiver { abstract public class GtasksOrderAction extends BroadcastReceiver {
@Autowired private GtasksMetadataService gtasksMetadataService; @Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
abstract int getDelta(); abstract int getDelta();
@ -38,7 +39,7 @@ abstract public class GtasksOrderAction extends BroadcastReceiver {
if(metadata == null) if(metadata == null)
return; return;
gtasksMetadataService.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID)); gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
metadata = gtasksMetadataService.getTaskMetadata(taskId); metadata = gtasksMetadataService.getTaskMetadata(taskId);
int oldOrder = metadata.getValue(GtasksMetadata.ORDER); int oldOrder = metadata.getValue(GtasksMetadata.ORDER);

@ -0,0 +1,142 @@
package com.todoroo.astrid.gtasks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import android.text.TextUtils;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.data.Task;
public class GtasksTaskListUpdater {
@Autowired private GtasksListService gtasksListService;
@Autowired private GtasksMetadataService gtasksMetadataService;
private final HashMap<Long, Long> parents = new HashMap<Long, Long>();
private final HashMap<Long, Long> siblings = new HashMap<Long, Long>();
private final HashMap<Long, String> localToRemoteIdMap =
new HashMap<Long, String>();
public GtasksTaskListUpdater() {
DependencyInjectionService.getInstance().inject(this);
}
/**
* Update order and parent fields for all tasks in the given list
* @param listId
*/
public void updateMetadataForList(String listId) {
StoreObject list = gtasksListService.getList(listId);
if(list == GtasksListService.LIST_NOT_FOUND_OBJECT)
return;
final ArrayList<Long> ids = new ArrayList<Long>();
final Stack<Long> taskHierarchyStack = new Stack<Long>();
final AtomicInteger order = new AtomicInteger(0);
final AtomicInteger previousIndent = new AtomicInteger(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId) {
ids.add(taskId);
Metadata metadata = gtasksMetadataService.getTaskMetadata(taskId);
if(metadata == null)
return;
metadata.setValue(GtasksMetadata.ORDER, order.getAndAdd(1));
int indent = metadata.getValue(GtasksMetadata.INDENT);
for(int i = indent; i <= previousIndent.get(); i++) {
if(!taskHierarchyStack.isEmpty())
taskHierarchyStack.pop();
}
if(indent > 0) {
if(taskHierarchyStack.isEmpty()) {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
metadata.setValue(GtasksMetadata.INDENT, 0);
} else
metadata.setValue(GtasksMetadata.PARENT_TASK, taskHierarchyStack.peek());
} else {
metadata.setValue(GtasksMetadata.PARENT_TASK, 0L);
}
PluginServices.getMetadataService().save(metadata);
taskHierarchyStack.push(taskId);
previousIndent.set(indent);
}
});
PluginServices.getTaskService().clearDetails(Task.ID.in(ids));
}
/**
* Create a local tree of tasks to expedite sibling and parent lookups
*/
public void createParentSiblingMaps() {
for(StoreObject list : gtasksListService.getLists()) {
final AtomicLong previousTask = new AtomicLong(-1L);
final AtomicInteger previousIndent = new AtomicInteger(-1);
iterateThroughList(list, new ListIterator() {
@Override
public void processTask(long taskId) {
Metadata metadata = gtasksMetadataService.getTaskMetadata(taskId);
if(metadata == null)
return;
int indent = metadata.getValue(GtasksMetadata.INDENT);
final long parent, sibling;
if(indent > previousIndent.get()) {
parent = previousTask.get();
sibling = -1L;
} else if(indent == previousIndent.get()) {
sibling = previousTask.get();
parent = parents.get(sibling);
} else {
sibling = parents.get(previousTask.get());
parent = parents.get(sibling);
}
parents.put(taskId, parent);
siblings.put(taskId, sibling);
previousTask.set(taskId);
previousIndent.set(indent);
if(!TextUtils.isEmpty(metadata.getValue(GtasksMetadata.ID)))
localToRemoteIdMap.put(taskId, metadata.getValue(GtasksMetadata.ID));
}
});
}
}
private interface ListIterator {
public void processTask(long taskId);
}
private void iterateThroughList(StoreObject list, ListIterator iterator) {
Filter filter = GtasksFilterExposer.filterFromList(list);
TodorooCursor<Task> cursor = PluginServices.getTaskService().fetchFiltered(filter.sqlQuery, null, Task.ID);
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
long taskId = cursor.getLong(0);
iterator.processTask(taskId);
}
} finally {
cursor.close();
}
}
}

@ -38,6 +38,7 @@ import com.todoroo.astrid.gtasks.GtasksMetadata;
import com.todoroo.astrid.gtasks.GtasksMetadataService; import com.todoroo.astrid.gtasks.GtasksMetadataService;
import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksPreferences; import com.todoroo.astrid.gtasks.GtasksPreferences;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.producteev.ProducteevBackgroundService; import com.todoroo.astrid.producteev.ProducteevBackgroundService;
import com.todoroo.astrid.producteev.ProducteevLoginActivity; import com.todoroo.astrid.producteev.ProducteevLoginActivity;
import com.todoroo.astrid.producteev.ProducteevUtilities; import com.todoroo.astrid.producteev.ProducteevUtilities;
@ -66,6 +67,7 @@ public class GtasksSyncProvider extends SyncProvider<GtasksTaskContainer> {
@Autowired private GtasksListService gtasksListService; @Autowired private GtasksListService gtasksListService;
@Autowired private GtasksMetadataService gtasksMetadataService; @Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksPreferenceService gtasksPreferenceService; @Autowired private GtasksPreferenceService gtasksPreferenceService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
/** google task service fields */ /** google task service fields */
private GoogleTaskService taskService = null; private GoogleTaskService taskService = null;
@ -214,7 +216,7 @@ public class GtasksSyncProvider extends SyncProvider<GtasksTaskContainer> {
gtasksListService.updateLists(taskView.getAllLists()); gtasksListService.updateLists(taskView.getAllLists());
gtasksMetadataService.createParentSiblingMaps(); gtasksTaskListUpdater.createParentSiblingMaps();
// batched read tasks for each list // batched read tasks for each list
ArrayList<GtasksTaskContainer> remoteTasks = new ArrayList<GtasksTaskContainer>(); ArrayList<GtasksTaskContainer> remoteTasks = new ArrayList<GtasksTaskContainer>();

@ -14,6 +14,7 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.gtasks.GtasksListService; import com.todoroo.astrid.gtasks.GtasksListService;
import com.todoroo.astrid.gtasks.GtasksMetadataService; import com.todoroo.astrid.gtasks.GtasksMetadataService;
import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
/** /**
@ -68,6 +69,7 @@ public class AstridDependencyInjector extends AbstractDependencyInjector {
injectables.put("gtasksPreferenceService", GtasksPreferenceService.class); injectables.put("gtasksPreferenceService", GtasksPreferenceService.class);
injectables.put("gtasksListService", GtasksListService.class); injectables.put("gtasksListService", GtasksListService.class);
injectables.put("gtasksMetadataService", GtasksMetadataService.class); injectables.put("gtasksMetadataService", GtasksMetadataService.class);
injectables.put("gtasksTaskListUpdater", GtasksTaskListUpdater.class);
// these make reference to fields defined above // these make reference to fields defined above
injectables.put("errorReporters", new ErrorReporter[] { injectables.put("errorReporters", new ErrorReporter[] {

Loading…
Cancel
Save