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 {
@Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
abstract int getDelta();
@ -43,7 +44,7 @@ abstract public class GtasksIndentAction extends BroadcastReceiver {
metadata.setValue(GtasksMetadata.INDENT, newIndent);
PluginServices.getMetadataService().save(metadata);
gtasksMetadataService.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
Flags.set(Flags.REFRESH);
Toast.makeText(context, context.getString(R.string.gtasks_indent_toast, newIndent),

@ -4,21 +4,13 @@
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 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.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.data.Metadata;
import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.sync.GtasksTaskContainer;
import com.todoroo.astrid.sync.SyncMetadataService;
@ -33,7 +25,6 @@ import com.todoroo.astrid.sync.SyncProviderUtilities;
public final class GtasksMetadataService extends SyncMetadataService<GtasksTaskContainer> {
@Autowired private GtasksPreferenceService gtasksPreferenceService;
@Autowired private GtasksListService gtasksListService;
public GtasksMetadataService() {
super(ContextManager.getContext());
@ -66,113 +57,4 @@ public final class GtasksMetadataService extends SyncMetadataService<GtasksTaskC
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 {
@Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
abstract int getDelta();
@ -38,7 +39,7 @@ abstract public class GtasksOrderAction extends BroadcastReceiver {
if(metadata == null)
return;
gtasksMetadataService.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
gtasksTaskListUpdater.updateMetadataForList(metadata.getValue(GtasksMetadata.LIST_ID));
metadata = gtasksMetadataService.getTaskMetadata(taskId);
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.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksPreferences;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.producteev.ProducteevBackgroundService;
import com.todoroo.astrid.producteev.ProducteevLoginActivity;
import com.todoroo.astrid.producteev.ProducteevUtilities;
@ -66,6 +67,7 @@ public class GtasksSyncProvider extends SyncProvider<GtasksTaskContainer> {
@Autowired private GtasksListService gtasksListService;
@Autowired private GtasksMetadataService gtasksMetadataService;
@Autowired private GtasksPreferenceService gtasksPreferenceService;
@Autowired private GtasksTaskListUpdater gtasksTaskListUpdater;
/** google task service fields */
private GoogleTaskService taskService = null;
@ -214,7 +216,7 @@ public class GtasksSyncProvider extends SyncProvider<GtasksTaskContainer> {
gtasksListService.updateLists(taskView.getAllLists());
gtasksMetadataService.createParentSiblingMaps();
gtasksTaskListUpdater.createParentSiblingMaps();
// batched read tasks for each list
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.GtasksMetadataService;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.utility.Constants;
/**
@ -68,6 +69,7 @@ public class AstridDependencyInjector extends AbstractDependencyInjector {
injectables.put("gtasksPreferenceService", GtasksPreferenceService.class);
injectables.put("gtasksListService", GtasksListService.class);
injectables.put("gtasksMetadataService", GtasksMetadataService.class);
injectables.put("gtasksTaskListUpdater", GtasksTaskListUpdater.class);
// these make reference to fields defined above
injectables.put("errorReporters", new ErrorReporter[] {

Loading…
Cancel
Save