package org.adaptlab.chpir.android.activerecordcloudsync;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import org.adaptlab.chpir.android.survey.AppUtil;
import org.adaptlab.chpir.android.survey.R;
import org.adaptlab.chpir.android.survey.Models.Instrument;
import android.content.Context;
import android.util.Log;
public class ActiveRecordCloudSync {
private static final String TAG="ActiveRecordCloudSync";
private static Map<String, Class<? extends ReceiveModel>> mReceiveTables =
new LinkedHashMap<String, Class<? extends ReceiveModel>>();
private static Map<String, Class<? extends SendModel>> mSendTables =
new LinkedHashMap<String, Class<? extends SendModel>>();
private static String mEndPoint; // The remote API endpoint url
private static String mAccessToken; // API Access Key
private static int mVersionCode; // App version code from Manifest
private static String mInstrumentVersions;
/**
* Add a ReceiveTable. A ReceiveTable is an active record model class that extends the
* ReceiveModel abstract class.
*
* @param tableName
* @param receiveTable
*/
public static void addReceiveTable(String tableName, Class<? extends ReceiveModel> receiveTable) {
mReceiveTables.put(tableName, receiveTable);
}
public static Map<String, Class<? extends ReceiveModel>> getReceiveTables() {
return mReceiveTables;
}
public static void addSendTable(String tableName, Class<? extends SendModel> sendTable) {
mSendTables.put(tableName, sendTable);
}
public static void setEndPoint(String endPoint) {
if (AppUtil.DEBUG) Log.i(TAG, "Api End point is: " + endPoint);
char lastChar = endPoint.charAt(endPoint.length() - 1);
if (lastChar != '/') endPoint = endPoint + "/";
mEndPoint = endPoint;
}
public static String getEndPoint() {
return mEndPoint;
}
public static void syncReceiveTables(Context context) {
NetworkNotificationUtils.showNotification(context, android.R.drawable.stat_sys_download, R.string.sync_notification_text);
ActiveRecordCloudSync.setInstrumentVersions();
for (Map.Entry<String, Class<? extends ReceiveModel>> entry : mReceiveTables.entrySet()) {
if (AppUtil.DEBUG) Log.i(TAG, "Syncing " + entry.getValue() + " from remote table " + entry.getKey());
HttpFetchr httpFetchr = new HttpFetchr(entry.getKey(), entry.getValue());
httpFetchr.fetch();
}
NetworkNotificationUtils.showNotification(context, android.R.drawable.stat_sys_download_done, R.string.sync_notification_complete_text);
}
public static void syncSendTables(Context context) {
NetworkNotificationUtils.showNotification(context, android.R.drawable.stat_sys_download, R.string.sync_notification_text);
for (Map.Entry<String, Class<? extends SendModel>> entry : mSendTables.entrySet()) {
if (AppUtil.DEBUG) Log.i(TAG, "Syncing " + entry.getValue() + " to remote table " + entry.getKey());
HttpPushr httpPushr = new HttpPushr(entry.getKey(), entry.getValue(), context);
httpPushr.push();
}
NetworkNotificationUtils.showNotification(context, android.R.drawable.stat_sys_download_done, R.string.sync_notification_complete_text);
}
public static boolean isApiAvailable() {
if (getPingAddress() == null) return true;
int responseCode = ping(getPingAddress(), 10000);
if (responseCode == 426) return true; // Api is available but an app upgrade is required
return (200 <= responseCode && responseCode < 300);
}
/*
* Check to see if this version of the application meets the
* minimum standard to interact with API.
*/
public static boolean isVersionAcceptable() {
int responseCode = ping(getPingAddress(), 10000);
return responseCode != 426; // Http Status Code 426 = upgrade required
}
public static void setAccessToken(String token) {
mAccessToken = token;
}
public static String getAccessToken() {
return mAccessToken;
}
public static void setVersionCode(int code) {
mVersionCode = code;
}
/*
* Version code from AndroidManifest
*/
public static int getVersionCode() {
return mVersionCode;
}
/*
* Append to all api calls.
* Ensure that the access token is valid and the version code is up to date
* before allowing an update.
*/
public static String getParams() {
return "?access_token=" + getAccessToken() + "&version_code=" + getVersionCode() + getInstrumentVersions();
}
public static void setInstrumentVersions() {
mInstrumentVersions = Instrument.getInstrumentVersions();
}
public static String getInstrumentVersions() {
return mInstrumentVersions;
}
private static String getPingAddress() {
if (!getReceiveTables().keySet().isEmpty()) {
return getEndPoint() + getReceiveTables().keySet().iterator().next();
}
return getEndPoint();
}
private static int ping(String url, int timeout) {
if (url == null) return -1;
url = url + getParams();
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();
if (AppUtil.DEBUG) Log.i(TAG, "Received response code " + responseCode + " for api endpoint");
return responseCode;
} catch (IOException exception) {
return -1;
}
}
}