mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
8.8 KiB
Java
285 lines
8.8 KiB
Java
/*
|
|
* ASTRID: Android's Simple Task Recording Dashboard
|
|
*
|
|
* Copyright (c) 2009 Tim Su
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
package com.timsu.astrid.sync;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.Date;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.util.Log;
|
|
|
|
import com.timsu.astrid.activities.TaskListSubActivity;
|
|
import com.timsu.astrid.data.AbstractController;
|
|
import com.timsu.astrid.data.alerts.AlertController;
|
|
import com.timsu.astrid.data.sync.SyncDataController;
|
|
import com.timsu.astrid.data.tag.TagController;
|
|
import com.timsu.astrid.data.task.TaskController;
|
|
import com.timsu.astrid.data.task.TaskIdentifier;
|
|
import com.timsu.astrid.utilities.Preferences;
|
|
|
|
/**
|
|
* Synchronizer is a class that manages a synchronization lifecycle. You would
|
|
* use it as follows.
|
|
* <p>
|
|
* <pre>Synchronizer synchronizer = new Synchronizer(...);
|
|
* synchronizer.synchronize();</pre>
|
|
*
|
|
* @author Tim Su
|
|
*
|
|
*/
|
|
public class Synchronizer {
|
|
|
|
/** identifier for the RTM sync provider */
|
|
private static final int SYNC_ID_RTM = 1;
|
|
|
|
// --- public interface
|
|
|
|
/** Synchronize all tasks */
|
|
public Synchronizer(boolean isService) {
|
|
this.isService = isService;
|
|
singleTaskForSync = null;
|
|
}
|
|
|
|
/** Synchronize a specific task only */
|
|
public Synchronizer(TaskIdentifier task) {
|
|
isService = false;
|
|
singleTaskForSync = task;
|
|
}
|
|
|
|
public interface SynchronizerListener {
|
|
void onSynchronizerFinished(int numServicesSynced);
|
|
}
|
|
|
|
/** Synchronize all activated sync services */
|
|
public synchronized void synchronize(Context context, SynchronizerListener listener) {
|
|
currentStep = ServiceWrapper._FIRST_SERVICE.ordinal();
|
|
servicesSynced = 0;
|
|
callback = listener;
|
|
|
|
// if we're not the autosync service, stop it
|
|
if(!isService)
|
|
SynchronizationService.stop();
|
|
|
|
continueSynchronization(context);
|
|
}
|
|
|
|
|
|
/** Clears tokens of activated services */
|
|
public static void clearUserData(Activity activity) {
|
|
Synchronizer synchronizer = new Synchronizer(false);
|
|
for(ServiceWrapper serviceWrapper : ServiceWrapper.values()) {
|
|
if(serviceWrapper.isActivated(activity)) {
|
|
serviceWrapper.service.synchronizer = synchronizer;
|
|
serviceWrapper.service.clearPersonalData(activity);
|
|
}
|
|
}
|
|
synchronizer.closeControllers();
|
|
}
|
|
|
|
// --- internal synchronization logic
|
|
|
|
/** Synchronization Services enumeration
|
|
* note that id must be kept constant!
|
|
* @author timsu
|
|
*
|
|
*/
|
|
private enum ServiceWrapper {
|
|
_FIRST_SERVICE(null) { // must be first entry
|
|
@Override
|
|
boolean isActivated(Context arg0) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
RTM(new RTMSyncProvider(SYNC_ID_RTM)) {
|
|
@Override
|
|
boolean isActivated(Context context) {
|
|
return Preferences.shouldSyncRTM(context);
|
|
}
|
|
},
|
|
|
|
_LAST_SERVICE(null) { // must be last entry
|
|
@Override
|
|
boolean isActivated(Context arg0) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
private SynchronizationProvider service;
|
|
|
|
private ServiceWrapper(SynchronizationProvider service) {
|
|
this.service = service;
|
|
}
|
|
|
|
abstract boolean isActivated(Context context);
|
|
}
|
|
|
|
// Internal state for the synchronization process
|
|
|
|
/** Current step in the sync process */
|
|
private int currentStep = 0;
|
|
|
|
/** # of services synchronized */
|
|
private int servicesSynced = 0;
|
|
|
|
/** On finished callback */
|
|
private SynchronizerListener callback = null;
|
|
|
|
/** Whether this sync is initiated by a background service */
|
|
private final boolean isService;
|
|
|
|
/** The single task to synchronize, if applicable */
|
|
private final TaskIdentifier singleTaskForSync;
|
|
|
|
boolean isService() {
|
|
return isService;
|
|
}
|
|
|
|
TaskIdentifier getSingleTaskForSync() {
|
|
return singleTaskForSync;
|
|
}
|
|
|
|
/** Called to do the next step of synchronization. */
|
|
void continueSynchronization(Context context) {
|
|
ServiceWrapper serviceWrapper =
|
|
ServiceWrapper.values()[currentStep];
|
|
currentStep++;
|
|
switch(serviceWrapper) {
|
|
case _FIRST_SERVICE:
|
|
continueSynchronization(context);
|
|
break;
|
|
case RTM:
|
|
if(serviceWrapper.isActivated(context)) {
|
|
servicesSynced++;
|
|
serviceWrapper.service.synchronizeService(context, this);
|
|
} else {
|
|
continueSynchronization(context);
|
|
}
|
|
break;
|
|
case _LAST_SERVICE:
|
|
finishSynchronization(context);
|
|
}
|
|
}
|
|
|
|
/** Called at the end of sync. */
|
|
private void finishSynchronization(final Context context) {
|
|
closeControllers();
|
|
if(callback != null)
|
|
callback.onSynchronizerFinished(servicesSynced);
|
|
|
|
if(getSingleTaskForSync() != null)
|
|
Preferences.setSyncLastSync(context, new Date());
|
|
if(!isService) {
|
|
SynchronizationService.start();
|
|
TaskListSubActivity.shouldRefreshTaskList = true;
|
|
}
|
|
}
|
|
|
|
// --- controller stuff
|
|
|
|
private ControllerWrapper<SyncDataController> syncController =
|
|
new ControllerWrapper<SyncDataController>(SyncDataController.class);
|
|
private ControllerWrapper<TaskController> taskController =
|
|
new ControllerWrapper<TaskController>(TaskController.class);
|
|
private ControllerWrapper<TagController> tagController =
|
|
new ControllerWrapper<TagController>(TagController.class);
|
|
private ControllerWrapper<AlertController> alertController =
|
|
new ControllerWrapper<AlertController>(AlertController.class);
|
|
|
|
private static class ControllerWrapper<TYPE extends AbstractController> {
|
|
TYPE controller;
|
|
Class<TYPE> typeClass;
|
|
boolean override;
|
|
|
|
public ControllerWrapper(Class<TYPE> cls) {
|
|
override = false;
|
|
controller = null;
|
|
typeClass = cls;
|
|
}
|
|
|
|
public TYPE get(Context context) {
|
|
if(controller == null) {
|
|
try {
|
|
controller = typeClass.getConstructors()[0].newInstance(context);
|
|
} catch (IllegalArgumentException e) {
|
|
Log.e(getClass().getSimpleName(), e.toString());
|
|
} catch (SecurityException e) {
|
|
Log.e(getClass().getSimpleName(), e.toString());
|
|
} catch (InstantiationException e) {
|
|
Log.e(getClass().getSimpleName(), e.toString());
|
|
} catch (IllegalAccessException e) {
|
|
Log.e(getClass().getSimpleName(), e.toString());
|
|
} catch (InvocationTargetException e) {
|
|
Log.e(getClass().getSimpleName(), e.toString());
|
|
}
|
|
controller.open();
|
|
}
|
|
return controller;
|
|
}
|
|
|
|
public void set(TYPE newController) {
|
|
if(controller != null && !override)
|
|
close();
|
|
|
|
override = newController != null;
|
|
controller = newController;
|
|
}
|
|
|
|
public void close() {
|
|
if(controller != null && !override) {
|
|
controller.close();
|
|
controller = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
SyncDataController getSyncController(Context context) {
|
|
return syncController.get(context);
|
|
}
|
|
|
|
TaskController getTaskController(Context context) {
|
|
return taskController.get(context);
|
|
}
|
|
|
|
TagController getTagController(Context context) {
|
|
return tagController.get(context);
|
|
}
|
|
|
|
AlertController getAlertController(Context context) {
|
|
return alertController.get(context);
|
|
}
|
|
|
|
public void setTaskController(TaskController taskController) {
|
|
this.taskController.set(taskController);
|
|
}
|
|
|
|
public void setTagController(TagController tagController) {
|
|
this.tagController.set(tagController);
|
|
}
|
|
|
|
private void closeControllers() {
|
|
syncController.close();
|
|
taskController.close();
|
|
tagController.close();
|
|
alertController.close();
|
|
}
|
|
}
|