package ca.grocerygo.android.services;
import android.app.IntentService;
import android.content.Intent;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import ca.grocerygo.android.GroceryApplication;
import ca.grocerygo.android.SplashScreenActivity;
import ca.grocerygo.android.database.*;
import ca.grocerygo.android.database.contentprovider.GroceryotgProvider;
import ca.grocerygo.android.database.objects.*;
import ca.grocerygo.android.utils.GroceryGoUtils;
import ca.grocerygo.android.utils.JSONParser;
import ca.grocerygo.android.utils.ServerURLs;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.stream.JsonReader;
public class NetworkHandler extends IntentService {
public static final String REFRESH_COMPLETED_ACTION = "com.grocerygo.android.service.REFRESH_COMPLETE";
public static final String CONNECTION_STATE = "connectionStatus";
public static final int CONNECTION = 10;
public static final int NO_CONNECTION = 11;
public static final String REFRESH_CONTENT = "content";
public static final int CAT = 10;
public static final int GRO = 20;
public static final int STO_PAR = 30;
public static final int STO = 40;
public static final int FLY = 50;
public static final String REQUEST_TYPE = "refresh_type";
private static boolean stopped = false;
JSONParser jsonParser = new JSONParser();
public NetworkHandler() {
super("NetworkHandler");
}
@Override
protected void onHandleIntent(Intent intent) {
SQLiteDatabase db = GroceryotgProvider.database.getWritableDatabase();
Bundle extras = intent.getExtras();
Integer requestType = null;
int connectionState = NO_CONNECTION;
Bundle bundle = new Bundle();
if (ServerURLs.checkNetworkStatus(this.getBaseContext()) && extras != null) {
requestType = (Integer) extras.get(REFRESH_CONTENT);
switch (requestType) {
case CAT:
refreshCategory(db);
break;
case GRO:
refreshGrocery(db);
break;
case STO_PAR:
refreshStoreParent(db);
break;
case STO:
refreshStore(db);
break;
case FLY:
refreshFlyer(db);
break;
default:
Log.e("GroceryOTG", "unknown request received by NetworkHandler");
break;
}
connectionState = CONNECTION;
bundle.putInt(REQUEST_TYPE, requestType);
} else if (!ServerURLs.checkNetworkStatus(this.getBaseContext())) {
connectionState = NO_CONNECTION;
bundle.putInt(REQUEST_TYPE, 0);
}
bundle.putInt(CONNECTION_STATE, connectionState);
Intent localIntent = new Intent(REFRESH_COMPLETED_ACTION).putExtra("bundle", bundle);
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
@Override
public void onDestroy() {
stopped = true;
super.onDestroy();
}
private void refreshCategory(SQLiteDatabase db) {
Log.i(GroceryApplication.TAG, "refreshing category...");
Gson gson = new Gson();
JsonArray categoryArray = jsonParser.getJSONFromUrl(ServerURLs.getCateoryUrl());
DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(db, CategoryTable.TABLE_CATEGORY);
Category category;
if (categoryArray != null) {
try {
db.beginTransaction();
int previousIncrement = 0;
int windowLength = categoryArray.size() / 10;
if (windowLength == 0)
windowLength = 1;
int category_id = ih.getColumnIndex(CategoryTable.COLUMN_CATEGORY_ID);
int category_name = ih.getColumnIndex(CategoryTable.COLUMN_CATEGORY_NAME);
for (JsonElement jsonElement : categoryArray) {
category = gson.fromJson(jsonElement, Category.class);
ih.prepareForInsert();
ih.bind(category_id, category.getCategoryId());
ih.bind(category_name, category.getCategoryName());
ih.execute();
if (++previousIncrement == windowLength) {
previousIncrement = 0;
updateProgressBar(1);
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
ih.close();
}
}
Log.i(GroceryApplication.TAG, "refreshing category... DONE");
}
private void refreshGrocery(SQLiteDatabase db) {
Log.i(GroceryApplication.TAG, "refreshing grocery...");
// this is here for testing purposes
String date = "?date=2013-03-13";
// String date = ServerURLs.getDateNowAsArg();
String[] requestArgs = new String[]{date};
String getGrocery = buildGroceryURL(requestArgs);
JsonReader groceryReader = jsonParser.getReaderFromUrl(getGrocery);
if (groceryReader != null) {
int maxGroceryIdBefore = addNewGroceries(groceryReader, db);
int maxGroceryIdAfter = GroceryGoUtils.getMaxGroceryId(this);
if (maxGroceryIdAfter > maxGroceryIdBefore)
removeExpiredGroceries(maxGroceryIdBefore);
}
Log.i(GroceryApplication.TAG, "refreshing grocery...DONE");
}
private void refreshStoreParent(SQLiteDatabase db) {
Log.i(GroceryApplication.TAG, "refreshing store parent...");
Gson gson = new Gson();
JsonArray storeParentArray = jsonParser.getJSONFromUrl(ServerURLs.getStoreParentUrl());
DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(db, StoreParentTable.TABLE_STORE_PARENT);
StoreParent storeParent;
if (storeParentArray != null) {
try {
db.beginTransaction();
int previousIncrement = 0;
int windowLength = storeParentArray.size() / 10;
if (windowLength == 0)
windowLength = 1;
int store_parent_id = ih.getColumnIndex(StoreParentTable.COLUMN_STORE_PARENT_ID);
int store_parent_name = ih.getColumnIndex(StoreParentTable.COLUMN_STORE_PARENT_NAME);
for (JsonElement jsonElement : storeParentArray) {
storeParent = gson.fromJson(jsonElement, StoreParent.class);
ih.prepareForInsert();
ih.bind(store_parent_id, storeParent.getStoreParentId());
ih.bind(store_parent_name, storeParent.getName());
ih.execute();
if (++previousIncrement == windowLength) {
previousIncrement = 0;
updateProgressBar(1);
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
ih.close();
}
}
Log.i(GroceryApplication.TAG, "refreshing store parent...DONE");
}
private void refreshStore(SQLiteDatabase db) {
Log.i(GroceryApplication.TAG, "refreshing store...");
Gson gson = new Gson();
JsonArray storeArray = jsonParser.getJSONFromUrl(ServerURLs.getStoreUrl());
DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(db, StoreTable.TABLE_STORE);
Store store;
if (storeArray != null) {
try {
db.beginTransaction();
int previousIncrement = 0;
int windowLength = storeArray.size() / 10;
if (windowLength == 0)
windowLength = 1;
int store_id = ih.getColumnIndex(StoreTable.COLUMN_STORE_ID);
int store_parent = ih.getColumnIndex(StoreTable.COLUMN_STORE_PARENT);
int store_flyer = ih.getColumnIndex(StoreTable.COLUMN_STORE_FLYER);
int store_addr = ih.getColumnIndex(StoreTable.COLUMN_STORE_ADDR);
int store_lat = ih.getColumnIndex(StoreTable.COLUMN_STORE_LATITUDE);
int store_lng = ih.getColumnIndex(StoreTable.COLUMN_STORE_LONGITUDE);
for (JsonElement jsonElement : storeArray) {
store = gson.fromJson(jsonElement, Store.class);
ih.prepareForInsert();
ih.bind(store_id, store.getStoreId());
ih.bind(store_parent, store.getStoreParent().getStoreParentId());
if (store.getFlyer() != null)
ih.bind(store_flyer, store.getFlyer().getFlyerId());
if (store.getStoreAddress() != null)
ih.bind(store_addr, store.getStoreAddress());
if (store.getStoreLatitude() != null)
ih.bind(store_lat, store.getStoreLatitude());
if (store.getStoreLongitude() != null)
ih.bind(store_lng, store.getStoreLongitude());
ih.execute();
if (++previousIncrement == windowLength) {
previousIncrement = 0;
updateProgressBar(1);
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
ih.close();
}
}
Log.i(GroceryApplication.TAG, "refreshing store...DONE");
}
private void refreshFlyer(SQLiteDatabase db) {
Log.i(GroceryApplication.TAG, "refreshing flyer...");
Gson gson = new Gson();
JsonArray flyerArray = jsonParser.getJSONFromUrl(ServerURLs.getFlyerUrl());
DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(db, FlyerTable.TABLE_FLYER);
Flyer flyer;
if (flyerArray != null) {
try {
db.beginTransaction();
int previousIncrement = 0;
int windowLength = flyerArray.size() / 10;
if (windowLength == 0)
windowLength = 1;
int flyer_id = ih.getColumnIndex(FlyerTable.COLUMN_FLYER_ID);
int flyer_url = ih.getColumnIndex(FlyerTable.COLUMN_FLYER_URL);
int flyer_store_parent = ih.getColumnIndex(FlyerTable.COLUMN_FLYER_STOREPARENT);
for (JsonElement jsonElement : flyerArray) {
flyer = gson.fromJson(jsonElement, Flyer.class);
ih.prepareForInsert();
ih.bind(flyer_id, flyer.getFlyerId());
ih.bind(flyer_url, flyer.getUrl());
ih.bind(flyer_store_parent, flyer.getStoreParent().getStoreParentId());
ih.execute();
if (++previousIncrement == windowLength) {
previousIncrement = 0;
updateProgressBar(1);
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
ih.close();
}
}
Log.i(GroceryApplication.TAG, "refreshing flyer...DONE");
}
private int addNewGroceries(JsonReader groceryReader, SQLiteDatabase db) {
//TODO: hard coded date format!! not good...
Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy").create();
DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(db, GroceryTable.TABLE_GROCERY);
Grocery[] groceries = gson.fromJson(groceryReader, Grocery[].class);
int maxGroceryIdBefore = GroceryGoUtils.getMaxGroceryId(this);
try {
db.beginTransaction();
int previousIncrement = 0;
int numGrocery = groceries.length;
int windowLength = numGrocery / 50;
if (windowLength == 0)
windowLength = 1;
Log.i("GroceryOTG", "Number of grocery available: " + numGrocery);
int grocery_id = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_ID);
int grocery_name = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_NAME);
int grocery_price = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_PRICE);
int grocery_category = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_CATEGORY);
int grocery_expiry = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_EXPIRY);
int grocery_score = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_SCORE);
int grocery_flyer = ih.getColumnIndex(GroceryTable.COLUMN_GROCERY_FLYER);
for (int i = 0; i < numGrocery; i++) {
if (stopped) {
Log.i(GroceryApplication.TAG, "intent serverice stopped");
break;
}
ih.prepareForInsert();
ih.bind(grocery_id, groceries[i].getGroceryId());
ih.bind(grocery_name, groceries[i].getRawString());
if (groceries[i].getTotalPrice() != null)
ih.bind(grocery_price, groceries[i].getTotalPrice());
if (groceries[i].getCategoryId() != null)
ih.bind(grocery_category, groceries[i].getCategoryId());
if (groceries[i].getEndDate() != null)
ih.bind(grocery_expiry, groceries[i].getEndDate().getTime());
if (groceries[i].getScore() != null)
ih.bind(grocery_score, groceries[i].getScore());
ih.bind(grocery_flyer, groceries[i].getFlyer().getFlyerId());
ih.execute();
if (++previousIncrement == windowLength) {
previousIncrement = 0;
updateProgressBar(1);
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
ih.close();
}
return maxGroceryIdBefore;
}
private void removeExpiredGroceries(int maxGroceryIdBefore) {
String selection = GroceryTable.COLUMN_GROCERY_ID + " <= '" + maxGroceryIdBefore + "'";
getContentResolver().delete(GroceryotgProvider.CONTENT_URI_GRO, selection, null);
}
private String buildGroceryURL(String[] args) {
StringBuilder url = new StringBuilder();
url.append(ServerURLs.getGroceryBaseUrl());
for (String arg : args)
url.append(arg);
return url.toString();
}
private void updateProgressBar(int inc) {
Intent intent = new Intent();
intent.setAction(SplashScreenActivity.BROADCAST_ACTION_UPDATE_PROGRESS);
intent.putExtra(SplashScreenActivity.BROADCAST_ACTION_UPDATE_PROGRESS_INCREMENT, inc);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}