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.
299 lines
11 KiB
Java
299 lines
11 KiB
Java
package com.timsu.astrid.utilities;
|
|
|
|
import android.app.AlertDialog;
|
|
import android.app.ProgressDialog;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.util.Log;
|
|
import com.timsu.astrid.R;
|
|
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.sync.SyncMapping;
|
|
import com.timsu.astrid.data.tag.TagController;
|
|
import com.timsu.astrid.data.tag.TagIdentifier;
|
|
import com.timsu.astrid.data.tag.TagModelForView;
|
|
import com.timsu.astrid.data.task.TaskController;
|
|
import com.timsu.astrid.data.task.TaskIdentifier;
|
|
import com.timsu.astrid.data.task.TaskModelForXml;
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
import org.xmlpull.v1.XmlPullParserException;
|
|
import org.xmlpull.v1.XmlPullParserFactory;
|
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileReader;
|
|
import java.util.Date;
|
|
|
|
public class TasksXmlImporter {
|
|
public static final String TAG = "TasksXmlImporter";
|
|
public static final String ASTRID_TAG = TasksXmlExporter.ASTRID_TAG;
|
|
public static final String ASTRID_ATTR_VERSION = TasksXmlExporter.ASTRID_ATTR_VERSION;
|
|
public static final String TASK_TAG = TasksXmlExporter.TASK_TAG;
|
|
public static final String TAG_TAG = TasksXmlExporter.TAG_TAG;
|
|
public static final String ALERT_TAG = TasksXmlExporter.ALERT_TAG;
|
|
public static final String SYNC_TAG = TasksXmlExporter.SYNC_TAG;
|
|
public static final String TASK_ID = AbstractController.KEY_ROWID;
|
|
public static final String TASK_NAME = TaskModelForXml.NAME;
|
|
public static final String TASK_CREATION_DATE = TaskModelForXml.CREATION_DATE;
|
|
public static final String TAG_ATTR_NAME = TasksXmlExporter.TAG_ATTR_NAME;
|
|
public static final String ALERT_ATTR_DATE = TasksXmlExporter.ALERT_ATTR_DATE;
|
|
public static final String SYNC_ATTR_SERVICE = TasksXmlExporter.SYNC_ATTR_SERVICE;
|
|
public static final String SYNC_ATTR_REMOTE_ID = TasksXmlExporter.SYNC_ATTR_REMOTE_ID;
|
|
|
|
private TaskController taskController;
|
|
private TagController tagController;
|
|
private AlertController alertController;
|
|
private SyncDataController syncDataController;
|
|
private XmlPullParser xpp;
|
|
private String input;
|
|
private Handler importHandler;
|
|
private final Context context;
|
|
private int taskCount;
|
|
private int importCount;
|
|
private int skipCount;
|
|
|
|
static ProgressDialog progressDialog;
|
|
|
|
public TasksXmlImporter(Context context) {
|
|
this.context = context;
|
|
setContext(context);
|
|
}
|
|
|
|
private void setProgressMessage(final String message) {
|
|
importHandler.post(new Runnable() {
|
|
public void run() {
|
|
progressDialog.setMessage(message);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void importTasks(final Runnable runAfterImport) {
|
|
importHandler = new Handler();
|
|
importHandler.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
TasksXmlImporter.progressDialog = new ProgressDialog(context);
|
|
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
|
|
progressDialog.setTitle(R.string.import_progress_title);
|
|
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
|
progressDialog.setMessage(context.getString(R.string.import_progress_open));
|
|
progressDialog.setCancelable(false);
|
|
progressDialog.setIndeterminate(true);
|
|
progressDialog.show();
|
|
}
|
|
});
|
|
new Thread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
Looper.prepare();
|
|
try {
|
|
performImport();
|
|
if (runAfterImport != null) {
|
|
importHandler.post(runAfterImport);
|
|
}
|
|
} catch (FileNotFoundException e) {
|
|
Log.e("TasksXmlImporter", e.getMessage());
|
|
} catch (XmlPullParserException e) {
|
|
Log.e("TasksXmlImporter", e.getMessage());
|
|
}
|
|
Looper.loop();
|
|
}
|
|
}).start();
|
|
}
|
|
|
|
private void performImport() throws FileNotFoundException, XmlPullParserException {
|
|
taskCount = 0;
|
|
importCount = 0;
|
|
skipCount = 0;
|
|
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
|
|
xpp = factory.newPullParser();
|
|
xpp.setInput(new FileReader(input));
|
|
setProgressMessage(context.getString(R.string.import_progress_opened));
|
|
|
|
openControllers();
|
|
try {
|
|
TaskModelForXml currentTask = null;
|
|
while (xpp.next() != XmlPullParser.END_DOCUMENT) {
|
|
String tag = xpp.getName();
|
|
if (xpp.getEventType() == XmlPullParser.END_TAG) {
|
|
// Ignore end tag.
|
|
continue;
|
|
}
|
|
if (tag != null) {
|
|
if (tag.equals(ASTRID_TAG)) {
|
|
// Process <astrid ... >
|
|
// Perform version compatibility check?
|
|
}
|
|
else if (tag.equals(TASK_TAG)) {
|
|
// Parse <task ... >
|
|
currentTask = parseTask();
|
|
} else if (currentTask != null) {
|
|
// These tags all require that we have a task to associate them with.
|
|
if (tag.equals(TAG_TAG)) {
|
|
// Process <tag ... >
|
|
parseTag(currentTask.getTaskIdentifier());
|
|
} else if (tag.equals(ALERT_TAG)) {
|
|
// Process <alert ... >
|
|
parseAlert(currentTask.getTaskIdentifier());
|
|
} else if (tag.equals(SYNC_TAG)) {
|
|
// Process <sync ... >
|
|
parseSync(currentTask.getTaskIdentifier());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "import error " + e.getMessage());
|
|
} finally {
|
|
closeControllers();
|
|
progressDialog.dismiss();
|
|
showSummary();
|
|
}
|
|
}
|
|
|
|
private boolean parseSync(TaskIdentifier taskId) {
|
|
String service = xpp.getAttributeValue(null, SYNC_ATTR_SERVICE);
|
|
String remoteId = xpp.getAttributeValue(null, SYNC_ATTR_REMOTE_ID);
|
|
if (service != null && remoteId != null) {
|
|
int serviceInt = Integer.parseInt(service);
|
|
SyncMapping sm = new SyncMapping(taskId, serviceInt, remoteId);
|
|
syncDataController.saveSyncMapping(sm);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean parseAlert(TaskIdentifier taskId) {
|
|
String alert = xpp.getAttributeValue(null, ALERT_ATTR_DATE);
|
|
if (alert != null) {
|
|
Date alertDate = DateUtilities.getDateFromIso8601String(alert);
|
|
if (alertDate != null) {
|
|
if (! alertController.addAlert(taskId, alertDate)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean parseTag(TaskIdentifier taskId) {
|
|
String tagName = xpp.getAttributeValue(null, TAG_ATTR_NAME);
|
|
if (tagName != null) {
|
|
TagIdentifier tagId;
|
|
TagModelForView tagModel;
|
|
tagModel = tagController.fetchTagFromName(tagName);
|
|
if (tagModel == null) {
|
|
// Tag not found, create a new one.
|
|
tagId = tagController.createTag(tagName);
|
|
} else {
|
|
tagId = tagModel.getTagIdentifier();
|
|
}
|
|
if (! tagController.addTag(taskId, tagId)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private TaskModelForXml parseTask() {
|
|
taskCount++;
|
|
setProgressMessage(context.getString(R.string.import_progress_read, taskCount));
|
|
TaskModelForXml task = null;
|
|
String taskName = xpp.getAttributeValue(null, TASK_NAME);
|
|
|
|
Date creationDate = null;
|
|
String createdString = xpp.getAttributeValue(null, TASK_CREATION_DATE);
|
|
if (createdString != null) {
|
|
creationDate = DateUtilities.getDateFromIso8601String(createdString);
|
|
}
|
|
// If the task's name and creation date match an existing task, skip it.
|
|
if (creationDate != null && taskName != null) {
|
|
task = taskController.fetchTaskForXml(taskName, creationDate);
|
|
}
|
|
if (task != null) {
|
|
// Skip this task.
|
|
skipCount++;
|
|
setProgressMessage(context.getString(R.string.import_progress_skip, taskCount));
|
|
// Set currentTask to null so we skip its alerts/syncs/tags, too.
|
|
return null;
|
|
}
|
|
// Else, make a new task model and add away.
|
|
task = new TaskModelForXml();
|
|
int numAttributes = xpp.getAttributeCount();
|
|
for (int i = 0; i < numAttributes; i++) {
|
|
String fieldName = xpp.getAttributeName(i);
|
|
String fieldValue = xpp.getAttributeValue(i);
|
|
task.setField(fieldName, fieldValue);
|
|
}
|
|
// Save the task to the database.
|
|
taskController.saveTask(task, false);
|
|
importCount++;
|
|
setProgressMessage(context.getString(R.string.import_progress_add, taskCount));
|
|
return task;
|
|
}
|
|
|
|
private void showSummary() {
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
builder.setTitle(R.string.import_summary_title);
|
|
String message = context.getString(R.string.import_summary_message,
|
|
input, taskCount, importCount, skipCount);
|
|
builder.setMessage(message);
|
|
builder.setPositiveButton(context.getString(android.R.string.ok),
|
|
new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
dialog.dismiss();
|
|
}
|
|
});
|
|
builder.show();
|
|
}
|
|
|
|
public void setTaskController(TaskController taskController) {
|
|
this.taskController = taskController;
|
|
}
|
|
|
|
public void setTagController(TagController tagController) {
|
|
this.tagController = tagController;
|
|
}
|
|
|
|
public void setAlertController(AlertController alertController) {
|
|
this.alertController = alertController;
|
|
}
|
|
|
|
public void setSyncDataController(SyncDataController syncDataController) {
|
|
this.syncDataController = syncDataController;
|
|
}
|
|
|
|
public void setContext(Context ctx) {
|
|
setTaskController(new TaskController(ctx));
|
|
setTagController(new TagController(ctx));
|
|
setAlertController(new AlertController(ctx));
|
|
setSyncDataController(new SyncDataController(ctx));
|
|
}
|
|
|
|
private void closeControllers() {
|
|
taskController.close();
|
|
tagController.close();
|
|
alertController.close();
|
|
syncDataController.close();
|
|
}
|
|
|
|
private void openControllers() {
|
|
taskController.open();
|
|
tagController.open();
|
|
alertController.open();
|
|
syncDataController.open();
|
|
}
|
|
|
|
public void setInput(String input) {
|
|
this.input = input;
|
|
}
|
|
}
|