package com.transitwidget.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import com.transitwidget.feed.model.Agency;
import com.transitwidget.feed.model.BusPrediction;
import com.transitwidget.feed.model.Direction;
import com.transitwidget.feed.model.Route;
import com.transitwidget.feed.model.Stop;
public class ServiceProvider {
private static final String TAG = ServiceProvider.class.getName();
private static Map<String, ServiceAPI> services;
static {
services = new HashMap<String, ServiceAPI>();
// Add service providers
addService(new NextBusAPI());
}
public static void addService(ServiceAPI service) {
Log.i(TAG, "Adding service " + service + " to service provider");
services.put(service.getName(), service);
}
public static List<BusPrediction> getPredictions(String service, String agencyTag, String stopTag, String directionTag, String routeTag) {
return services.get(service).getPredictions(agencyTag, stopTag, directionTag, routeTag);
}
public static Stop getStop(Context ctx, String agencyTag, String stopTag) {
Stop result = null;
String selection = Stop.AGENCY + " = ? AND " + Stop.TAG + " = ?";
String[] selectionArgs = { agencyTag, stopTag };
Cursor cursor = ctx.getContentResolver().query(Stop.CONTENT_URI, null, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
result = new Stop(cursor);
}
cursor.close();
return result;
}
public static Direction getDirection(Context ctx, String agencyTag, String directionTag) {
Direction result = null;
String selection = Direction.AGENCY + " = ? AND " + Direction.TAG + " = ?";
String[] selectionArgs = { agencyTag, directionTag };
Cursor cursor = ctx.getContentResolver().query(Direction.CONTENT_URI, null, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
result = new Direction(cursor, ctx);
}
cursor.close();
return result;
}
public static Route getRoute(Context ctx, String agencyTag, String routeTag) {
Route result = null;
String selection = Route.AGENCY + " = ? AND " + Route.TAG + " = ?";
String[] selectionArgs = { agencyTag, routeTag };
Cursor cursor = ctx.getContentResolver().query(Route.CONTENT_URI, null, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
result = new Route(cursor);
}
cursor.close();
return result;
}
public static Agency getAgency(Context ctx, String agencyTag) {
Agency result = null;
String selection = Agency.TAG + " = ?";
String[] selectionArgs = { agencyTag };
Cursor cursor = ctx.getContentResolver().query(Agency.CONTENT_URI, null, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
result = new Agency(cursor);
}
cursor.close();
return result;
}
/**
* Get a list of all the agencies provided by the service providers.
*
* Check for existing agencies stored in the database, if there are any found those are returned.
* If nothing is in the database, the list is generated from all the service provider APIs and
* persisted to the database.
*
* @param ctx
* @return
*/
public static List<Agency> getAgencies(Context ctx) {
List<Agency> results = new ArrayList<Agency>();
// Check for database results.
Cursor cursor = ctx.getContentResolver().query(Agency.CONTENT_URI, null, null, null, null);
while (cursor != null && cursor.moveToNext()) {
results.add(new Agency(cursor));
}
cursor.close();
if (results.isEmpty()) {
// Nothing in DB, load from API
for (ServiceAPI service : services.values()) {
for (Agency agency : service.getAgencies()) {
agency.setService(service.getName());
results.add(agency);
}
}
// Persist back to DB
for (Agency agency : results) {
// Log.d(TAG, "Persisting agency " + agency + " to database.");
ctx.getContentResolver().insert(Agency.CONTENT_URI, agency.getContentValues());
}
}
return results;
}
public static List<Route> getRoutes(Context ctx, String agencyTag) {
List<Route> results = new ArrayList<Route>();
// Check for database results.
String selection = Route.AGENCY + " = ?";
String[] selectionArgs = { agencyTag };
Cursor cursor = ctx.getContentResolver().query(Route.CONTENT_URI, null, selection, selectionArgs, null);
while (cursor.moveToNext()) {
results.add(new Route(cursor));
}
cursor.close();
if (results.isEmpty()) {
// Get service
String serviceName = getAgencyService(ctx, agencyTag);
ServiceAPI service = services.get(serviceName);
results.addAll(service.getRoutes(agencyTag));
// Persist back to DB
for (Route route: results) {
route.setAgency(agencyTag);
// Log.d(TAG, "Persisting route " + route + " to database.");
ctx.getContentResolver().insert(Route.CONTENT_URI, route.getContentValues());
}
}
return results;
}
public static List<Direction> getRouteConfig(Context ctx, String agencyTag, String routeTag) {
List<Direction> results = new ArrayList<Direction>();
// Check for database results.
String selection = Direction.AGENCY + " = ? AND " + Direction.ROUTE + " = ?";
String[] selectionArgs = { agencyTag, routeTag };
Cursor cursor = ctx.getContentResolver().query(Direction.CONTENT_URI, null, selection, selectionArgs, null);
while (cursor.moveToNext()) {
results.add(new Direction(cursor, ctx));
}
cursor.close();
if (results.isEmpty()) {
// Get service
String serviceName = getAgencyService(ctx, agencyTag);
ServiceAPI service = services.get(serviceName);
results.addAll(service.getRouteConfig(agencyTag, routeTag));
// Persist back to DB
for (Direction direction: results) {
// Log.d(TAG, "Persisting directions " + direction + " to database.");
direction.setAgency(agencyTag);
direction.setRoute(routeTag);
ctx.getContentResolver().insert(Direction.CONTENT_URI, direction.getContentValues());
// Persist stops
for (Stop stop : direction.getStops()) {
stop.setAgency(agencyTag);
String stopSelection = Stop.TAG + " = ? AND " + Stop.AGENCY + " = ?";
String[] stopSelectionArgs = { stop.getTag(), stop.getAgency() };
Cursor stopCursor = ctx.getContentResolver().query(Stop.CONTENT_URI, null, stopSelection, stopSelectionArgs, null);
if (!stopCursor.moveToFirst()) {
// only add the stop if it doesn't exist
// Log.d(TAG, "Persisting stop " + stop + " to database.");
ctx.getContentResolver().insert(Stop.CONTENT_URI, stop.getContentValues());
}
stopCursor.close();
}
}
}
return results;
}
private static String getAgencyService(Context ctx, String agencyTag) {
String[] projection = {Agency.SERVICE};
String selection = Agency.TAG + " = ?";
String[] selectionArgs = { agencyTag };
Cursor serviceCursor = ctx.getContentResolver().query(Agency.CONTENT_URI, projection, selection, selectionArgs, null);
serviceCursor.moveToFirst();
String serviceName = serviceCursor.getString(0);
serviceCursor.close();
return serviceName;
}
}