Added default values for all things in creating a new list and syncing it. Also handling sync errors silently

pull/14/head
Tim Su 14 years ago
parent 8600a6a237
commit 9cdba9c17a

@ -44,16 +44,32 @@ public abstract class SynchronizationProvider<TYPE extends TaskContainer> {
/**
* Perform authenticate and other pre-synchronization steps, then
* synchronize.
* @param context either the parent activity, or a background service
*
* @param context
* either the parent activity, or a background service
*/
abstract protected void initiate(Context context);
/**
* Gets title of the notification bar notification
*
* @param context
* @return title of notification
*/
abstract protected String getNotificationTitle(Context context);
/**
* Deal with an exception that occurs during synchronization
*
* @param tag
* short string description of where error occurred
* @param e
* exception
* @param displayError
* whether to display error to the user
*/
abstract protected void handleException(String tag, Exception e, boolean displayError);
/**
* Create a task on the remote server.
*
@ -207,52 +223,60 @@ public abstract class SynchronizationProvider<TYPE extends TaskContainer> {
length = data.localCreated.getCount();
for(int i = 0; i < length; i++) {
data.localCreated.moveToNext();
TYPE local = read(data.localCreated);
String taskTitle = local.task.getValue(Task.TITLE);
/* If there exists an incoming remote task with the same name and no
* mapping, we don't want to create this on the remote server,
* because user could have synchronized like this before. Instead,
* we create a mapping and do an update.
*/
if (remoteNewTaskNameMap.containsKey(taskTitle)) {
int remoteIndex = remoteNewTaskNameMap.remove(taskTitle);
TYPE remote = data.remoteUpdated.get(remoteIndex);
transferIdentifiers(remote, local);
push(local, remote);
// re-read remote task after merge, update remote task list
remote = pull(remote);
remote.task.setId(local.task.getId());
data.remoteUpdated.set(remoteIndex, remote);
} else {
create(local);
try {
TYPE local = read(data.localCreated);
String taskTitle = local.task.getValue(Task.TITLE);
/* If there exists an incoming remote task with the same name and no
* mapping, we don't want to create this on the remote server,
* because user could have synchronized like this before. Instead,
* we create a mapping and do an update.
*/
if (remoteNewTaskNameMap.containsKey(taskTitle)) {
int remoteIndex = remoteNewTaskNameMap.remove(taskTitle);
TYPE remote = data.remoteUpdated.get(remoteIndex);
transferIdentifiers(remote, local);
push(local, remote);
// re-read remote task after merge, update remote task list
remote = pull(remote);
remote.task.setId(local.task.getId());
data.remoteUpdated.set(remoteIndex, remote);
} else {
create(local);
}
write(local);
} catch (Exception e) {
handleException("sync-local-created", e, false); //$NON-NLS-1$
}
write(local);
}
// 2. UPDATE: for each updated local task
length = data.localUpdated.getCount();
for(int i = 0; i < length; i++) {
data.localUpdated.moveToNext();
TYPE local = read(data.localUpdated);
if(local.task == null)
continue;
// if there is a conflict, merge
int remoteIndex = matchTask((ArrayList<TYPE>)data.remoteUpdated, local);
if(remoteIndex != -1) {
TYPE remote = data.remoteUpdated.get(remoteIndex);
push(local, remote);
// re-read remote task after merge
remote = pull(remote);
remote.task.setId(local.task.getId());
data.remoteUpdated.set(remoteIndex, remote);
} else {
push(local, null);
try {
TYPE local = read(data.localUpdated);
if(local.task == null)
continue;
// if there is a conflict, merge
int remoteIndex = matchTask((ArrayList<TYPE>)data.remoteUpdated, local);
if(remoteIndex != -1) {
TYPE remote = data.remoteUpdated.get(remoteIndex);
push(local, remote);
// re-read remote task after merge
remote = pull(remote);
remote.task.setId(local.task.getId());
data.remoteUpdated.set(remoteIndex, remote);
} else {
push(local, null);
}
} catch (Exception e) {
handleException("sync-local-updated", e, false); //$NON-NLS-1$
}
}
@ -290,7 +314,11 @@ public abstract class SynchronizationProvider<TYPE extends TaskContainer> {
length = data.remoteUpdated.size();
for(int i = 0; i < length; i++) {
TYPE remote = data.remoteUpdated.get(i);
write(remote);
try {
write(remote);
} catch (Exception e) {
handleException("sync-remote-updated", e, false); //$NON-NLS-1$
}
}
}

@ -219,6 +219,19 @@ public abstract class AbstractModel implements Parcelable {
return false;
}
/**
* @param property
* @return true if setValues or values contains this property, and the value
* stored is not null
*/
public boolean containsNonNullValue(Property<?> property) {
if(setValues != null && setValues.containsKey(property.name))
return setValues.get(property.name) != null;
if(values != null && values.containsKey(property.name))
return values.get(property.name) != null;
return false;
}
// --- data storage
/**

@ -39,6 +39,9 @@ public class MilkFilterExposer extends BroadcastReceiver {
ContentValues values = new ContentValues();
values.put(Metadata.KEY.name, MilkTask.METADATA_KEY);
values.put(MilkTask.LIST_ID.name, list.id);
values.put(MilkTask.TASK_SERIES_ID.name, 0);
values.put(MilkTask.TASK_ID.name, 0);
values.put(MilkTask.REPEATING.name, 0);
Filter filter = new Filter(listTitle, title, new QueryTemplate().join(
MilkDataService.METADATA_JOIN).where(Criterion.and(
MetadataCriteria.withKey(MilkTask.METADATA_KEY),

@ -22,6 +22,7 @@ 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.service.ExceptionService;
import com.todoroo.andlib.utility.AndroidUtilities;
@ -100,12 +101,11 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
* error tag
* @param e
* exception
* @param showErrorIfNeeded
* @param showError
* whether to display a dialog
*/
private void handleRtmException(Context context, String tag, Exception e,
boolean showErrorIfNeeded) {
@Override
protected void handleException(String tag, Exception e, boolean showError) {
Utilities.setLastError(e.toString());
// occurs when application was closed
@ -118,7 +118,8 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
IOException) {
Exception enclosedException = ((ServiceInternalException)e).getEnclosedException();
exceptionService.reportError(tag + "-ioexception", enclosedException); //$NON-NLS-1$
if(showErrorIfNeeded) {
if(showError) {
Context context = ContextManager.getContext();
showError(context, enclosedException,
context.getString(R.string.rmilk_ioerror));
}
@ -126,8 +127,10 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
if(e instanceof ServiceInternalException)
e = ((ServiceInternalException)e).getEnclosedException();
exceptionService.reportError(tag + "-unhandled", e); //$NON-NLS-1$
if(showErrorIfNeeded)
if(showError) {
Context context = ContextManager.getContext();
showError(context, e, null);
}
}
}
@ -169,7 +172,7 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
try {
String token = rtmService.completeAuthorization();
Utilities.setToken(token);
performSync(context);
performSync();
return;
} catch (Exception e) {
@ -211,12 +214,12 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
context.startActivity(intent);
} else {
performSync(context);
performSync();
}
} catch (IllegalStateException e) {
// occurs when application was closed
} catch (Exception e) {
handleRtmException(context, "rtm-authenticate", e, true);
handleException("rtm-authenticate", e, true);
} finally {
Utilities.stopOngoing();
}
@ -226,7 +229,7 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
// ----------------------------------------------------- synchronization!
// ----------------------------------------------------------------------
protected void performSync(final Context context) {
protected void performSync() {
try {
// get RTM timeline
timeline = rtmService.timelines_create();
@ -249,7 +252,7 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
RtmTasks tasks = rtmService.tasks_getList(null, filter, lastSyncDate);
addTasksToList(tasks, remoteChanges);
} catch (Exception e) {
handleRtmException(context, "rtm-quick-sync", e, false); //$NON-NLS-1$
handleException("rtm-quick-sync", e, false); //$NON-NLS-1$
remoteChanges.clear();
shouldSyncIndividualLists = true;
}
@ -264,7 +267,7 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
filter, lastSyncDate);
addTasksToList(tasks, remoteChanges);
} catch (Exception e) {
handleRtmException(context, "rtm-indiv-sync", e, true); //$NON-NLS-1$
handleException("rtm-indiv-sync", e, true); //$NON-NLS-1$
continue;
}
}
@ -284,7 +287,7 @@ public class RTMSyncProvider extends SynchronizationProvider<RTMTaskContainer> {
} catch (IllegalStateException e) {
// occurs when application was closed
} catch (Exception e) {
handleRtmException(context, "rtm-sync", e, true); //$NON-NLS-1$
handleException("rtm-sync", e, true); //$NON-NLS-1$
}
}

@ -44,13 +44,13 @@ public class RTMTaskContainer extends TaskContainer {
for(Iterator<Metadata> iterator = metadata.iterator(); iterator.hasNext(); ) {
Metadata item = iterator.next();
if(MilkTask.METADATA_KEY.equals(item.getValue(Metadata.KEY))) {
if(item.containsValue(MilkTask.LIST_ID))
if(item.containsNonNullValue(MilkTask.LIST_ID))
listId = item.getValue(MilkTask.LIST_ID);
if(item.containsValue(MilkTask.TASK_SERIES_ID))
if(item.containsNonNullValue(MilkTask.TASK_SERIES_ID))
taskSeriesId = item.getValue(MilkTask.TASK_SERIES_ID);
if(item.containsValue(MilkTask.TASK_ID))
if(item.containsNonNullValue(MilkTask.TASK_ID))
taskId = item.getValue(MilkTask.TASK_ID);
if(item.containsValue(MilkTask.REPEATING))
if(item.containsNonNullValue(MilkTask.REPEATING))
repeating = item.getValue(MilkTask.REPEATING) == 1;
iterator.remove();
break;

Loading…
Cancel
Save