package org.sana.android.task;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.sana.core.Event;
import org.sana.android.net.MDSInterface;
import org.sana.android.provider.Events;
import org.sana.android.provider.Events.Contract;
import org.sana.android.util.SanaUtil;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.util.Log;
/**
* Task for synching with an MDS instance.
*
* @author Sana Development Team
*
*/
public class MDSSyncTask extends AsyncTask<Context, Void, Integer> {
public static final String TAG = MDSSyncTask.class.getSimpleName();
/** Indicates a connection could not be established for synching. */
public static final Integer EMR_SYNC_NO_CONNECTION = 0;
/** Indicates synching was successful. */
public static final Integer EMR_SYNC_SUCCESS = 1;
/** Indicates synching failed. */
public static final Integer EMR_SYNC_FAILURE = 2;
private ProgressDialog progressDialog;
private Context mContext = null; // TODO context leak?
/**
* A new synchronization task.
*
* @param c the COntext to synch with
*/
public MDSSyncTask(Context c) {
mContext = c;
}
private boolean syncPatients(Context c) throws UnsupportedEncodingException {
return MDSInterface.updatePatientDatabase(c, c.getContentResolver());
}
private boolean syncEvents(Context c) {
Cursor cursor = null;
Log.i(TAG, "Syncing the event log to the MDS.");
try {
// Get all un-uploaded events.
cursor = c.getContentResolver().query(Events.CONTENT_URI,
new String[] { Contract._ID,
Contract.CREATED,
Contract.EVENT_TYPE,
Contract.EVENT_VALUE,
Contract.ENCOUNTER,
Contract.SUBJECT,
Contract.OBSERVER },
Contract.UPLOADED+"=?", new String[] { "0" }, null);
int numEvents = cursor.getCount();
if (numEvents == 0) {
// Nothing to upload, quit.
Log.i(TAG, "No unuploaded events. Skipping syncEvents.");
return true;
} else {
Log.i(TAG, "There are " + numEvents + " unuploaded events.");
}
StringBuilder sb = new StringBuilder("(");
List<Event> events = new ArrayList<Event>(numEvents);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Event e = new Event();
e.event_time = cursor.getLong(cursor.getColumnIndex(
Contract.CREATED));
e.event_type = cursor.getString(cursor.getColumnIndex(
Contract.EVENT_TYPE));
e.event_value = cursor.getString(cursor.getColumnIndex(
Contract.EVENT_VALUE));
e.encounter = cursor.getString(cursor.getColumnIndex(
Contract.ENCOUNTER));
e.subject = cursor.getString(cursor.getColumnIndex(
Contract.SUBJECT));
e.observer = cursor.getString(cursor.getColumnIndex(
Contract.OBSERVER));
int id = cursor.getInt(cursor.getColumnIndex(
Contract._ID));
events.add(e);
sb.append(id);
if (!cursor.isLast()) {
sb.append(",");
}
cursor.moveToNext();
}
sb.append(")");
// Submit the events to the MDS
boolean result = MDSInterface.submitEvents(c, events);
// Set the uploaded events as uploaded in the database.
if (result) {
Log.i(TAG, "Successfully uploaded " + numEvents + " events.");
ContentValues cv = new ContentValues();
cv.put(Contract.UPLOADED, 1);
int rowsUpdated = c.getContentResolver().update(
Events.CONTENT_URI, cv,
Contract._ID +" in " + sb.toString(), null);
if (rowsUpdated != numEvents) {
Log.w(TAG,
"Didn't get as many rows updated as we thought we would.");
}
}
return result;
} catch (Exception e) {
Log.e(TAG, "While trying to submit the event log, got exception: "
+ e.toString());
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return false;
}
/** {@inheritDoc} */
@Override
protected Integer doInBackground(Context... params) {
Log.i(TAG, "Executing EMRSyncTask");
Context c = params[0];
Integer result = EMR_SYNC_NO_CONNECTION; // TODO detect this case better
try{
if (SanaUtil.checkConnection(c)) {
boolean patientSyncResult = syncPatients(c);
boolean eventSyncResult = syncEvents(c);
result = (patientSyncResult && eventSyncResult) ?
EMR_SYNC_SUCCESS : EMR_SYNC_FAILURE;
}
} catch(Exception e){
Log.e(TAG, "Could not sync. " + e.toString());
}
return result;
}
/** {@inheritDoc} */
@Override
protected void onPreExecute() {
Log.i(TAG, "About to execute EMRSyncTask");
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage("Updating patient database cache");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
}
/** {@inheritDoc} */
@Override
protected void onPostExecute(Integer result) {
Log.i(TAG, "Completed EMRSyncTask");
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}
}