package org.projectbuendia.client.sync.controllers;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.SyncResult;
import com.android.volley.toolbox.RequestFuture;
import com.google.common.base.Joiner;
import org.projectbuendia.client.App;
import org.projectbuendia.client.json.JsonChart;
import org.projectbuendia.client.json.JsonChartItem;
import org.projectbuendia.client.json.JsonChartSection;
import org.projectbuendia.client.models.AppModel;
import org.projectbuendia.client.net.OpenMrsChartServer;
import org.projectbuendia.client.providers.Contracts;
import org.projectbuendia.client.utils.Logger;
import org.projectbuendia.client.utils.Utils;
import java.util.ArrayList;
/**
* Handles syncing charts. Always fetches everything. This is okay because the full set of chart
* layouts is usually fairly small in size.
*/
public class ChartsSyncPhaseRunnable implements SyncPhaseRunnable {
private static final Logger LOG = Logger.create();
@Override
public void sync(ContentResolver contentResolver, SyncResult syncResult,
ContentProviderClient providerClient)
throws Throwable {
OpenMrsChartServer chartServer = new OpenMrsChartServer(App.getConnectionDetails());
RequestFuture<JsonChart> future = RequestFuture.newFuture();
// errors handled by caller
chartServer.getChartStructure(AppModel.CHART_UUID, future, future);
final JsonChart chart = future.get();
// When we do a chart update, delete everything first, then insert all the new rows.
providerClient.delete(Contracts.ChartItems.CONTENT_URI, null, null);
syncResult.stats.numDeletes++;
providerClient.applyBatch(getChartUpdateOps(chart, syncResult));
}
/** Converts a JsonChart response into appropriate inserts in the chart table. */
private static ArrayList<ContentProviderOperation> getChartUpdateOps(
JsonChart response, SyncResult syncResult) {
if (response.uuid == null) {
LOG.e("null chart uuid when fetching chart structure");
}
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
int nextId = 1;
int nextWeight = 1;
for (JsonChartSection section : response.sections) {
int parentId = nextId;
ops.add(ContentProviderOperation.newInsert(Contracts.ChartItems.CONTENT_URI)
.withValue("rowid", nextId++)
.withValue(Contracts.ChartItems.CHART_UUID, response.uuid)
.withValue(Contracts.ChartItems.WEIGHT, nextWeight++)
.withValue(Contracts.ChartItems.SECTION_TYPE, section.type == null ? null : section.type.name())
.withValue(Contracts.ChartItems.LABEL, section.label)
.build());
syncResult.stats.numInserts++;
for (JsonChartItem item : section.items) {
Object[] conceptUuids = new Object[item.concepts.length];
for (int i = 0; i < conceptUuids.length; i++) {
conceptUuids[i] = Utils.expandUuid(item.concepts[i]);
}
ops.add(ContentProviderOperation.newInsert(Contracts.ChartItems.CONTENT_URI)
.withValue("rowid", nextId++)
.withValue(Contracts.ChartItems.CHART_UUID, response.uuid)
.withValue(Contracts.ChartItems.WEIGHT, nextWeight++)
.withValue(Contracts.ChartItems.PARENT_ROWID, parentId)
.withValue(Contracts.ChartItems.LABEL, item.label)
.withValue(Contracts.ChartItems.TYPE, item.type)
.withValue(Contracts.ChartItems.REQUIRED, item.required ? 1 : 0)
.withValue(Contracts.ChartItems.CONCEPT_UUIDS, Joiner.on(",").join(conceptUuids))
.withValue(Contracts.ChartItems.FORMAT, item.format)
.withValue(Contracts.ChartItems.CAPTION_FORMAT, item.caption_format)
.withValue(Contracts.ChartItems.CSS_CLASS, item.css_class)
.withValue(Contracts.ChartItems.CSS_STYLE, item.css_style)
.withValue(Contracts.ChartItems.SCRIPT, item.script)
.build());
syncResult.stats.numInserts++;
}
}
return ops;
}
}