diff --git a/res/values/strings.xml b/res/values/strings.xml
index 41f894b..d88faf4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -42,5 +42,6 @@
Silence alarm
Cancel alarm
Set alarm
+ Leaving
\ No newline at end of file
diff --git a/src/com/dougkeen/bart/BartRunnerApplication.java b/src/com/dougkeen/bart/BartRunnerApplication.java
index ab73720..458a786 100644
--- a/src/com/dougkeen/bart/BartRunnerApplication.java
+++ b/src/com/dougkeen/bart/BartRunnerApplication.java
@@ -31,6 +31,18 @@ public class BartRunnerApplication extends Application {
private MediaPlayer mAlarmMediaPlayer;
+ private static Context context;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ context = getApplicationContext();
+ }
+
+ public static Context getAppContext() {
+ return context;
+ }
+
public boolean shouldPlayAlarmRingtone() {
return mPlayAlarmRingtone;
}
diff --git a/src/com/dougkeen/bart/activities/RoutesListActivity.java b/src/com/dougkeen/bart/activities/RoutesListActivity.java
index 74735c6..65ae665 100644
--- a/src/com/dougkeen/bart/activities/RoutesListActivity.java
+++ b/src/com/dougkeen/bart/activities/RoutesListActivity.java
@@ -18,11 +18,10 @@ import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
-import com.WazaBe.HoloEverywhere.widget.TextView;
-
import com.WazaBe.HoloEverywhere.app.AlertDialog;
import com.WazaBe.HoloEverywhere.app.DialogFragment;
import com.WazaBe.HoloEverywhere.sherlock.SActivity;
+import com.WazaBe.HoloEverywhere.widget.TextView;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
diff --git a/src/com/dougkeen/bart/controls/CountdownTextView.java b/src/com/dougkeen/bart/controls/CountdownTextView.java
index e573567..3183938 100644
--- a/src/com/dougkeen/bart/controls/CountdownTextView.java
+++ b/src/com/dougkeen/bart/controls/CountdownTextView.java
@@ -1,57 +1,57 @@
-package com.dougkeen.bart.controls;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.dougkeen.bart.model.TextProvider;
-
-public class CountdownTextView extends TextView implements
- Ticker.TickSubscriber {
-
- private TextProvider mTextProvider;
- private int mTickInterval;
-
- public CountdownTextView(Context context) {
- super(context);
- }
-
- public CountdownTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- setInstanceVarsFromAttrs(attrs);
- }
-
- public CountdownTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setInstanceVarsFromAttrs(attrs);
- }
-
- private void setInstanceVarsFromAttrs(AttributeSet attrs) {
- int tickInterval = attrs.getAttributeIntValue(
- "http://schemas.android.com/apk/res/com.dougkeen.bart",
- "tickInterval", 0);
- if (tickInterval > 0) {
- setTickInterval(tickInterval);
- }
- }
-
- public void setTextProvider(TextProvider provider) {
- mTextProvider = provider;
- Ticker.getInstance().addSubscriber(this, getContext());
- }
-
- @Override
- public int getTickInterval() {
- return mTickInterval;
- }
-
- public void setTickInterval(int tickInterval) {
- this.mTickInterval = tickInterval;
- }
-
- @Override
- public void onTick(long tickNumber) {
- setText(mTextProvider.getText(tickNumber));
- }
-
-}
+package com.dougkeen.bart.controls;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.dougkeen.bart.model.TextProvider;
+
+public class CountdownTextView extends TextView implements
+ Ticker.TickSubscriber {
+
+ private TextProvider mTextProvider;
+ private int mTickInterval;
+
+ public CountdownTextView(Context context) {
+ super(context);
+ }
+
+ public CountdownTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setInstanceVarsFromAttrs(attrs);
+ }
+
+ public CountdownTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setInstanceVarsFromAttrs(attrs);
+ }
+
+ private void setInstanceVarsFromAttrs(AttributeSet attrs) {
+ int tickInterval = attrs.getAttributeIntValue(
+ "http://schemas.android.com/apk/res/com.dougkeen.bart",
+ "tickInterval", 0);
+ if (tickInterval > 0) {
+ setTickInterval(tickInterval);
+ }
+ }
+
+ public void setTextProvider(TextProvider provider) {
+ mTextProvider = provider;
+ Ticker.getInstance().addSubscriber(this, getContext());
+ }
+
+ @Override
+ public int getTickInterval() {
+ return mTickInterval;
+ }
+
+ public void setTickInterval(int tickInterval) {
+ this.mTickInterval = tickInterval;
+ }
+
+ @Override
+ public void onTick(long tickNumber) {
+ setText(mTextProvider.getText(tickNumber));
+ }
+
+}
diff --git a/src/com/dougkeen/bart/controls/SwipeHelper.java b/src/com/dougkeen/bart/controls/SwipeHelper.java
index 490d21b..f242038 100644
--- a/src/com/dougkeen/bart/controls/SwipeHelper.java
+++ b/src/com/dougkeen/bart/controls/SwipeHelper.java
@@ -86,8 +86,8 @@ public class SwipeHelper implements View.OnTouchListener {
private float mTranslationX;
/**
- * The callback interface used by {@link SwipeHelper} to inform its
- * client about a successful dismissal of the view for which it was created.
+ * The callback interface used by {@link SwipeHelper} to inform its client
+ * about a successful dismissal of the view for which it was created.
*/
public interface OnDismissCallback {
/**
diff --git a/src/com/dougkeen/bart/controls/Ticker.java b/src/com/dougkeen/bart/controls/Ticker.java
index da2c052..03ddee3 100644
--- a/src/com/dougkeen/bart/controls/Ticker.java
+++ b/src/com/dougkeen/bart/controls/Ticker.java
@@ -1,114 +1,114 @@
-package com.dougkeen.bart.controls;
-
-import java.util.Iterator;
-import java.util.WeakHashMap;
-
-import android.content.Context;
-import android.os.Handler;
-
-public class Ticker {
- public static interface TickSubscriber {
- int getTickInterval();
-
- void onTick(long mTickCount);
- }
-
- private static Ticker sInstance;
-
- private WeakHashMap mSubscribers;
-
- private WeakHashMap mTickerHosts;
-
- private TickerEngine mEngine;
-
- private static class TickerEngine implements Runnable {
-
- private static final int TICK_INTERVAL_MILLIS = 1000;
- private Ticker publisher;
- private Handler mHandler;
- private boolean mPendingRequest = false;
- private boolean mForceStop = false;
- private long mTickCount = 0;
-
- public TickerEngine(Ticker publisher) {
- this.publisher = publisher;
- this.mHandler = new Handler();
- }
-
- @Override
- public void run() {
- mPendingRequest = false;
- if (mForceStop) {
- mForceStop = false;
- return;
- }
-
- long startTimeNanos = System.nanoTime();
- Iterator iterator = publisher.mSubscribers.keySet()
- .iterator();
- boolean stillHasListeners = false;
- while (iterator.hasNext()) {
- TickSubscriber subscriber = iterator.next();
- if (subscriber == null) {
- continue;
- }
-
- stillHasListeners = true;
- if (subscriber.getTickInterval() > 0
- && mTickCount % subscriber.getTickInterval() == 0)
- subscriber.onTick(mTickCount);
- }
- long endTimeNanos = System.nanoTime();
-
- if (stillHasListeners && !mPendingRequest) {
- mHandler.postDelayed(this, TICK_INTERVAL_MILLIS
- - ((endTimeNanos - startTimeNanos) / 1000000));
- mPendingRequest = true;
- mTickCount++;
- } else {
- mPendingRequest = false;
- }
- }
-
- public boolean isOn() {
- return mPendingRequest;
- }
-
- public void stop() {
- mForceStop = true;
- }
-
- };
-
- public synchronized static Ticker getInstance() {
- if (sInstance == null) {
- sInstance = new Ticker();
- }
- return sInstance;
- }
-
- public void addSubscriber(TickSubscriber subscriber, Context host) {
- if (!mSubscribers.containsKey(subscriber) && subscriber != null) {
- mSubscribers.put(subscriber, null);
- startTicking(host);
- }
- }
-
- private Ticker() {
- mSubscribers = new WeakHashMap();
- mTickerHosts = new WeakHashMap();
- mEngine = new TickerEngine(this);
- }
-
- public void startTicking(Context host) {
- mTickerHosts.put(host, true);
- if (!mEngine.isOn())
- mEngine.run();
- }
-
- public void stopTicking(Context host) {
- mTickerHosts.remove(host);
- if (mEngine.isOn() && mTickerHosts.isEmpty())
- mEngine.stop();
- }
-}
+package com.dougkeen.bart.controls;
+
+import java.util.Iterator;
+import java.util.WeakHashMap;
+
+import android.content.Context;
+import android.os.Handler;
+
+public class Ticker {
+ public static interface TickSubscriber {
+ int getTickInterval();
+
+ void onTick(long mTickCount);
+ }
+
+ private static Ticker sInstance;
+
+ private WeakHashMap mSubscribers;
+
+ private WeakHashMap mTickerHosts;
+
+ private TickerEngine mEngine;
+
+ private static class TickerEngine implements Runnable {
+
+ private static final int TICK_INTERVAL_MILLIS = 1000;
+ private Ticker publisher;
+ private Handler mHandler;
+ private boolean mPendingRequest = false;
+ private boolean mForceStop = false;
+ private long mTickCount = 0;
+
+ public TickerEngine(Ticker publisher) {
+ this.publisher = publisher;
+ this.mHandler = new Handler();
+ }
+
+ @Override
+ public void run() {
+ mPendingRequest = false;
+ if (mForceStop) {
+ mForceStop = false;
+ return;
+ }
+
+ long startTimeNanos = System.nanoTime();
+ Iterator iterator = publisher.mSubscribers.keySet()
+ .iterator();
+ boolean stillHasListeners = false;
+ while (iterator.hasNext()) {
+ TickSubscriber subscriber = iterator.next();
+ if (subscriber == null) {
+ continue;
+ }
+
+ stillHasListeners = true;
+ if (subscriber.getTickInterval() > 0
+ && mTickCount % subscriber.getTickInterval() == 0)
+ subscriber.onTick(mTickCount);
+ }
+ long endTimeNanos = System.nanoTime();
+
+ if (stillHasListeners && !mPendingRequest) {
+ mHandler.postDelayed(this, TICK_INTERVAL_MILLIS
+ - ((endTimeNanos - startTimeNanos) / 1000000));
+ mPendingRequest = true;
+ mTickCount++;
+ } else {
+ mPendingRequest = false;
+ }
+ }
+
+ public boolean isOn() {
+ return mPendingRequest;
+ }
+
+ public void stop() {
+ mForceStop = true;
+ }
+
+ };
+
+ public synchronized static Ticker getInstance() {
+ if (sInstance == null) {
+ sInstance = new Ticker();
+ }
+ return sInstance;
+ }
+
+ public void addSubscriber(TickSubscriber subscriber, Context host) {
+ if (!mSubscribers.containsKey(subscriber) && subscriber != null) {
+ mSubscribers.put(subscriber, null);
+ startTicking(host);
+ }
+ }
+
+ private Ticker() {
+ mSubscribers = new WeakHashMap();
+ mTickerHosts = new WeakHashMap();
+ mEngine = new TickerEngine(this);
+ }
+
+ public void startTicking(Context host) {
+ mTickerHosts.put(host, true);
+ if (!mEngine.isOn())
+ mEngine.run();
+ }
+
+ public void stopTicking(Context host) {
+ mTickerHosts.remove(host);
+ if (mEngine.isOn() && mTickerHosts.isEmpty())
+ mEngine.stop();
+ }
+}
diff --git a/src/com/dougkeen/bart/controls/TimedTextSwitcher.java b/src/com/dougkeen/bart/controls/TimedTextSwitcher.java
index a82c052..60716ba 100644
--- a/src/com/dougkeen/bart/controls/TimedTextSwitcher.java
+++ b/src/com/dougkeen/bart/controls/TimedTextSwitcher.java
@@ -1,67 +1,67 @@
-package com.dougkeen.bart.controls;
-
-import org.apache.commons.lang3.StringUtils;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.TextSwitcher;
-
-import com.dougkeen.bart.model.TextProvider;
-
-public class TimedTextSwitcher extends TextSwitcher implements
- Ticker.TickSubscriber {
-
- public TimedTextSwitcher(Context context, AttributeSet attrs) {
- super(context, attrs);
- setInstanceVarsFromAttrs(attrs);
- }
-
- public TimedTextSwitcher(Context context) {
- super(context);
- }
-
- private void setInstanceVarsFromAttrs(AttributeSet attrs) {
- int tickInterval = attrs.getAttributeIntValue(
- "http://schemas.android.com/apk/res/com.dougkeen.bart",
- "tickInterval", 0);
- if (tickInterval > 0) {
- setTickInterval(tickInterval);
- }
- }
-
- private int mTickInterval;
- private TextProvider mTextProvider;
-
- @Override
- public int getTickInterval() {
- return mTickInterval;
- }
-
- public void setTickInterval(int tickInterval) {
- this.mTickInterval = tickInterval;
- }
-
- public void setTextProvider(TextProvider textProvider) {
- mTextProvider = textProvider;
- Ticker.getInstance().addSubscriber(this, getContext());
- }
-
- private CharSequence mLastText;
-
- @Override
- public void setCurrentText(CharSequence text) {
- mLastText = text;
- super.setCurrentText(text);
- }
-
- @Override
- public void onTick(long tickNumber) {
- String text = mTextProvider.getText(tickNumber);
- if (StringUtils.isNotBlank(text)
- && !StringUtils.equalsIgnoreCase(text, mLastText)) {
- mLastText = text;
- setText(text);
- }
- }
-
-}
+package com.dougkeen.bart.controls;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.TextSwitcher;
+
+import com.dougkeen.bart.model.TextProvider;
+
+public class TimedTextSwitcher extends TextSwitcher implements
+ Ticker.TickSubscriber {
+
+ public TimedTextSwitcher(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setInstanceVarsFromAttrs(attrs);
+ }
+
+ public TimedTextSwitcher(Context context) {
+ super(context);
+ }
+
+ private void setInstanceVarsFromAttrs(AttributeSet attrs) {
+ int tickInterval = attrs.getAttributeIntValue(
+ "http://schemas.android.com/apk/res/com.dougkeen.bart",
+ "tickInterval", 0);
+ if (tickInterval > 0) {
+ setTickInterval(tickInterval);
+ }
+ }
+
+ private int mTickInterval;
+ private TextProvider mTextProvider;
+
+ @Override
+ public int getTickInterval() {
+ return mTickInterval;
+ }
+
+ public void setTickInterval(int tickInterval) {
+ this.mTickInterval = tickInterval;
+ }
+
+ public void setTextProvider(TextProvider textProvider) {
+ mTextProvider = textProvider;
+ Ticker.getInstance().addSubscriber(this, getContext());
+ }
+
+ private CharSequence mLastText;
+
+ @Override
+ public void setCurrentText(CharSequence text) {
+ mLastText = text;
+ super.setCurrentText(text);
+ }
+
+ @Override
+ public void onTick(long tickNumber) {
+ String text = mTextProvider.getText(tickNumber);
+ if (StringUtils.isNotBlank(text)
+ && !StringUtils.equalsIgnoreCase(text, mLastText)) {
+ mLastText = text;
+ setText(text);
+ }
+ }
+
+}
diff --git a/src/com/dougkeen/bart/controls/YourTrainLayout.java b/src/com/dougkeen/bart/controls/YourTrainLayout.java
index a042c61..2b7a748 100644
--- a/src/com/dougkeen/bart/controls/YourTrainLayout.java
+++ b/src/com/dougkeen/bart/controls/YourTrainLayout.java
@@ -95,7 +95,7 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
@Override
public String getText(long tickNumber) {
if (boardedDeparture.hasDeparted()) {
- return "Departed";
+ return getContext().getString(R.string.leaving);
} else {
return "Leaves in " + boardedDeparture.getCountdownText()
+ " " + boardedDeparture.getUncertaintyText();
diff --git a/src/com/dougkeen/bart/data/BartContentProvider.java b/src/com/dougkeen/bart/data/BartContentProvider.java
index 0e66b3e..dd5239a 100644
--- a/src/com/dougkeen/bart/data/BartContentProvider.java
+++ b/src/com/dougkeen/bart/data/BartContentProvider.java
@@ -1,271 +1,271 @@
-package com.dougkeen.bart.data;
-
-import java.util.HashMap;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.database.MatrixCursor.RowBuilder;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.text.TextUtils;
-
-import com.dougkeen.bart.model.Constants;
-
-public class BartContentProvider extends ContentProvider {
-
- private static final UriMatcher sUriMatcher;
- private static HashMap sFavoritesProjectionMap;
-
- private static final int FAVORITES = 1;
- private static final int FAVORITE_ID = 2;
- private static final int ARBITRARY_ROUTE = 3;
- private static final int ARBITRARY_ROUTE_UNDEFINED = 4;
-
- /**
- * The default sort order for events
- */
- private static final String DEFAULT_SORT_ORDER = RoutesColumns.FROM_STATION.string
- + " DESC";
-
- static {
- sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- sUriMatcher.addURI(Constants.AUTHORITY, "favorites", FAVORITES);
- sUriMatcher.addURI(Constants.AUTHORITY, "favorites/#", FAVORITE_ID);
- sUriMatcher.addURI(Constants.AUTHORITY, "route/*/*", ARBITRARY_ROUTE);
- sUriMatcher.addURI(Constants.AUTHORITY, "route",
- ARBITRARY_ROUTE_UNDEFINED);
-
- sFavoritesProjectionMap = new HashMap();
- sFavoritesProjectionMap.put(RoutesColumns._ID.string,
- RoutesColumns._ID.string);
- sFavoritesProjectionMap.put(RoutesColumns.FROM_STATION.string,
- RoutesColumns.FROM_STATION.string);
- sFavoritesProjectionMap.put(RoutesColumns.TO_STATION.string,
- RoutesColumns.TO_STATION.string);
- sFavoritesProjectionMap.put(RoutesColumns.FARE.string,
- RoutesColumns.FARE.string);
- sFavoritesProjectionMap.put(RoutesColumns.FARE_LAST_UPDATED.string,
- RoutesColumns.FARE_LAST_UPDATED.string);
- sFavoritesProjectionMap.put(
- RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
- RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string);
- sFavoritesProjectionMap.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
- RoutesColumns.AVERAGE_TRIP_LENGTH.string);
- }
-
- private DatabaseHelper mDatabaseHelper;
-
- @Override
- public boolean onCreate() {
- mDatabaseHelper = new DatabaseHelper(getContext());
- return true;
- }
-
- @Override
- public String getType(Uri uri) {
- int match = sUriMatcher.match(uri);
- if (match == FAVORITES) {
- return Constants.FAVORITE_CONTENT_TYPE;
- } else if (match == FAVORITE_ID) {
- return Constants.FAVORITE_CONTENT_ITEM_TYPE;
- } else if (match == ARBITRARY_ROUTE) {
- return Constants.ARBITRARY_ROUTE_TYPE;
- } else if (match == ARBITRARY_ROUTE_UNDEFINED) {
- return Constants.ARBITRARY_ROUTE_UNDEFINED_TYPE;
- } else {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
-
- String orderBy = sortOrder;
-
- int match = sUriMatcher.match(uri);
-
- if (match == ARBITRARY_ROUTE) {
- final String origin = uri.getPathSegments().get(1);
- final String destination = uri.getPathSegments().get(2);
-
- qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
- qb.setProjectionMap(sFavoritesProjectionMap);
- qb.appendWhere(String.format("%s = '%s' AND %s = '%s'",
- RoutesColumns.FROM_STATION, origin,
- RoutesColumns.TO_STATION, destination));
- Cursor query = qb.query(db, projection, selection, selectionArgs,
- null, null, sortOrder);
- if (query.getCount() > 0)
- return query;
-
- MatrixCursor returnCursor = new MatrixCursor(projection);
- RowBuilder newRow = returnCursor.newRow();
-
- for (String column : projection) {
- if (column.equals(RoutesColumns.FROM_STATION.string)) {
- newRow.add(origin);
- } else if (column.equals(RoutesColumns.TO_STATION.string)) {
- newRow.add(destination);
- } else {
- newRow.add(null);
- }
- }
-
- return returnCursor;
- } else if (match == FAVORITE_ID) {
- qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
- qb.setProjectionMap(sFavoritesProjectionMap);
- qb.appendWhere(RoutesColumns._ID + " = "
- + uri.getPathSegments().get(1));
- } else if (match == FAVORITES) {
- qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
- qb.setProjectionMap(sFavoritesProjectionMap);
- } else {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
-
- // If no sort order is specified use the default
- if (TextUtils.isEmpty(orderBy)) {
- orderBy = DEFAULT_SORT_ORDER;
- }
-
- // Get the database and run the query
- Cursor cursor = qb.query(db, projection, selection, selectionArgs,
- null, null, orderBy);
-
- // Tell the cursor what uri to watch, so it knows when its source data
- // changes
- cursor.setNotificationUri(getContext().getContentResolver(), uri);
- return cursor;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues initialValues) {
- ContentValues values;
- if (initialValues != null) {
- values = new ContentValues(initialValues);
- } else {
- values = new ContentValues();
- }
-
- SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
-
- // Validate the requested uri
- int match = sUriMatcher.match(uri);
- if (match == FAVORITES) {
- long rowId = -1;
- Cursor cursor = db
- .query(DatabaseHelper.FAVORITES_TABLE_NAME,
- new String[] { RoutesColumns._ID.string },
- RoutesColumns.FROM_STATION + "=? AND "
- + RoutesColumns.TO_STATION + "=?",
- new String[] {
- values.getAsString(RoutesColumns.FROM_STATION.string),
- values.getAsString(RoutesColumns.TO_STATION.string) },
- null, null, null);
- try {
- if (cursor.moveToFirst()) {
- rowId = cursor.getLong(0);
- }
- } finally {
- CursorUtils.closeCursorQuietly(cursor);
- }
- if (rowId < 0) {
- rowId = db.insert(DatabaseHelper.FAVORITES_TABLE_NAME,
- RoutesColumns.FROM_STATION.string, values);
- }
- if (rowId > 0) {
- Uri eventUri = ContentUris.withAppendedId(
- Constants.FAVORITE_CONTENT_URI, rowId);
- getContext().getContentResolver().notifyChange(eventUri, null,
- false);
- return eventUri;
- }
- } else {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
-
- throw new SQLException("Failed to insert row into " + uri);
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String where,
- String[] whereArgs) {
- SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
-
- // Validate the requested uri
- int match = sUriMatcher.match(uri);
- if (match == FAVORITE_ID) {
- String favoriteId = uri.getPathSegments().get(1);
- int count = db.update(
- DatabaseHelper.FAVORITES_TABLE_NAME,
- values,
- RoutesColumns._ID
- + " = "
- + favoriteId
- + (!TextUtils.isEmpty(where) ? " AND (" + where
- + ')' : ""), whereArgs);
- getContext().getContentResolver().notifyChange(uri, null);
- return count;
- } else if (match == ARBITRARY_ROUTE) {
- // Get the route with the origin and destination provided, and
- // simply delegate to the previous log branch. If the given route
- // doesn't exist, do nothing.
- String origin = uri.getPathSegments().get(1);
- String destination = uri.getPathSegments().get(2);
-
- Cursor query = db.query(DatabaseHelper.FAVORITES_TABLE_NAME,
- new String[] { RoutesColumns._ID.string },
- RoutesColumns.FROM_STATION.string + "=? AND "
- + RoutesColumns.TO_STATION.string + "=?",
- new String[] { origin, destination }, null, null, null);
-
- try {
- if (query.moveToFirst()) {
- return update(ContentUris.withAppendedId(
- Constants.FAVORITE_CONTENT_URI, query.getLong(0)),
- values, where, whereArgs);
- }
- } finally {
- CursorUtils.closeCursorQuietly(query);
- }
- }
- return 0;
- }
-
- @Override
- public int delete(Uri uri, String where, String[] whereArgs) {
- // TODO: Sync with REST service?
- SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
- int count;
- int match = sUriMatcher.match(uri);
- if (match == FAVORITES) {
- count = db.delete(DatabaseHelper.FAVORITES_TABLE_NAME, where,
- whereArgs);
- } else if (match == FAVORITE_ID) {
- String favoriteId = uri.getPathSegments().get(1);
- count = db.delete(
- DatabaseHelper.FAVORITES_TABLE_NAME,
- RoutesColumns._ID
- + " = "
- + favoriteId
- + (!TextUtils.isEmpty(where) ? " AND (" + where
- + ')' : ""), whereArgs);
- } else {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
-
- getContext().getContentResolver().notifyChange(uri, null);
- return count;
- }
-}
+package com.dougkeen.bart.data;
+
+import java.util.HashMap;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import com.dougkeen.bart.model.Constants;
+
+public class BartContentProvider extends ContentProvider {
+
+ private static final UriMatcher sUriMatcher;
+ private static HashMap sFavoritesProjectionMap;
+
+ private static final int FAVORITES = 1;
+ private static final int FAVORITE_ID = 2;
+ private static final int ARBITRARY_ROUTE = 3;
+ private static final int ARBITRARY_ROUTE_UNDEFINED = 4;
+
+ /**
+ * The default sort order for events
+ */
+ private static final String DEFAULT_SORT_ORDER = RoutesColumns.FROM_STATION.string
+ + " DESC";
+
+ static {
+ sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ sUriMatcher.addURI(Constants.AUTHORITY, "favorites", FAVORITES);
+ sUriMatcher.addURI(Constants.AUTHORITY, "favorites/#", FAVORITE_ID);
+ sUriMatcher.addURI(Constants.AUTHORITY, "route/*/*", ARBITRARY_ROUTE);
+ sUriMatcher.addURI(Constants.AUTHORITY, "route",
+ ARBITRARY_ROUTE_UNDEFINED);
+
+ sFavoritesProjectionMap = new HashMap();
+ sFavoritesProjectionMap.put(RoutesColumns._ID.string,
+ RoutesColumns._ID.string);
+ sFavoritesProjectionMap.put(RoutesColumns.FROM_STATION.string,
+ RoutesColumns.FROM_STATION.string);
+ sFavoritesProjectionMap.put(RoutesColumns.TO_STATION.string,
+ RoutesColumns.TO_STATION.string);
+ sFavoritesProjectionMap.put(RoutesColumns.FARE.string,
+ RoutesColumns.FARE.string);
+ sFavoritesProjectionMap.put(RoutesColumns.FARE_LAST_UPDATED.string,
+ RoutesColumns.FARE_LAST_UPDATED.string);
+ sFavoritesProjectionMap.put(
+ RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
+ RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string);
+ sFavoritesProjectionMap.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
+ RoutesColumns.AVERAGE_TRIP_LENGTH.string);
+ }
+
+ private DatabaseHelper mDatabaseHelper;
+
+ @Override
+ public boolean onCreate() {
+ mDatabaseHelper = new DatabaseHelper(getContext());
+ return true;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ int match = sUriMatcher.match(uri);
+ if (match == FAVORITES) {
+ return Constants.FAVORITE_CONTENT_TYPE;
+ } else if (match == FAVORITE_ID) {
+ return Constants.FAVORITE_CONTENT_ITEM_TYPE;
+ } else if (match == ARBITRARY_ROUTE) {
+ return Constants.ARBITRARY_ROUTE_TYPE;
+ } else if (match == ARBITRARY_ROUTE_UNDEFINED) {
+ return Constants.ARBITRARY_ROUTE_UNDEFINED_TYPE;
+ } else {
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+ SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
+
+ String orderBy = sortOrder;
+
+ int match = sUriMatcher.match(uri);
+
+ if (match == ARBITRARY_ROUTE) {
+ final String origin = uri.getPathSegments().get(1);
+ final String destination = uri.getPathSegments().get(2);
+
+ qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
+ qb.setProjectionMap(sFavoritesProjectionMap);
+ qb.appendWhere(String.format("%s = '%s' AND %s = '%s'",
+ RoutesColumns.FROM_STATION, origin,
+ RoutesColumns.TO_STATION, destination));
+ Cursor query = qb.query(db, projection, selection, selectionArgs,
+ null, null, sortOrder);
+ if (query.getCount() > 0)
+ return query;
+
+ MatrixCursor returnCursor = new MatrixCursor(projection);
+ RowBuilder newRow = returnCursor.newRow();
+
+ for (String column : projection) {
+ if (column.equals(RoutesColumns.FROM_STATION.string)) {
+ newRow.add(origin);
+ } else if (column.equals(RoutesColumns.TO_STATION.string)) {
+ newRow.add(destination);
+ } else {
+ newRow.add(null);
+ }
+ }
+
+ return returnCursor;
+ } else if (match == FAVORITE_ID) {
+ qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
+ qb.setProjectionMap(sFavoritesProjectionMap);
+ qb.appendWhere(RoutesColumns._ID + " = "
+ + uri.getPathSegments().get(1));
+ } else if (match == FAVORITES) {
+ qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
+ qb.setProjectionMap(sFavoritesProjectionMap);
+ } else {
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+
+ // If no sort order is specified use the default
+ if (TextUtils.isEmpty(orderBy)) {
+ orderBy = DEFAULT_SORT_ORDER;
+ }
+
+ // Get the database and run the query
+ Cursor cursor = qb.query(db, projection, selection, selectionArgs,
+ null, null, orderBy);
+
+ // Tell the cursor what uri to watch, so it knows when its source data
+ // changes
+ cursor.setNotificationUri(getContext().getContentResolver(), uri);
+ return cursor;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues initialValues) {
+ ContentValues values;
+ if (initialValues != null) {
+ values = new ContentValues(initialValues);
+ } else {
+ values = new ContentValues();
+ }
+
+ SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+
+ // Validate the requested uri
+ int match = sUriMatcher.match(uri);
+ if (match == FAVORITES) {
+ long rowId = -1;
+ Cursor cursor = db
+ .query(DatabaseHelper.FAVORITES_TABLE_NAME,
+ new String[] { RoutesColumns._ID.string },
+ RoutesColumns.FROM_STATION + "=? AND "
+ + RoutesColumns.TO_STATION + "=?",
+ new String[] {
+ values.getAsString(RoutesColumns.FROM_STATION.string),
+ values.getAsString(RoutesColumns.TO_STATION.string) },
+ null, null, null);
+ try {
+ if (cursor.moveToFirst()) {
+ rowId = cursor.getLong(0);
+ }
+ } finally {
+ CursorUtils.closeCursorQuietly(cursor);
+ }
+ if (rowId < 0) {
+ rowId = db.insert(DatabaseHelper.FAVORITES_TABLE_NAME,
+ RoutesColumns.FROM_STATION.string, values);
+ }
+ if (rowId > 0) {
+ Uri eventUri = ContentUris.withAppendedId(
+ Constants.FAVORITE_CONTENT_URI, rowId);
+ getContext().getContentResolver().notifyChange(eventUri, null,
+ false);
+ return eventUri;
+ }
+ } else {
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String where,
+ String[] whereArgs) {
+ SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+
+ // Validate the requested uri
+ int match = sUriMatcher.match(uri);
+ if (match == FAVORITE_ID) {
+ String favoriteId = uri.getPathSegments().get(1);
+ int count = db.update(
+ DatabaseHelper.FAVORITES_TABLE_NAME,
+ values,
+ RoutesColumns._ID
+ + " = "
+ + favoriteId
+ + (!TextUtils.isEmpty(where) ? " AND (" + where
+ + ')' : ""), whereArgs);
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ } else if (match == ARBITRARY_ROUTE) {
+ // Get the route with the origin and destination provided, and
+ // simply delegate to the previous log branch. If the given route
+ // doesn't exist, do nothing.
+ String origin = uri.getPathSegments().get(1);
+ String destination = uri.getPathSegments().get(2);
+
+ Cursor query = db.query(DatabaseHelper.FAVORITES_TABLE_NAME,
+ new String[] { RoutesColumns._ID.string },
+ RoutesColumns.FROM_STATION.string + "=? AND "
+ + RoutesColumns.TO_STATION.string + "=?",
+ new String[] { origin, destination }, null, null, null);
+
+ try {
+ if (query.moveToFirst()) {
+ return update(ContentUris.withAppendedId(
+ Constants.FAVORITE_CONTENT_URI, query.getLong(0)),
+ values, where, whereArgs);
+ }
+ } finally {
+ CursorUtils.closeCursorQuietly(query);
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public int delete(Uri uri, String where, String[] whereArgs) {
+ // TODO: Sync with REST service?
+ SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+ int count;
+ int match = sUriMatcher.match(uri);
+ if (match == FAVORITES) {
+ count = db.delete(DatabaseHelper.FAVORITES_TABLE_NAME, where,
+ whereArgs);
+ } else if (match == FAVORITE_ID) {
+ String favoriteId = uri.getPathSegments().get(1);
+ count = db.delete(
+ DatabaseHelper.FAVORITES_TABLE_NAME,
+ RoutesColumns._ID
+ + " = "
+ + favoriteId
+ + (!TextUtils.isEmpty(where) ? " AND (" + where
+ + ')' : ""), whereArgs);
+ } else {
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+}
diff --git a/src/com/dougkeen/bart/data/CursorUtils.java b/src/com/dougkeen/bart/data/CursorUtils.java
index 35a6b53..6f3edc7 100644
--- a/src/com/dougkeen/bart/data/CursorUtils.java
+++ b/src/com/dougkeen/bart/data/CursorUtils.java
@@ -1,23 +1,23 @@
-package com.dougkeen.bart.data;
-
-import android.database.Cursor;
-
-public final class CursorUtils {
- private CursorUtils() {
- // Static only class
- }
-
- public static final void closeCursorQuietly(Cursor cursor) {
- if (cursor != null && !cursor.isClosed()) {
- cursor.close();
- }
- }
-
- public static final String getString(Cursor cursor, RoutesColumns column) {
- return cursor.getString(cursor.getColumnIndex(column.string));
- }
-
- public static final Long getLong(Cursor cursor, RoutesColumns column) {
- return cursor.getLong(cursor.getColumnIndex(column.string));
- }
-}
+package com.dougkeen.bart.data;
+
+import android.database.Cursor;
+
+public final class CursorUtils {
+ private CursorUtils() {
+ // Static only class
+ }
+
+ public static final void closeCursorQuietly(Cursor cursor) {
+ if (cursor != null && !cursor.isClosed()) {
+ cursor.close();
+ }
+ }
+
+ public static final String getString(Cursor cursor, RoutesColumns column) {
+ return cursor.getString(cursor.getColumnIndex(column.string));
+ }
+
+ public static final Long getLong(Cursor cursor, RoutesColumns column) {
+ return cursor.getLong(cursor.getColumnIndex(column.string));
+ }
+}
diff --git a/src/com/dougkeen/bart/data/DatabaseHelper.java b/src/com/dougkeen/bart/data/DatabaseHelper.java
index d22383b..383aba1 100644
--- a/src/com/dougkeen/bart/data/DatabaseHelper.java
+++ b/src/com/dougkeen/bart/data/DatabaseHelper.java
@@ -1,98 +1,98 @@
-package com.dougkeen.bart.data;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-public class DatabaseHelper extends SQLiteOpenHelper {
-
- private static final String DATABASE_NAME = "bart.dougkeen.db";
- private static final int DATABASE_VERSION = 4;
-
- public static final String FAVORITES_TABLE_NAME = "Favorites";
-
- public DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- createFavoritesTable(db);
- }
-
- private void createFavoritesTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE IF NOT EXISTS " + FAVORITES_TABLE_NAME + " ("
- + RoutesColumns._ID.getColumnDef() + " PRIMARY KEY, "
- + RoutesColumns.FROM_STATION.getColumnDef() + ", "
- + RoutesColumns.TO_STATION.getColumnDef() + ", "
- + RoutesColumns.FARE.getColumnDef() + ", "
- + RoutesColumns.FARE_LAST_UPDATED.getColumnDef() + ", "
- + RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.getColumnDef() + ", "
- + RoutesColumns.AVERAGE_TRIP_LENGTH.getColumnDef() + ");");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.beginTransaction();
- try {
- createFavoritesTable(db);
-
- List columns = getColumns(db, FAVORITES_TABLE_NAME);
-
- db.execSQL("ALTER TABLE " + FAVORITES_TABLE_NAME
- + " RENAME TO temp_" + FAVORITES_TABLE_NAME);
-
- createFavoritesTable(db);
-
- columns.retainAll(getColumns(db, FAVORITES_TABLE_NAME));
-
- String cols = StringUtils.join(columns, ",");
- db.execSQL(String.format(
- "INSERT INTO %s (%s) SELECT %s from temp_%s",
- FAVORITES_TABLE_NAME, cols, cols, FAVORITES_TABLE_NAME));
-
- db.execSQL("DROP TABLE temp_" + FAVORITES_TABLE_NAME);
-
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- public static List getColumns(SQLiteDatabase db, String tableName) {
- List ar = null;
- Cursor c = null;
- try {
- c = db.rawQuery("select * from " + tableName + " limit 1", null);
- if (c != null) {
- ar = new ArrayList(Arrays.asList(c.getColumnNames()));
- }
- } catch (Exception e) {
- Log.v(tableName, e.getMessage(), e);
- e.printStackTrace();
- } finally {
- if (c != null)
- c.close();
- }
- return ar;
- }
-
- public static String join(List list, String delim) {
- StringBuilder buf = new StringBuilder();
- int num = list.size();
- for (int i = 0; i < num; i++) {
- if (i != 0)
- buf.append(delim);
- buf.append((String) list.get(i));
- }
- return buf.toString();
- }
-}
+package com.dougkeen.bart.data;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+public class DatabaseHelper extends SQLiteOpenHelper {
+
+ private static final String DATABASE_NAME = "bart.dougkeen.db";
+ private static final int DATABASE_VERSION = 4;
+
+ public static final String FAVORITES_TABLE_NAME = "Favorites";
+
+ public DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ createFavoritesTable(db);
+ }
+
+ private void createFavoritesTable(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + FAVORITES_TABLE_NAME + " ("
+ + RoutesColumns._ID.getColumnDef() + " PRIMARY KEY, "
+ + RoutesColumns.FROM_STATION.getColumnDef() + ", "
+ + RoutesColumns.TO_STATION.getColumnDef() + ", "
+ + RoutesColumns.FARE.getColumnDef() + ", "
+ + RoutesColumns.FARE_LAST_UPDATED.getColumnDef() + ", "
+ + RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.getColumnDef() + ", "
+ + RoutesColumns.AVERAGE_TRIP_LENGTH.getColumnDef() + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.beginTransaction();
+ try {
+ createFavoritesTable(db);
+
+ List columns = getColumns(db, FAVORITES_TABLE_NAME);
+
+ db.execSQL("ALTER TABLE " + FAVORITES_TABLE_NAME
+ + " RENAME TO temp_" + FAVORITES_TABLE_NAME);
+
+ createFavoritesTable(db);
+
+ columns.retainAll(getColumns(db, FAVORITES_TABLE_NAME));
+
+ String cols = StringUtils.join(columns, ",");
+ db.execSQL(String.format(
+ "INSERT INTO %s (%s) SELECT %s from temp_%s",
+ FAVORITES_TABLE_NAME, cols, cols, FAVORITES_TABLE_NAME));
+
+ db.execSQL("DROP TABLE temp_" + FAVORITES_TABLE_NAME);
+
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+
+ public static List getColumns(SQLiteDatabase db, String tableName) {
+ List ar = null;
+ Cursor c = null;
+ try {
+ c = db.rawQuery("select * from " + tableName + " limit 1", null);
+ if (c != null) {
+ ar = new ArrayList(Arrays.asList(c.getColumnNames()));
+ }
+ } catch (Exception e) {
+ Log.v(tableName, e.getMessage(), e);
+ e.printStackTrace();
+ } finally {
+ if (c != null)
+ c.close();
+ }
+ return ar;
+ }
+
+ public static String join(List list, String delim) {
+ StringBuilder buf = new StringBuilder();
+ int num = list.size();
+ for (int i = 0; i < num; i++) {
+ if (i != 0)
+ buf.append(delim);
+ buf.append((String) list.get(i));
+ }
+ return buf.toString();
+ }
+}
diff --git a/src/com/dougkeen/bart/data/RoutesColumns.java b/src/com/dougkeen/bart/data/RoutesColumns.java
index e4d3097..0033cd7 100644
--- a/src/com/dougkeen/bart/data/RoutesColumns.java
+++ b/src/com/dougkeen/bart/data/RoutesColumns.java
@@ -1,28 +1,26 @@
-package com.dougkeen.bart.data;
-
-
-public enum RoutesColumns {
- _ID("_id", "INTEGER", false),
- FROM_STATION("FROM_STATION", "TEXT", false),
- TO_STATION("TO_STATION", "TEXT", false),
- FARE("FARE", "TEXT", true),
- FARE_LAST_UPDATED("FARE_LAST_UPDATED", "INTEGER", true),
- AVERAGE_TRIP_SAMPLE_COUNT("AVE_TRIP_SAMPLE_COUNT", "INTEGER", true),
- AVERAGE_TRIP_LENGTH("AVE_TRIP_LENGTH", "INTEGER", true);
-
-
- // This class cannot be instantiated
- private RoutesColumns(String string, String type, Boolean nullable) {
- this.string = string;
- this.sqliteType = type;
- this.nullable = nullable;
- }
-
- public final String string;
- public final String sqliteType;
- public final Boolean nullable;
-
- protected String getColumnDef() {
- return string + " " + sqliteType + (nullable?"":" NOT NULL");
- }
-}
+package com.dougkeen.bart.data;
+
+public enum RoutesColumns {
+ _ID("_id", "INTEGER", false),
+ FROM_STATION("FROM_STATION", "TEXT", false),
+ TO_STATION("TO_STATION", "TEXT", false),
+ FARE("FARE", "TEXT", true),
+ FARE_LAST_UPDATED("FARE_LAST_UPDATED", "INTEGER", true),
+ AVERAGE_TRIP_SAMPLE_COUNT("AVE_TRIP_SAMPLE_COUNT", "INTEGER", true),
+ AVERAGE_TRIP_LENGTH("AVE_TRIP_LENGTH", "INTEGER", true);
+
+ // This class cannot be instantiated
+ private RoutesColumns(String string, String type, Boolean nullable) {
+ this.string = string;
+ this.sqliteType = type;
+ this.nullable = nullable;
+ }
+
+ public final String string;
+ public final String sqliteType;
+ public final Boolean nullable;
+
+ protected String getColumnDef() {
+ return string + " " + sqliteType + (nullable ? "" : " NOT NULL");
+ }
+}
diff --git a/src/com/dougkeen/bart/model/Constants.java b/src/com/dougkeen/bart/model/Constants.java
index 479a077..c780c14 100644
--- a/src/com/dougkeen/bart/model/Constants.java
+++ b/src/com/dougkeen/bart/model/Constants.java
@@ -1,20 +1,20 @@
-package com.dougkeen.bart.model;
-
-import android.net.Uri;
-
-public class Constants {
- public static final String AUTHORITY = "com.dougkeen.bart.dataprovider";
- public static final String FAVORITE_CONTENT_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.favorite";
- public static final String ARBITRARY_ROUTE_UNDEFINED_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.arbitraryroute";
- public static final String ARBITRARY_ROUTE_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.arbitraryroute";
- public static final String FAVORITE_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.favorite";
- public static final Uri FAVORITE_CONTENT_URI = Uri.parse("content://"
- + AUTHORITY + "/favorites");
- public static final Uri ARBITRARY_ROUTE_CONTENT_URI_ROOT = Uri
- .parse("content://" + AUTHORITY + "/route");
- public static final String MAP_URL = "http://m.bart.gov/images/global/system-map29.gif";
-
- public static final String TAG = "com.dougkeen.BartRunner";
- public static final String API_KEY = "5LD9-IAYI-TRAT-MHHW";
- public static final String ACTION_ALARM = "com.dougkeen.action.ALARM";
-}
+package com.dougkeen.bart.model;
+
+import android.net.Uri;
+
+public class Constants {
+ public static final String AUTHORITY = "com.dougkeen.bart.dataprovider";
+ public static final String FAVORITE_CONTENT_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.favorite";
+ public static final String ARBITRARY_ROUTE_UNDEFINED_TYPE = "vnd.android.cursor.dir/com.dougkeen.bart.arbitraryroute";
+ public static final String ARBITRARY_ROUTE_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.arbitraryroute";
+ public static final String FAVORITE_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/com.dougkeen.bart.favorite";
+ public static final Uri FAVORITE_CONTENT_URI = Uri.parse("content://"
+ + AUTHORITY + "/favorites");
+ public static final Uri ARBITRARY_ROUTE_CONTENT_URI_ROOT = Uri
+ .parse("content://" + AUTHORITY + "/route");
+ public static final String MAP_URL = "http://m.bart.gov/images/global/system-map29.gif";
+
+ public static final String TAG = "com.dougkeen.BartRunner";
+ public static final String API_KEY = "5LD9-IAYI-TRAT-MHHW";
+ public static final String ACTION_ALARM = "com.dougkeen.action.ALARM";
+}
diff --git a/src/com/dougkeen/bart/model/Departure.java b/src/com/dougkeen/bart/model/Departure.java
index 52f5ce9..794aa9c 100644
--- a/src/com/dougkeen/bart/model/Departure.java
+++ b/src/com/dougkeen/bart/model/Departure.java
@@ -1,676 +1,678 @@
-package com.dougkeen.bart.model;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.lang3.time.DateFormatUtils;
-
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationCompat.Builder;
-import android.text.format.DateFormat;
-import android.util.Log;
-
-import com.dougkeen.bart.R;
-import com.dougkeen.bart.services.BoardedDepartureService;
-import com.dougkeen.util.Observable;
-
-public class Departure implements Parcelable, Comparable {
- private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 5000;
- private static final int EXPIRE_MINUTES_AFTER_ARRIVAL = 1;
-
- public Departure() {
- super();
- }
-
- public Departure(String destinationAbbr, String destinationColor,
- String platform, String direction, boolean bikeAllowed,
- String trainLength, int minutes) {
- super();
- this.trainDestination = Station.getByAbbreviation(destinationAbbr);
- this.destinationColor = destinationColor;
- this.platform = platform;
- this.direction = direction;
- this.bikeAllowed = bikeAllowed;
- this.trainLength = trainLength;
- this.minutes = minutes;
- }
-
- public Departure(Parcel in) {
- readFromParcel(in);
- }
-
- private Station origin;
- private Station trainDestination;
- private Station passengerDestination;
- private Line line;
- private String destinationColor;
- private String platform;
- private String direction;
- private boolean bikeAllowed;
- private String trainLength;
- private boolean requiresTransfer;
- private boolean transferScheduled;
-
- private int minutes;
-
- private long minEstimate;
- private long maxEstimate;
-
- private int estimatedTripTime;
-
- private boolean beganAsDeparted;
-
- private long arrivalTimeOverride;
-
- private Observable alarmLeadTimeMinutes = new Observable(
- 0);
- private Observable alarmPending = new Observable(false);
-
- public Station getOrigin() {
- return origin;
- }
-
- public void setOrigin(Station origin) {
- this.origin = origin;
- }
-
- public Station getTrainDestination() {
- return trainDestination;
- }
-
- public void setTrainDestination(Station destination) {
- this.trainDestination = destination;
- }
-
- public String getTrainDestinationName() {
- if (trainDestination != null)
- return trainDestination.name;
- return null;
- }
-
- public String getTrainDestinationAbbreviation() {
- if (trainDestination != null)
- return trainDestination.abbreviation;
- return null;
- }
-
- public Station getPassengerDestination() {
- return passengerDestination;
- }
-
- public void setPassengerDestination(Station passengerDestination) {
- this.passengerDestination = passengerDestination;
- }
-
- public StationPair getStationPair() {
- if (passengerDestination != null) {
- return new StationPair(origin, passengerDestination);
- } else {
- return null;
- }
- }
-
- public Line getLine() {
- return line;
- }
-
- public void setLine(Line line) {
- this.line = line;
- }
-
- public String getTrainDestinationColor() {
- return destinationColor;
- }
-
- public void setTrainDestinationColor(String destinationColor) {
- this.destinationColor = destinationColor;
- }
-
- public String getPlatform() {
- return platform;
- }
-
- public void setPlatform(String platform) {
- this.platform = platform;
- }
-
- public String getDirection() {
- return direction;
- }
-
- public void setDirection(String direction) {
- this.direction = direction;
- }
-
- public boolean isBikeAllowed() {
- return bikeAllowed;
- }
-
- public void setBikeAllowed(boolean bikeAllowed) {
- this.bikeAllowed = bikeAllowed;
- }
-
- public String getTrainLength() {
- return trainLength;
- }
-
- public void setTrainLength(String trainLength) {
- this.trainLength = trainLength;
- }
-
- public String getTrainLengthText() {
- return trainLength + " car train";
- }
-
- public boolean getRequiresTransfer() {
- return requiresTransfer;
- }
-
- public void setRequiresTransfer(boolean requiresTransfer) {
- this.requiresTransfer = requiresTransfer;
- }
-
- public boolean isTransferScheduled() {
- return transferScheduled;
- }
-
- public void setTransferScheduled(boolean transferScheduled) {
- this.transferScheduled = transferScheduled;
- }
-
- public int getMinutes() {
- return minutes;
- }
-
- public void setMinutes(int minutes) {
- this.minutes = minutes;
- if (minutes == 0) {
- beganAsDeparted = true;
- }
- }
-
- public long getMinEstimate() {
- return minEstimate;
- }
-
- public void setMinEstimate(long minEstimate) {
- this.minEstimate = minEstimate;
- }
-
- public long getMaxEstimate() {
- return maxEstimate;
- }
-
- public void setMaxEstimate(long maxEstimate) {
- this.maxEstimate = maxEstimate;
- }
-
- public int getEstimatedTripTime() {
- return estimatedTripTime;
- }
-
- public void setEstimatedTripTime(int estimatedTripTime) {
- this.estimatedTripTime = estimatedTripTime;
- }
-
- public boolean hasEstimatedTripTime() {
- return this.estimatedTripTime > 0;
- }
-
- public boolean hasAnyArrivalEstimate() {
- return this.estimatedTripTime > 0 || this.arrivalTimeOverride > 0;
- }
-
- public int getUncertaintySeconds() {
- return (int) (maxEstimate - minEstimate + 1000) / 2000;
- }
-
- public int getMinSecondsLeft() {
- return (int) ((getMinEstimate() - System.currentTimeMillis()) / 1000);
- }
-
- public int getMaxSecondsLeft() {
- return (int) ((getMaxEstimate() - System.currentTimeMillis()) / 1000);
- }
-
- public int getMeanSecondsLeft() {
- return (int) getMeanSecondsLeft(getMinEstimate(), getMaxEstimate());
- }
-
- public int getMeanSecondsLeft(long min, long max) {
- return (int) ((getMeanEstimate(min, max) - System.currentTimeMillis()) / 1000);
- }
-
- public long getMeanEstimate() {
- return getMeanEstimate(getMinEstimate(), getMaxEstimate());
- }
-
- public long getMeanEstimate(long min, long max) {
- return (min + max) / 2;
- }
-
- public long getArrivalTimeOverride() {
- return arrivalTimeOverride;
- }
-
- public void setArrivalTimeOverride(long arrivalTimeOverride) {
- this.arrivalTimeOverride = arrivalTimeOverride;
- }
-
- public long getEstimatedArrivalTime() {
- if (arrivalTimeOverride > 0) {
- return arrivalTimeOverride;
- }
- return getMeanEstimate() + getEstimatedTripTime();
- }
-
- public long getEstimatedArrivalMinutesLeft() {
- long millisLeft = getEstimatedArrivalTime()
- - System.currentTimeMillis();
- if (millisLeft < 0) {
- return -1;
- } else {
- // Add ~30s to emulate rounding
- return (millisLeft + 29999) / (60 * 1000);
- }
- }
-
- public String getEstimatedArrivalMinutesLeftText(Context context) {
- if (!hasAnyArrivalEstimate()) {
- return "Estimated arrival unknown";
- }
- long minutesLeft = getEstimatedArrivalMinutesLeft();
- if (minutesLeft < 0) {
- return "Arrived at destination";
- } else if (minutesLeft == 0) {
- return "Arrives ~" + getEstimatedArrivalTimeText(context)
- + " (<1 min)";
- } else if (minutesLeft == 1) {
- return "Arrives ~" + getEstimatedArrivalTimeText(context)
- + " (1 min)";
- } else {
- return "Arrives ~" + getEstimatedArrivalTimeText(context) + " ("
- + minutesLeft + " mins)";
- }
- }
-
- public String getEstimatedArrivalTimeText(Context context) {
- if (getEstimatedTripTime() > 0 || arrivalTimeOverride > 0) {
- return DateFormat.getTimeFormat(context).format(
- new Date(getEstimatedArrivalTime()));
- } else {
- return "";
- }
- }
-
- public boolean hasDeparted() {
- return getMeanSecondsLeft() <= 0;
- }
-
- public void calculateEstimates(long originalEstimateTime) {
- setMinEstimate(originalEstimateTime + (getMinutes() * 60 * 1000)
- - (30000));
- setMaxEstimate(getMinEstimate() + 60000);
- }
-
- public void mergeEstimate(Departure departure) {
- if (departure.hasDeparted() && origin.longStationLinger
- && getMinEstimate() > 0 && !beganAsDeparted) {
- /*
- * This is probably not a true departure, but an indication that the
- * train is in the station. Don't update the estimates.
- */
- return;
- }
-
- boolean wasDeparted = hasDeparted();
- if (!hasAnyArrivalEstimate() && departure.hasAnyArrivalEstimate()) {
- setArrivalTimeOverride(departure.getArrivalTimeOverride());
- setEstimatedTripTime(departure.getEstimatedTripTime());
- }
-
- long newMin = Math.max(getMinEstimate(), departure.getMinEstimate());
- long newMax = Math.min(getMaxEstimate(), departure.getMaxEstimate());
-
- if ((getMaxEstimate() - departure.getMinEstimate()) < MINIMUM_MERGE_OVERLAP_MILLIS
- || departure.getMaxEstimate() - getMinEstimate() < MINIMUM_MERGE_OVERLAP_MILLIS) {
- /*
- * The estimate must have changed... just use the latest incoming
- * values
- */
- newMin = departure.getMinEstimate();
- newMax = departure.getMaxEstimate();
- }
-
- /*
- * If the new departure would mark this as departed, and we have < 60
- * seconds left on a fairly accurate local estimate, ignore the incoming
- * departure
- */
- if (!wasDeparted && getMeanSecondsLeft(newMin, newMax) <= 0
- && getMeanSecondsLeft() < 60 && getUncertaintySeconds() < 30) {
- Log.d(Constants.TAG,
- "Skipping estimate merge, since it would make this departure show as 'departed' prematurely");
- return;
- }
-
- if (newMax > newMin) {
- // We must never have 0 or negative uncertainty
- setMinEstimate(newMin);
- setMaxEstimate(newMax);
- }
- }
-
- public boolean hasExpired() {
- final long now = System.currentTimeMillis();
- return getMaxEstimate() < now
- && getEstimatedArrivalTime() + EXPIRE_MINUTES_AFTER_ARRIVAL
- * 60000 < now;
- }
-
- public int compareTo(Departure another) {
- return (this.getMeanSecondsLeft() > another.getMeanSecondsLeft()) ? 1
- : ((this.getMeanSecondsLeft() == another.getMeanSecondsLeft()) ? 0
- : -1);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (bikeAllowed ? 1231 : 1237);
- result = prime
- * result
- + ((trainDestination == null) ? 0 : trainDestination.hashCode());
- result = prime
- * result
- + ((destinationColor == null) ? 0 : destinationColor.hashCode());
- result = prime * result
- + ((direction == null) ? 0 : direction.hashCode());
- result = prime * result + ((line == null) ? 0 : line.hashCode());
- result = prime * result + (int) (maxEstimate ^ (maxEstimate >>> 32));
- result = prime * result + (int) (minEstimate ^ (minEstimate >>> 32));
- result = prime * result + minutes;
- result = prime * result
- + ((platform == null) ? 0 : platform.hashCode());
- result = prime * result + (requiresTransfer ? 1231 : 1237);
- result = prime * result
- + ((trainLength == null) ? 0 : trainLength.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Departure other = (Departure) obj;
- if (bikeAllowed != other.bikeAllowed)
- return false;
- if (trainDestination != other.trainDestination)
- return false;
- if (destinationColor == null) {
- if (other.destinationColor != null)
- return false;
- } else if (!destinationColor.equals(other.destinationColor))
- return false;
- if (direction == null) {
- if (other.direction != null)
- return false;
- } else if (!direction.equals(other.direction))
- return false;
- if (line != other.line)
- return false;
- if (Math.abs(maxEstimate - other.maxEstimate) > getEqualsTolerance())
- return false;
- if (platform == null) {
- if (other.platform != null)
- return false;
- } else if (!platform.equals(other.platform))
- return false;
- if (requiresTransfer != other.requiresTransfer)
- return false;
- if (trainLength == null) {
- if (other.trainLength != null)
- return false;
- } else if (!trainLength.equals(other.trainLength))
- return false;
- return true;
- }
-
- private int getEqualsTolerance() {
- if (origin != null) {
- return origin.departureEqualityTolerance;
- } else {
- return Station.DEFAULT_DEPARTURE_EQUALITY_TOLERANCE;
- }
- }
-
- public String getCountdownText() {
- StringBuilder builder = new StringBuilder();
- int secondsLeft = getMeanSecondsLeft();
- if (hasDeparted()) {
- if (origin != null && origin.longStationLinger && beganAsDeparted) {
- builder.append("At station");
- } else {
- builder.append("Departed");
- }
- } else {
- builder.append(secondsLeft / 60);
- builder.append("m, ");
- builder.append(secondsLeft % 60);
- builder.append("s");
- }
- return builder.toString();
- }
-
- public String getUncertaintyText() {
- if (hasDeparted()) {
- return "";
- } else {
- return "(±" + getUncertaintySeconds() + "s)";
- }
- }
-
- public int getAlarmLeadTimeMinutes() {
- return alarmLeadTimeMinutes.getValue();
- }
-
- public Observable getAlarmLeadTimeMinutesObservable() {
- return alarmLeadTimeMinutes;
- }
-
- public boolean isAlarmPending() {
- return alarmPending.getValue();
- }
-
- public Observable getAlarmPendingObservable() {
- return alarmPending;
- }
-
- private PendingIntent getAlarmIntent(Context context) {
- return PendingIntent.getBroadcast(context, 0, new Intent(
- Constants.ACTION_ALARM, getStationPair().getUri()),
- PendingIntent.FLAG_UPDATE_CURRENT);
- }
-
- private long getAlarmClockTime() {
- return getMeanEstimate() - alarmLeadTimeMinutes.getValue() * 60 * 1000;
- }
-
- public int getSecondsUntilAlarm() {
- return getMeanSecondsLeft() - getAlarmLeadTimeMinutes() * 60;
- }
-
- public void setUpAlarm(int leadTimeMinutes) {
- this.alarmLeadTimeMinutes.setValue(leadTimeMinutes);
- this.alarmPending.setValue(true);
- }
-
- public void updateAlarm(Context context, AlarmManager alarmManager) {
- if (alarmManager == null)
- return;
-
- if (isAlarmPending() && getAlarmLeadTimeMinutes() > 0) {
- final PendingIntent alarmIntent = getAlarmIntent(context);
- alarmManager.cancel(alarmIntent);
-
- long alarmTime = getAlarmClockTime();
-
- alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, alarmIntent);
-
- if (Log.isLoggable(Constants.TAG, Log.VERBOSE))
- Log.v(Constants.TAG,
- "Scheduling alarm for "
- + DateFormatUtils.format(alarmTime, "h:mm:ss"));
- }
- }
-
- public void cancelAlarm(Context context, AlarmManager alarmManager) {
- alarmManager.cancel(getAlarmIntent(context));
- this.alarmPending.setValue(false);
- }
-
- private PendingIntent notificationIntent;
-
- private PendingIntent getNotificationIntent(Context context) {
- if (notificationIntent == null) {
- Intent targetIntent = new Intent(Intent.ACTION_VIEW,
- getStationPair().getUri());
- targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- notificationIntent = PendingIntent.getActivity(context, 0,
- targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- }
- return notificationIntent;
- }
-
- public Notification createNotification(Context context) {
- final int halfMinutes = (getMeanSecondsLeft() + 15) / 30;
- float minutes = halfMinutes / 2f;
- final String minutesText = (minutes < 1) ? "Less than one minute"
- : (String.format("~%.1f minute", minutes) + ((minutes != 1.0) ? "s"
- : ""));
-
- final Intent cancelAlarmIntent = new Intent(context,
- BoardedDepartureService.class);
- cancelAlarmIntent.putExtra("cancelNotifications", true);
- Builder notificationBuilder = new NotificationCompat.Builder(context)
- .setOngoing(true)
- .setSmallIcon(R.drawable.ic_stat_notification)
- .setContentTitle(
- getOrigin().shortName + " to "
- + getPassengerDestination().shortName)
- .setContentIntent(getNotificationIntent(context)).setWhen(0);
- if (android.os.Build.VERSION.SDK_INT >= 16) {
- notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
- .setContentText(minutesText + " until departure");
- if (isAlarmPending()) {
- notificationBuilder.addAction(
- R.drawable.ic_action_cancel_alarm,
- "Cancel alarm",
- PendingIntent.getService(context, 0, cancelAlarmIntent,
- PendingIntent.FLAG_UPDATE_CURRENT)).setSubText(
- "Alarm " + getAlarmLeadTimeMinutes()
- + " minutes before departure");
- }
- } else if (isAlarmPending()) {
- notificationBuilder.setContentText(minutesText
- + " to departure (alarm at " + getAlarmLeadTimeMinutes()
- + " min" + ((getAlarmLeadTimeMinutes() == 1) ? "" : "s")
- + ")");
- } else {
- notificationBuilder
- .setContentText(minutesText + " until departure");
- }
-
- return notificationBuilder.build();
- }
-
- @Override
- public String toString() {
- java.text.DateFormat format = SimpleDateFormat.getTimeInstance();
- StringBuilder builder = new StringBuilder();
- builder.append(trainDestination);
- if (requiresTransfer) {
- builder.append(" (w/ xfer)");
- }
- builder.append(", ");
- builder.append(getCountdownText());
- builder.append(", ");
- builder.append(format.format(new Date(getMeanEstimate())));
- return builder.toString();
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(origin.abbreviation);
- dest.writeString(trainDestination.abbreviation);
- dest.writeString(passengerDestination == null ? null
- : passengerDestination.abbreviation);
- dest.writeString(destinationColor);
- dest.writeString(platform);
- dest.writeString(direction);
- dest.writeByte((byte) (bikeAllowed ? 1 : 0));
- dest.writeString(trainLength);
- dest.writeByte((byte) (requiresTransfer ? 1 : 0));
- dest.writeInt(minutes);
- dest.writeLong(minEstimate);
- dest.writeLong(maxEstimate);
- dest.writeLong(arrivalTimeOverride);
- dest.writeInt(estimatedTripTime);
- dest.writeInt(line.ordinal());
- dest.writeByte(beganAsDeparted ? (byte) 1 : (byte) 0);
- dest.writeByte(bikeAllowed ? (byte) 1 : (byte) 0);
- dest.writeByte(requiresTransfer ? (byte) 1 : (byte) 0);
- dest.writeByte(transferScheduled ? (byte) 1 : (byte) 0);
- }
-
- private void readFromParcel(Parcel in) {
- origin = Station.getByAbbreviation(in.readString());
- trainDestination = Station.getByAbbreviation(in.readString());
- passengerDestination = Station.getByAbbreviation(in.readString());
- destinationColor = in.readString();
- platform = in.readString();
- direction = in.readString();
- bikeAllowed = in.readByte() != 0;
- trainLength = in.readString();
- requiresTransfer = in.readByte() != 0;
- minutes = in.readInt();
- minEstimate = in.readLong();
- maxEstimate = in.readLong();
- arrivalTimeOverride = in.readLong();
- estimatedTripTime = in.readInt();
- line = Line.values()[in.readInt()];
- beganAsDeparted = in.readByte() == (byte) 1;
- bikeAllowed = in.readByte() == (byte) 1;
- requiresTransfer = in.readByte() == (byte) 1;
- transferScheduled = in.readByte() == (byte) 1;
- }
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public Departure createFromParcel(Parcel in) {
- return new Departure(in);
- }
-
- public Departure[] newArray(int size) {
- return new Departure[size];
- }
- };
-
- public void notifyAlarmHasBeenHandled() {
- this.alarmPending.setValue(false);
- }
+package com.dougkeen.bart.model;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationCompat.Builder;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import com.dougkeen.bart.BartRunnerApplication;
+import com.dougkeen.bart.R;
+import com.dougkeen.bart.services.BoardedDepartureService;
+import com.dougkeen.util.Observable;
+
+public class Departure implements Parcelable, Comparable {
+ private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 5000;
+ private static final int EXPIRE_MINUTES_AFTER_ARRIVAL = 1;
+
+ public Departure() {
+ super();
+ }
+
+ public Departure(String destinationAbbr, String destinationColor,
+ String platform, String direction, boolean bikeAllowed,
+ String trainLength, int minutes) {
+ super();
+ this.trainDestination = Station.getByAbbreviation(destinationAbbr);
+ this.destinationColor = destinationColor;
+ this.platform = platform;
+ this.direction = direction;
+ this.bikeAllowed = bikeAllowed;
+ this.trainLength = trainLength;
+ this.minutes = minutes;
+ }
+
+ public Departure(Parcel in) {
+ readFromParcel(in);
+ }
+
+ private Station origin;
+ private Station trainDestination;
+ private Station passengerDestination;
+ private Line line;
+ private String destinationColor;
+ private String platform;
+ private String direction;
+ private boolean bikeAllowed;
+ private String trainLength;
+ private boolean requiresTransfer;
+ private boolean transferScheduled;
+
+ private int minutes;
+
+ private long minEstimate;
+ private long maxEstimate;
+
+ private int estimatedTripTime;
+
+ private boolean beganAsDeparted;
+
+ private long arrivalTimeOverride;
+
+ private Observable alarmLeadTimeMinutes = new Observable(
+ 0);
+ private Observable alarmPending = new Observable(false);
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Station origin) {
+ this.origin = origin;
+ }
+
+ public Station getTrainDestination() {
+ return trainDestination;
+ }
+
+ public void setTrainDestination(Station destination) {
+ this.trainDestination = destination;
+ }
+
+ public String getTrainDestinationName() {
+ if (trainDestination != null)
+ return trainDestination.name;
+ return null;
+ }
+
+ public String getTrainDestinationAbbreviation() {
+ if (trainDestination != null)
+ return trainDestination.abbreviation;
+ return null;
+ }
+
+ public Station getPassengerDestination() {
+ return passengerDestination;
+ }
+
+ public void setPassengerDestination(Station passengerDestination) {
+ this.passengerDestination = passengerDestination;
+ }
+
+ public StationPair getStationPair() {
+ if (passengerDestination != null) {
+ return new StationPair(origin, passengerDestination);
+ } else {
+ return null;
+ }
+ }
+
+ public Line getLine() {
+ return line;
+ }
+
+ public void setLine(Line line) {
+ this.line = line;
+ }
+
+ public String getTrainDestinationColor() {
+ return destinationColor;
+ }
+
+ public void setTrainDestinationColor(String destinationColor) {
+ this.destinationColor = destinationColor;
+ }
+
+ public String getPlatform() {
+ return platform;
+ }
+
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+
+ public String getDirection() {
+ return direction;
+ }
+
+ public void setDirection(String direction) {
+ this.direction = direction;
+ }
+
+ public boolean isBikeAllowed() {
+ return bikeAllowed;
+ }
+
+ public void setBikeAllowed(boolean bikeAllowed) {
+ this.bikeAllowed = bikeAllowed;
+ }
+
+ public String getTrainLength() {
+ return trainLength;
+ }
+
+ public void setTrainLength(String trainLength) {
+ this.trainLength = trainLength;
+ }
+
+ public String getTrainLengthText() {
+ return trainLength + " car train";
+ }
+
+ public boolean getRequiresTransfer() {
+ return requiresTransfer;
+ }
+
+ public void setRequiresTransfer(boolean requiresTransfer) {
+ this.requiresTransfer = requiresTransfer;
+ }
+
+ public boolean isTransferScheduled() {
+ return transferScheduled;
+ }
+
+ public void setTransferScheduled(boolean transferScheduled) {
+ this.transferScheduled = transferScheduled;
+ }
+
+ public int getMinutes() {
+ return minutes;
+ }
+
+ public void setMinutes(int minutes) {
+ this.minutes = minutes;
+ if (minutes == 0) {
+ beganAsDeparted = true;
+ }
+ }
+
+ public long getMinEstimate() {
+ return minEstimate;
+ }
+
+ public void setMinEstimate(long minEstimate) {
+ this.minEstimate = minEstimate;
+ }
+
+ public long getMaxEstimate() {
+ return maxEstimate;
+ }
+
+ public void setMaxEstimate(long maxEstimate) {
+ this.maxEstimate = maxEstimate;
+ }
+
+ public int getEstimatedTripTime() {
+ return estimatedTripTime;
+ }
+
+ public void setEstimatedTripTime(int estimatedTripTime) {
+ this.estimatedTripTime = estimatedTripTime;
+ }
+
+ public boolean hasEstimatedTripTime() {
+ return this.estimatedTripTime > 0;
+ }
+
+ public boolean hasAnyArrivalEstimate() {
+ return this.estimatedTripTime > 0 || this.arrivalTimeOverride > 0;
+ }
+
+ public int getUncertaintySeconds() {
+ return (int) (maxEstimate - minEstimate + 1000) / 2000;
+ }
+
+ public int getMinSecondsLeft() {
+ return (int) ((getMinEstimate() - System.currentTimeMillis()) / 1000);
+ }
+
+ public int getMaxSecondsLeft() {
+ return (int) ((getMaxEstimate() - System.currentTimeMillis()) / 1000);
+ }
+
+ public int getMeanSecondsLeft() {
+ return (int) getMeanSecondsLeft(getMinEstimate(), getMaxEstimate());
+ }
+
+ public int getMeanSecondsLeft(long min, long max) {
+ return (int) ((getMeanEstimate(min, max) - System.currentTimeMillis()) / 1000);
+ }
+
+ public long getMeanEstimate() {
+ return getMeanEstimate(getMinEstimate(), getMaxEstimate());
+ }
+
+ public long getMeanEstimate(long min, long max) {
+ return (min + max) / 2;
+ }
+
+ public long getArrivalTimeOverride() {
+ return arrivalTimeOverride;
+ }
+
+ public void setArrivalTimeOverride(long arrivalTimeOverride) {
+ this.arrivalTimeOverride = arrivalTimeOverride;
+ }
+
+ public long getEstimatedArrivalTime() {
+ if (arrivalTimeOverride > 0) {
+ return arrivalTimeOverride;
+ }
+ return getMeanEstimate() + getEstimatedTripTime();
+ }
+
+ public long getEstimatedArrivalMinutesLeft() {
+ long millisLeft = getEstimatedArrivalTime()
+ - System.currentTimeMillis();
+ if (millisLeft < 0) {
+ return -1;
+ } else {
+ // Add ~30s to emulate rounding
+ return (millisLeft + 29999) / (60 * 1000);
+ }
+ }
+
+ public String getEstimatedArrivalMinutesLeftText(Context context) {
+ if (!hasAnyArrivalEstimate()) {
+ return "Estimated arrival unknown";
+ }
+ long minutesLeft = getEstimatedArrivalMinutesLeft();
+ if (minutesLeft < 0) {
+ return "Arrived at destination";
+ } else if (minutesLeft == 0) {
+ return "Arrives ~" + getEstimatedArrivalTimeText(context)
+ + " (<1 min)";
+ } else if (minutesLeft == 1) {
+ return "Arrives ~" + getEstimatedArrivalTimeText(context)
+ + " (1 min)";
+ } else {
+ return "Arrives ~" + getEstimatedArrivalTimeText(context) + " ("
+ + minutesLeft + " mins)";
+ }
+ }
+
+ public String getEstimatedArrivalTimeText(Context context) {
+ if (getEstimatedTripTime() > 0 || arrivalTimeOverride > 0) {
+ return DateFormat.getTimeFormat(context).format(
+ new Date(getEstimatedArrivalTime()));
+ } else {
+ return "";
+ }
+ }
+
+ public boolean hasDeparted() {
+ return getMeanSecondsLeft() <= 0;
+ }
+
+ public void calculateEstimates(long originalEstimateTime) {
+ setMinEstimate(originalEstimateTime + (getMinutes() * 60 * 1000)
+ - (30000));
+ setMaxEstimate(getMinEstimate() + 60000);
+ }
+
+ public void mergeEstimate(Departure departure) {
+ if (departure.hasDeparted() && origin.longStationLinger
+ && getMinEstimate() > 0 && !beganAsDeparted) {
+ /*
+ * This is probably not a true departure, but an indication that the
+ * train is in the station. Don't update the estimates.
+ */
+ return;
+ }
+
+ boolean wasDeparted = hasDeparted();
+ if (!hasAnyArrivalEstimate() && departure.hasAnyArrivalEstimate()) {
+ setArrivalTimeOverride(departure.getArrivalTimeOverride());
+ setEstimatedTripTime(departure.getEstimatedTripTime());
+ }
+
+ long newMin = Math.max(getMinEstimate(), departure.getMinEstimate());
+ long newMax = Math.min(getMaxEstimate(), departure.getMaxEstimate());
+
+ if ((getMaxEstimate() - departure.getMinEstimate()) < MINIMUM_MERGE_OVERLAP_MILLIS
+ || departure.getMaxEstimate() - getMinEstimate() < MINIMUM_MERGE_OVERLAP_MILLIS) {
+ /*
+ * The estimate must have changed... just use the latest incoming
+ * values
+ */
+ newMin = departure.getMinEstimate();
+ newMax = departure.getMaxEstimate();
+ }
+
+ /*
+ * If the new departure would mark this as departed, and we have < 60
+ * seconds left on a fairly accurate local estimate, ignore the incoming
+ * departure
+ */
+ if (!wasDeparted && getMeanSecondsLeft(newMin, newMax) <= 0
+ && getMeanSecondsLeft() < 60 && getUncertaintySeconds() < 30) {
+ Log.d(Constants.TAG,
+ "Skipping estimate merge, since it would make this departure show as 'departed' prematurely");
+ return;
+ }
+
+ if (newMax > newMin) {
+ // We must never have 0 or negative uncertainty
+ setMinEstimate(newMin);
+ setMaxEstimate(newMax);
+ }
+ }
+
+ public boolean hasExpired() {
+ final long now = System.currentTimeMillis();
+ return getMaxEstimate() < now
+ && getEstimatedArrivalTime() + EXPIRE_MINUTES_AFTER_ARRIVAL
+ * 60000 < now;
+ }
+
+ public int compareTo(Departure another) {
+ return (this.getMeanSecondsLeft() > another.getMeanSecondsLeft()) ? 1
+ : ((this.getMeanSecondsLeft() == another.getMeanSecondsLeft()) ? 0
+ : -1);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (bikeAllowed ? 1231 : 1237);
+ result = prime
+ * result
+ + ((trainDestination == null) ? 0 : trainDestination.hashCode());
+ result = prime
+ * result
+ + ((destinationColor == null) ? 0 : destinationColor.hashCode());
+ result = prime * result
+ + ((direction == null) ? 0 : direction.hashCode());
+ result = prime * result + ((line == null) ? 0 : line.hashCode());
+ result = prime * result + (int) (maxEstimate ^ (maxEstimate >>> 32));
+ result = prime * result + (int) (minEstimate ^ (minEstimate >>> 32));
+ result = prime * result + minutes;
+ result = prime * result
+ + ((platform == null) ? 0 : platform.hashCode());
+ result = prime * result + (requiresTransfer ? 1231 : 1237);
+ result = prime * result
+ + ((trainLength == null) ? 0 : trainLength.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Departure other = (Departure) obj;
+ if (bikeAllowed != other.bikeAllowed)
+ return false;
+ if (trainDestination != other.trainDestination)
+ return false;
+ if (destinationColor == null) {
+ if (other.destinationColor != null)
+ return false;
+ } else if (!destinationColor.equals(other.destinationColor))
+ return false;
+ if (direction == null) {
+ if (other.direction != null)
+ return false;
+ } else if (!direction.equals(other.direction))
+ return false;
+ if (line != other.line)
+ return false;
+ if (Math.abs(maxEstimate - other.maxEstimate) > getEqualsTolerance())
+ return false;
+ if (platform == null) {
+ if (other.platform != null)
+ return false;
+ } else if (!platform.equals(other.platform))
+ return false;
+ if (requiresTransfer != other.requiresTransfer)
+ return false;
+ if (trainLength == null) {
+ if (other.trainLength != null)
+ return false;
+ } else if (!trainLength.equals(other.trainLength))
+ return false;
+ return true;
+ }
+
+ private int getEqualsTolerance() {
+ if (origin != null) {
+ return origin.departureEqualityTolerance;
+ } else {
+ return Station.DEFAULT_DEPARTURE_EQUALITY_TOLERANCE;
+ }
+ }
+
+ public String getCountdownText() {
+ StringBuilder builder = new StringBuilder();
+ int secondsLeft = getMeanSecondsLeft();
+ if (hasDeparted()) {
+ if (origin != null && origin.longStationLinger && beganAsDeparted) {
+ builder.append("At station");
+ } else {
+ builder.append(BartRunnerApplication.getAppContext().getString(
+ R.string.leaving));
+ }
+ } else {
+ builder.append(secondsLeft / 60);
+ builder.append("m, ");
+ builder.append(secondsLeft % 60);
+ builder.append("s");
+ }
+ return builder.toString();
+ }
+
+ public String getUncertaintyText() {
+ if (hasDeparted()) {
+ return "";
+ } else {
+ return "(±" + getUncertaintySeconds() + "s)";
+ }
+ }
+
+ public int getAlarmLeadTimeMinutes() {
+ return alarmLeadTimeMinutes.getValue();
+ }
+
+ public Observable getAlarmLeadTimeMinutesObservable() {
+ return alarmLeadTimeMinutes;
+ }
+
+ public boolean isAlarmPending() {
+ return alarmPending.getValue();
+ }
+
+ public Observable getAlarmPendingObservable() {
+ return alarmPending;
+ }
+
+ private PendingIntent getAlarmIntent(Context context) {
+ return PendingIntent.getBroadcast(context, 0, new Intent(
+ Constants.ACTION_ALARM, getStationPair().getUri()),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ private long getAlarmClockTime() {
+ return getMeanEstimate() - alarmLeadTimeMinutes.getValue() * 60 * 1000;
+ }
+
+ public int getSecondsUntilAlarm() {
+ return getMeanSecondsLeft() - getAlarmLeadTimeMinutes() * 60;
+ }
+
+ public void setUpAlarm(int leadTimeMinutes) {
+ this.alarmLeadTimeMinutes.setValue(leadTimeMinutes);
+ this.alarmPending.setValue(true);
+ }
+
+ public void updateAlarm(Context context, AlarmManager alarmManager) {
+ if (alarmManager == null)
+ return;
+
+ if (isAlarmPending() && getAlarmLeadTimeMinutes() > 0) {
+ final PendingIntent alarmIntent = getAlarmIntent(context);
+ alarmManager.cancel(alarmIntent);
+
+ long alarmTime = getAlarmClockTime();
+
+ alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, alarmIntent);
+
+ if (Log.isLoggable(Constants.TAG, Log.VERBOSE))
+ Log.v(Constants.TAG,
+ "Scheduling alarm for "
+ + DateFormatUtils.format(alarmTime, "h:mm:ss"));
+ }
+ }
+
+ public void cancelAlarm(Context context, AlarmManager alarmManager) {
+ alarmManager.cancel(getAlarmIntent(context));
+ this.alarmPending.setValue(false);
+ }
+
+ private PendingIntent notificationIntent;
+
+ private PendingIntent getNotificationIntent(Context context) {
+ if (notificationIntent == null) {
+ Intent targetIntent = new Intent(Intent.ACTION_VIEW,
+ getStationPair().getUri());
+ targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ notificationIntent = PendingIntent.getActivity(context, 0,
+ targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+ return notificationIntent;
+ }
+
+ public Notification createNotification(Context context) {
+ final int halfMinutes = (getMeanSecondsLeft() + 15) / 30;
+ float minutes = halfMinutes / 2f;
+ final String minutesText = (minutes < 1) ? "Less than one minute"
+ : (String.format("~%.1f minute", minutes) + ((minutes != 1.0) ? "s"
+ : ""));
+
+ final Intent cancelAlarmIntent = new Intent(context,
+ BoardedDepartureService.class);
+ cancelAlarmIntent.putExtra("cancelNotifications", true);
+ Builder notificationBuilder = new NotificationCompat.Builder(context)
+ .setOngoing(true)
+ .setSmallIcon(R.drawable.ic_stat_notification)
+ .setContentTitle(
+ getOrigin().shortName + " to "
+ + getPassengerDestination().shortName)
+ .setContentIntent(getNotificationIntent(context)).setWhen(0);
+ if (android.os.Build.VERSION.SDK_INT >= 16) {
+ notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
+ .setContentText(minutesText + " until departure");
+ if (isAlarmPending()) {
+ notificationBuilder.addAction(
+ R.drawable.ic_action_cancel_alarm,
+ "Cancel alarm",
+ PendingIntent.getService(context, 0, cancelAlarmIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT)).setSubText(
+ "Alarm " + getAlarmLeadTimeMinutes()
+ + " minutes before departure");
+ }
+ } else if (isAlarmPending()) {
+ notificationBuilder.setContentText(minutesText
+ + " to departure (alarm at " + getAlarmLeadTimeMinutes()
+ + " min" + ((getAlarmLeadTimeMinutes() == 1) ? "" : "s")
+ + ")");
+ } else {
+ notificationBuilder
+ .setContentText(minutesText + " until departure");
+ }
+
+ return notificationBuilder.build();
+ }
+
+ @Override
+ public String toString() {
+ java.text.DateFormat format = SimpleDateFormat.getTimeInstance();
+ StringBuilder builder = new StringBuilder();
+ builder.append(trainDestination);
+ if (requiresTransfer) {
+ builder.append(" (w/ xfer)");
+ }
+ builder.append(", ");
+ builder.append(getCountdownText());
+ builder.append(", ");
+ builder.append(format.format(new Date(getMeanEstimate())));
+ return builder.toString();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(origin.abbreviation);
+ dest.writeString(trainDestination.abbreviation);
+ dest.writeString(passengerDestination == null ? null
+ : passengerDestination.abbreviation);
+ dest.writeString(destinationColor);
+ dest.writeString(platform);
+ dest.writeString(direction);
+ dest.writeByte((byte) (bikeAllowed ? 1 : 0));
+ dest.writeString(trainLength);
+ dest.writeByte((byte) (requiresTransfer ? 1 : 0));
+ dest.writeInt(minutes);
+ dest.writeLong(minEstimate);
+ dest.writeLong(maxEstimate);
+ dest.writeLong(arrivalTimeOverride);
+ dest.writeInt(estimatedTripTime);
+ dest.writeInt(line.ordinal());
+ dest.writeByte(beganAsDeparted ? (byte) 1 : (byte) 0);
+ dest.writeByte(bikeAllowed ? (byte) 1 : (byte) 0);
+ dest.writeByte(requiresTransfer ? (byte) 1 : (byte) 0);
+ dest.writeByte(transferScheduled ? (byte) 1 : (byte) 0);
+ }
+
+ private void readFromParcel(Parcel in) {
+ origin = Station.getByAbbreviation(in.readString());
+ trainDestination = Station.getByAbbreviation(in.readString());
+ passengerDestination = Station.getByAbbreviation(in.readString());
+ destinationColor = in.readString();
+ platform = in.readString();
+ direction = in.readString();
+ bikeAllowed = in.readByte() != 0;
+ trainLength = in.readString();
+ requiresTransfer = in.readByte() != 0;
+ minutes = in.readInt();
+ minEstimate = in.readLong();
+ maxEstimate = in.readLong();
+ arrivalTimeOverride = in.readLong();
+ estimatedTripTime = in.readInt();
+ line = Line.values()[in.readInt()];
+ beganAsDeparted = in.readByte() == (byte) 1;
+ bikeAllowed = in.readByte() == (byte) 1;
+ requiresTransfer = in.readByte() == (byte) 1;
+ transferScheduled = in.readByte() == (byte) 1;
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ public Departure createFromParcel(Parcel in) {
+ return new Departure(in);
+ }
+
+ public Departure[] newArray(int size) {
+ return new Departure[size];
+ }
+ };
+
+ public void notifyAlarmHasBeenHandled() {
+ this.alarmPending.setValue(false);
+ }
}
\ No newline at end of file
diff --git a/src/com/dougkeen/bart/model/Line.java b/src/com/dougkeen/bart/model/Line.java
index 1f9ae29..7bcd425 100644
--- a/src/com/dougkeen/bart/model/Line.java
+++ b/src/com/dougkeen/bart/model/Line.java
@@ -1,113 +1,115 @@
-package com.dougkeen.bart.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-public enum Line {
- RED(false, Station.MLBR, Station.SBRN, Station.SSAN, Station.COLM,
- Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
- Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
- Station.EMBR, Station.WOAK, Station._12TH, Station._19TH,
- Station.MCAR, Station.ASHB, Station.DBRK, Station.NBRK,
- Station.PLZA, Station.DELN, Station.RICH),
- ORANGE(false, Station.FRMT, Station.UCTY, Station.SHAY, Station.HAYW,
- Station.BAYF, Station.SANL, Station.COLS, Station.FTVL,
- Station.LAKE, Station._12TH, Station._19TH, Station.MCAR,
- Station.ASHB, Station.DBRK, Station.NBRK, Station.PLZA,
- Station.DELN, Station.RICH),
- YELLOW(false, Station.MLBR, Station.SFIA, Station.SBRN, Station.SSAN,
- Station.COLM, Station.DALY, Station.BALB, Station.GLEN,
- Station._24TH, Station._16TH, Station.CIVC, Station.POWL,
- Station.MONT, Station.EMBR, Station.WOAK, Station._12TH,
- Station._19TH, Station.MCAR, Station.ROCK, Station.ORIN,
- Station.LAFY, Station.WCRK, Station.PHIL, Station.CONC,
- Station.NCON, Station.PITT),
- BLUE(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
- Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
- Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
- Station.COLS, Station.SANL, Station.BAYF, Station.CAST,
- Station.WDUB, Station.DUBL),
- GREEN(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
- Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
- Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
- Station.COLS, Station.SANL, Station.BAYF, Station.HAYW,
- Station.SHAY, Station.UCTY, Station.FRMT),
- YELLOW_ORANGE_SCHEDULED_TRANSFER(YELLOW, ORANGE, Station.MLBR,
- Station.SFIA, Station.SBRN, Station.SSAN, Station.COLM,
- Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
- Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
- Station.EMBR, Station.WOAK, Station.ASHB, Station.DBRK,
- Station.NBRK, Station.PLZA, Station.DELN, Station.RICH);
-
- public final List stations;
-
- protected final boolean directionMayInvert;
-
- protected final boolean requiresTransfer;
-
- protected final Line transferLine1;
-
- protected final Line transferLine2;
-
- private Line(boolean directionMayInvert, Station... stationArray) {
- this.requiresTransfer = false;
- this.directionMayInvert = directionMayInvert;
- stations = Arrays.asList(stationArray);
- this.transferLine1 = null;
- this.transferLine2 = null;
- }
-
- private Line(Line transferLine1, Line transferLine2,
- Station... stationArray) {
- this.requiresTransfer = true;
- this.directionMayInvert = false;
- stations = Arrays.asList(stationArray);
- this.transferLine1 = transferLine1;
- this.transferLine2 = transferLine2;
- }
-
- private Line(boolean directionMayInvert, Line transferLine1,
- Line transferLine2, Station... stationArray) {
- this.requiresTransfer = true;
- this.directionMayInvert = directionMayInvert;
- stations = Arrays.asList(stationArray);
- this.transferLine1 = transferLine1;
- this.transferLine2 = transferLine2;
- }
-
- public static Collection getLinesForStation(Station station) {
- Collection lines = new ArrayList();
- for (Line line : Line.values()) {
- if (line.stations.contains(station)) {
- lines.add(line);
- }
- }
- return lines;
- }
-
- public static Collection getLinesWithStations(Station station1, Station station2) {
- Collection lines = new ArrayList();
- for (Line line : Line.values()) {
- if (line.stations.contains(station1) && line.stations.contains(station2)) {
- lines.add(line);
- }
- }
- return lines;
- }
-
- public static Set getPotentialDestinations(Station station) {
- Set destinations = new TreeSet();
-
- for (Line line : getLinesForStation(station)) {
- destinations.addAll(line.stations);
- }
-
- destinations.remove(station);
-
- return destinations;
- }
-}
+package com.dougkeen.bart.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public enum Line {
+ RED(false, Station.MLBR, Station.SBRN, Station.SSAN, Station.COLM,
+ Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
+ Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
+ Station.EMBR, Station.WOAK, Station._12TH, Station._19TH,
+ Station.MCAR, Station.ASHB, Station.DBRK, Station.NBRK,
+ Station.PLZA, Station.DELN, Station.RICH),
+ ORANGE(false, Station.FRMT, Station.UCTY, Station.SHAY, Station.HAYW,
+ Station.BAYF, Station.SANL, Station.COLS, Station.FTVL,
+ Station.LAKE, Station._12TH, Station._19TH, Station.MCAR,
+ Station.ASHB, Station.DBRK, Station.NBRK, Station.PLZA,
+ Station.DELN, Station.RICH),
+ YELLOW(false, Station.MLBR, Station.SFIA, Station.SBRN, Station.SSAN,
+ Station.COLM, Station.DALY, Station.BALB, Station.GLEN,
+ Station._24TH, Station._16TH, Station.CIVC, Station.POWL,
+ Station.MONT, Station.EMBR, Station.WOAK, Station._12TH,
+ Station._19TH, Station.MCAR, Station.ROCK, Station.ORIN,
+ Station.LAFY, Station.WCRK, Station.PHIL, Station.CONC,
+ Station.NCON, Station.PITT),
+ BLUE(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
+ Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
+ Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
+ Station.COLS, Station.SANL, Station.BAYF, Station.CAST,
+ Station.WDUB, Station.DUBL),
+ GREEN(true, Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
+ Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
+ Station.EMBR, Station.WOAK, Station.LAKE, Station.FTVL,
+ Station.COLS, Station.SANL, Station.BAYF, Station.HAYW,
+ Station.SHAY, Station.UCTY, Station.FRMT),
+ YELLOW_ORANGE_SCHEDULED_TRANSFER(YELLOW, ORANGE, Station.MLBR,
+ Station.SFIA, Station.SBRN, Station.SSAN, Station.COLM,
+ Station.DALY, Station.BALB, Station.GLEN, Station._24TH,
+ Station._16TH, Station.CIVC, Station.POWL, Station.MONT,
+ Station.EMBR, Station.WOAK, Station.ASHB, Station.DBRK,
+ Station.NBRK, Station.PLZA, Station.DELN, Station.RICH);
+
+ public final List stations;
+
+ protected final boolean directionMayInvert;
+
+ protected final boolean requiresTransfer;
+
+ protected final Line transferLine1;
+
+ protected final Line transferLine2;
+
+ private Line(boolean directionMayInvert, Station... stationArray) {
+ this.requiresTransfer = false;
+ this.directionMayInvert = directionMayInvert;
+ stations = Arrays.asList(stationArray);
+ this.transferLine1 = null;
+ this.transferLine2 = null;
+ }
+
+ private Line(Line transferLine1, Line transferLine2,
+ Station... stationArray) {
+ this.requiresTransfer = true;
+ this.directionMayInvert = false;
+ stations = Arrays.asList(stationArray);
+ this.transferLine1 = transferLine1;
+ this.transferLine2 = transferLine2;
+ }
+
+ private Line(boolean directionMayInvert, Line transferLine1,
+ Line transferLine2, Station... stationArray) {
+ this.requiresTransfer = true;
+ this.directionMayInvert = directionMayInvert;
+ stations = Arrays.asList(stationArray);
+ this.transferLine1 = transferLine1;
+ this.transferLine2 = transferLine2;
+ }
+
+ public static Collection getLinesForStation(Station station) {
+ Collection lines = new ArrayList();
+ for (Line line : Line.values()) {
+ if (line.stations.contains(station)) {
+ lines.add(line);
+ }
+ }
+ return lines;
+ }
+
+ public static Collection getLinesWithStations(Station station1,
+ Station station2) {
+ Collection lines = new ArrayList();
+ for (Line line : Line.values()) {
+ if (line.stations.contains(station1)
+ && line.stations.contains(station2)) {
+ lines.add(line);
+ }
+ }
+ return lines;
+ }
+
+ public static Set getPotentialDestinations(Station station) {
+ Set destinations = new TreeSet();
+
+ for (Line line : getLinesForStation(station)) {
+ destinations.addAll(line.stations);
+ }
+
+ destinations.remove(station);
+
+ return destinations;
+ }
+}
diff --git a/src/com/dougkeen/bart/model/RealTimeDepartures.java b/src/com/dougkeen/bart/model/RealTimeDepartures.java
index 9513dbf..363095c 100644
--- a/src/com/dougkeen/bart/model/RealTimeDepartures.java
+++ b/src/com/dougkeen/bart/model/RealTimeDepartures.java
@@ -1,152 +1,152 @@
-package com.dougkeen.bart.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-public class RealTimeDepartures {
- public RealTimeDepartures(Station origin, Station destination,
- List routes) {
- this.origin = origin;
- this.destination = destination;
- this.routes = routes;
- this.unfilteredDepartures = new ArrayList();
- }
-
- private Station origin;
- private Station destination;
- private long time;
-
- private List departures;
-
- final private List unfilteredDepartures;
-
- private List routes;
-
- public Station getOrigin() {
- return origin;
- }
-
- public void setOrigin(Station origin) {
- this.origin = origin;
- }
-
- public Station getDestination() {
- return destination;
- }
-
- public void setDestination(Station destination) {
- this.destination = destination;
- }
-
- public long getTime() {
- return time;
- }
-
- public void setTime(long time) {
- this.time = time;
- }
-
- public List getDepartures() {
- if (departures == null) {
- departures = new ArrayList();
- }
- return departures;
- }
-
- public void setDepartures(List departures) {
- this.departures = departures;
- }
-
- public void includeTransferRoutes() {
- routes.addAll(origin.getTransferRoutes(destination));
- rebuildFilteredDepaturesCollection();
- }
-
- public void includeDoubleTransferRoutes() {
- routes.addAll(origin.getDoubleTransferRoutes(destination));
- rebuildFilteredDepaturesCollection();
- }
-
- private void rebuildFilteredDepaturesCollection() {
- getDepartures().clear();
- for (Departure departure : unfilteredDepartures) {
- addDepartureIfApplicable(departure);
- }
- }
-
- public void addDeparture(Departure departure) {
- unfilteredDepartures.add(departure);
- addDepartureIfApplicable(departure);
- }
-
- private void addDepartureIfApplicable(Departure departure) {
- Station destination = Station.getByAbbreviation(departure
- .getTrainDestinationAbbreviation());
- if (departure.getLine() == null)
- return;
- for (Route route : routes) {
- if (route.trainDestinationIsApplicable(destination,
- departure.getLine())) {
- departure.setRequiresTransfer(route.hasTransfer());
- departure
- .setTransferScheduled(Line.YELLOW_ORANGE_SCHEDULED_TRANSFER
- .equals(route.getDirectLine()));
- getDepartures().add(departure);
- departure.calculateEstimates(time);
- return;
- }
- }
- }
-
- public void sortDepartures() {
- Collections.sort(getDepartures());
- }
-
- public void finalizeDeparturesList() {
- boolean hasDirectRoute = false;
- for (Departure departure : getDepartures()) {
- if (!departure.getRequiresTransfer()) {
- hasDirectRoute = true;
- break;
- }
- }
- if (hasDirectRoute) {
- Iterator iterator = getDepartures().iterator();
- while (iterator.hasNext()) {
- Departure departure = iterator.next();
- if (departure.getRequiresTransfer()
- && (!departure.isTransferScheduled() || departure
- .getTrainDestination().isBetween(getOrigin(),
- getDestination(), departure.getLine()))) {
- iterator.remove();
- }
- }
- }
- sortDepartures();
- }
-
- public List getRoutes() {
- return routes;
- }
-
- public void setRoutes(List routes) {
- this.routes = routes;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("RealTimeDepartures [origin=");
- builder.append(origin);
- builder.append(", destination=");
- builder.append(destination);
- builder.append(", time=");
- builder.append(time);
- builder.append(", departures=");
- builder.append(departures);
- builder.append("]");
- return builder.toString();
- }
-}
+package com.dougkeen.bart.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class RealTimeDepartures {
+ public RealTimeDepartures(Station origin, Station destination,
+ List routes) {
+ this.origin = origin;
+ this.destination = destination;
+ this.routes = routes;
+ this.unfilteredDepartures = new ArrayList();
+ }
+
+ private Station origin;
+ private Station destination;
+ private long time;
+
+ private List departures;
+
+ final private List unfilteredDepartures;
+
+ private List routes;
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Station origin) {
+ this.origin = origin;
+ }
+
+ public Station getDestination() {
+ return destination;
+ }
+
+ public void setDestination(Station destination) {
+ this.destination = destination;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public List getDepartures() {
+ if (departures == null) {
+ departures = new ArrayList();
+ }
+ return departures;
+ }
+
+ public void setDepartures(List departures) {
+ this.departures = departures;
+ }
+
+ public void includeTransferRoutes() {
+ routes.addAll(origin.getTransferRoutes(destination));
+ rebuildFilteredDepaturesCollection();
+ }
+
+ public void includeDoubleTransferRoutes() {
+ routes.addAll(origin.getDoubleTransferRoutes(destination));
+ rebuildFilteredDepaturesCollection();
+ }
+
+ private void rebuildFilteredDepaturesCollection() {
+ getDepartures().clear();
+ for (Departure departure : unfilteredDepartures) {
+ addDepartureIfApplicable(departure);
+ }
+ }
+
+ public void addDeparture(Departure departure) {
+ unfilteredDepartures.add(departure);
+ addDepartureIfApplicable(departure);
+ }
+
+ private void addDepartureIfApplicable(Departure departure) {
+ Station destination = Station.getByAbbreviation(departure
+ .getTrainDestinationAbbreviation());
+ if (departure.getLine() == null)
+ return;
+ for (Route route : routes) {
+ if (route.trainDestinationIsApplicable(destination,
+ departure.getLine())) {
+ departure.setRequiresTransfer(route.hasTransfer());
+ departure
+ .setTransferScheduled(Line.YELLOW_ORANGE_SCHEDULED_TRANSFER
+ .equals(route.getDirectLine()));
+ getDepartures().add(departure);
+ departure.calculateEstimates(time);
+ return;
+ }
+ }
+ }
+
+ public void sortDepartures() {
+ Collections.sort(getDepartures());
+ }
+
+ public void finalizeDeparturesList() {
+ boolean hasDirectRoute = false;
+ for (Departure departure : getDepartures()) {
+ if (!departure.getRequiresTransfer()) {
+ hasDirectRoute = true;
+ break;
+ }
+ }
+ if (hasDirectRoute) {
+ Iterator iterator = getDepartures().iterator();
+ while (iterator.hasNext()) {
+ Departure departure = iterator.next();
+ if (departure.getRequiresTransfer()
+ && (!departure.isTransferScheduled() || departure
+ .getTrainDestination().isBetween(getOrigin(),
+ getDestination(), departure.getLine()))) {
+ iterator.remove();
+ }
+ }
+ }
+ sortDepartures();
+ }
+
+ public List getRoutes() {
+ return routes;
+ }
+
+ public void setRoutes(List routes) {
+ this.routes = routes;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("RealTimeDepartures [origin=");
+ builder.append(origin);
+ builder.append(", destination=");
+ builder.append(destination);
+ builder.append(", time=");
+ builder.append(time);
+ builder.append(", departures=");
+ builder.append(departures);
+ builder.append("]");
+ return builder.toString();
+ }
+}
diff --git a/src/com/dougkeen/bart/model/Route.java b/src/com/dougkeen/bart/model/Route.java
index 020557c..3b0e3f6 100644
--- a/src/com/dougkeen/bart/model/Route.java
+++ b/src/com/dougkeen/bart/model/Route.java
@@ -1,111 +1,111 @@
-package com.dougkeen.bart.model;
-
-import java.util.Collection;
-
-public class Route {
- private Station origin;
- private Station destination;
- private Line directLine;
- private Collection transferLines;
- private boolean requiresTransfer;
- private Station transferStation;
- private String direction;
-
- public Station getOrigin() {
- return origin;
- }
-
- public void setOrigin(Station origin) {
- this.origin = origin;
- }
-
- public Station getDestination() {
- return destination;
- }
-
- public void setDestination(Station destination) {
- this.destination = destination;
- }
-
- public Line getDirectLine() {
- return directLine;
- }
-
- public void setDirectLine(Line line) {
- this.directLine = line;
- }
-
- public Collection getTransferLines() {
- return transferLines;
- }
-
- public void setTransferLines(Collection transferLines) {
- this.transferLines = transferLines;
- }
-
- public boolean hasTransfer() {
- return requiresTransfer;
- }
-
- public void setTransfer(boolean requiresTransfer) {
- this.requiresTransfer = requiresTransfer;
- }
-
- public Station getTransferStation() {
- return transferStation;
- }
-
- public void setTransferStation(Station transferStation) {
- this.transferStation = transferStation;
- }
-
- public String getDirection() {
- return direction;
- }
-
- public void setDirection(String direction) {
- this.direction = direction;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Route [origin=");
- builder.append(origin);
- builder.append(", destination=");
- builder.append(destination);
- builder.append(", line=");
- builder.append(directLine);
- builder.append(", requiresTransfer=");
- builder.append(requiresTransfer);
- builder.append(", transferStation=");
- builder.append(transferStation);
- builder.append(", direction=");
- builder.append(direction);
- builder.append("]");
- return builder.toString();
- }
-
- public boolean trainDestinationIsApplicable(Station lineDestination,
- Line viaLine) {
- Line routeLine = getDirectLine();
- if (routeLine.transferLine1 != null
- && viaLine.equals(routeLine.transferLine1)) {
- return true;
- } else if (routeLine.transferLine2 != null
- && viaLine.equals(routeLine.transferLine2)) {
- return true;
- } else if (requiresTransfer && transferLines != null
- && !transferLines.isEmpty()) {
- return transferLines.contains(viaLine);
- } else {
- int originIndex = viaLine.stations.indexOf(origin);
- int routeDestinationIndex = viaLine.stations.indexOf(destination);
- int lineDestinationIndex = viaLine.stations
- .indexOf(lineDestination);
- return routeDestinationIndex >= 0
- && ((originIndex <= routeDestinationIndex && routeDestinationIndex <= lineDestinationIndex) || (originIndex >= routeDestinationIndex && routeDestinationIndex >= lineDestinationIndex));
- }
- }
-
-}
+package com.dougkeen.bart.model;
+
+import java.util.Collection;
+
+public class Route {
+ private Station origin;
+ private Station destination;
+ private Line directLine;
+ private Collection transferLines;
+ private boolean requiresTransfer;
+ private Station transferStation;
+ private String direction;
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Station origin) {
+ this.origin = origin;
+ }
+
+ public Station getDestination() {
+ return destination;
+ }
+
+ public void setDestination(Station destination) {
+ this.destination = destination;
+ }
+
+ public Line getDirectLine() {
+ return directLine;
+ }
+
+ public void setDirectLine(Line line) {
+ this.directLine = line;
+ }
+
+ public Collection getTransferLines() {
+ return transferLines;
+ }
+
+ public void setTransferLines(Collection transferLines) {
+ this.transferLines = transferLines;
+ }
+
+ public boolean hasTransfer() {
+ return requiresTransfer;
+ }
+
+ public void setTransfer(boolean requiresTransfer) {
+ this.requiresTransfer = requiresTransfer;
+ }
+
+ public Station getTransferStation() {
+ return transferStation;
+ }
+
+ public void setTransferStation(Station transferStation) {
+ this.transferStation = transferStation;
+ }
+
+ public String getDirection() {
+ return direction;
+ }
+
+ public void setDirection(String direction) {
+ this.direction = direction;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Route [origin=");
+ builder.append(origin);
+ builder.append(", destination=");
+ builder.append(destination);
+ builder.append(", line=");
+ builder.append(directLine);
+ builder.append(", requiresTransfer=");
+ builder.append(requiresTransfer);
+ builder.append(", transferStation=");
+ builder.append(transferStation);
+ builder.append(", direction=");
+ builder.append(direction);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ public boolean trainDestinationIsApplicable(Station lineDestination,
+ Line viaLine) {
+ Line routeLine = getDirectLine();
+ if (routeLine.transferLine1 != null
+ && viaLine.equals(routeLine.transferLine1)) {
+ return true;
+ } else if (routeLine.transferLine2 != null
+ && viaLine.equals(routeLine.transferLine2)) {
+ return true;
+ } else if (requiresTransfer && transferLines != null
+ && !transferLines.isEmpty()) {
+ return transferLines.contains(viaLine);
+ } else {
+ int originIndex = viaLine.stations.indexOf(origin);
+ int routeDestinationIndex = viaLine.stations.indexOf(destination);
+ int lineDestinationIndex = viaLine.stations
+ .indexOf(lineDestination);
+ return routeDestinationIndex >= 0
+ && ((originIndex <= routeDestinationIndex && routeDestinationIndex <= lineDestinationIndex) || (originIndex >= routeDestinationIndex && routeDestinationIndex >= lineDestinationIndex));
+ }
+ }
+
+}
diff --git a/src/com/dougkeen/bart/model/ScheduleInformation.java b/src/com/dougkeen/bart/model/ScheduleInformation.java
index 6bede36..5fb3b91 100644
--- a/src/com/dougkeen/bart/model/ScheduleInformation.java
+++ b/src/com/dougkeen/bart/model/ScheduleInformation.java
@@ -1,89 +1,89 @@
-package com.dougkeen.bart.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ScheduleInformation {
-
- public ScheduleInformation(Station origin, Station destination) {
- super();
- this.origin = origin;
- this.destination = destination;
- }
-
- private Station origin;
- private Station destination;
- private long date;
- private List trips;
-
- public Station getOrigin() {
- return origin;
- }
-
- public void setOrigin(Station origin) {
- this.origin = origin;
- }
-
- public Station getDestination() {
- return destination;
- }
-
- public void setDestination(Station destination) {
- this.destination = destination;
- }
-
- public long getDate() {
- return date;
- }
-
- public void setDate(long date) {
- this.date = date;
- }
-
- public List getTrips() {
- if (trips == null) {
- trips = new ArrayList();
- }
- return trips;
- }
-
- public void setTrips(List trips) {
- this.trips = trips;
- }
-
- public void addTrip(ScheduleItem trip) {
- getTrips().add(trip);
- }
-
- public long getLatestDepartureTime() {
- if (getTrips().isEmpty())
- return -1;
- else
- return getTrips().get(getTrips().size() - 1).getDepartureTime();
- }
-
- private int aveTripLength = -1;
- private int tripCount = 0;
-
- public int getAverageTripLength() {
- if (aveTripLength < 0) {
- int sum = 0;
- for (ScheduleItem trip : getTrips()) {
- int tripLength = trip.getTripLength();
- if (tripLength > 0) {
- sum += tripLength;
- tripCount++;
- }
- }
- if (tripCount > 0) {
- aveTripLength = sum / tripCount;
- }
- }
- return aveTripLength;
- }
-
- public int getTripCountForAverage() {
- getAverageTripLength();
- return tripCount;
- }
+package com.dougkeen.bart.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScheduleInformation {
+
+ public ScheduleInformation(Station origin, Station destination) {
+ super();
+ this.origin = origin;
+ this.destination = destination;
+ }
+
+ private Station origin;
+ private Station destination;
+ private long date;
+ private List trips;
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Station origin) {
+ this.origin = origin;
+ }
+
+ public Station getDestination() {
+ return destination;
+ }
+
+ public void setDestination(Station destination) {
+ this.destination = destination;
+ }
+
+ public long getDate() {
+ return date;
+ }
+
+ public void setDate(long date) {
+ this.date = date;
+ }
+
+ public List getTrips() {
+ if (trips == null) {
+ trips = new ArrayList();
+ }
+ return trips;
+ }
+
+ public void setTrips(List trips) {
+ this.trips = trips;
+ }
+
+ public void addTrip(ScheduleItem trip) {
+ getTrips().add(trip);
+ }
+
+ public long getLatestDepartureTime() {
+ if (getTrips().isEmpty())
+ return -1;
+ else
+ return getTrips().get(getTrips().size() - 1).getDepartureTime();
+ }
+
+ private int aveTripLength = -1;
+ private int tripCount = 0;
+
+ public int getAverageTripLength() {
+ if (aveTripLength < 0) {
+ int sum = 0;
+ for (ScheduleItem trip : getTrips()) {
+ int tripLength = trip.getTripLength();
+ if (tripLength > 0) {
+ sum += tripLength;
+ tripCount++;
+ }
+ }
+ if (tripCount > 0) {
+ aveTripLength = sum / tripCount;
+ }
+ }
+ return aveTripLength;
+ }
+
+ public int getTripCountForAverage() {
+ getAverageTripLength();
+ return tripCount;
+ }
}
\ No newline at end of file
diff --git a/src/com/dougkeen/bart/model/ScheduleItem.java b/src/com/dougkeen/bart/model/ScheduleItem.java
index 7d0ca96..d5144f5 100644
--- a/src/com/dougkeen/bart/model/ScheduleItem.java
+++ b/src/com/dougkeen/bart/model/ScheduleItem.java
@@ -1,115 +1,115 @@
-package com.dougkeen.bart.model;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public class ScheduleItem {
-
- public ScheduleItem() {
- super();
- }
-
- public ScheduleItem(Station origin, Station destination) {
- super();
- this.origin = origin;
- this.destination = destination;
- }
-
- public static final int SCHEDULE_ITEM_DEPARTURE_EQUALS_TOLERANCE = 120000;
-
- private Station origin;
- private Station destination;
- private String fare;
- private long departureTime;
- private long arrivalTime;
- private boolean bikesAllowed;
- private String trainHeadStation;
-
- public Station getOrigin() {
- return origin;
- }
-
- public void setOrigin(Station origin) {
- this.origin = origin;
- }
-
- public Station getDestination() {
- return destination;
- }
-
- public void setDestination(Station destination) {
- this.destination = destination;
- }
-
- public String getFare() {
- return fare;
- }
-
- public void setFare(String fare) {
- this.fare = fare;
- }
-
- public long getDepartureTime() {
- return departureTime;
- }
-
- public void setDepartureTime(long departureTime) {
- this.departureTime = departureTime;
- }
-
- public long getArrivalTime() {
- return arrivalTime;
- }
-
- public void setArrivalTime(long arrivalTime) {
- this.arrivalTime = arrivalTime;
- }
-
- public int getTripLength() {
- if (departureTime <= 0 || arrivalTime <= 0) {
- return 0;
- } else {
- return (int) (arrivalTime - departureTime);
- }
- }
-
- public boolean isBikesAllowed() {
- return bikesAllowed;
- }
-
- public void setBikesAllowed(boolean bikesAllowed) {
- this.bikesAllowed = bikesAllowed;
- }
-
- public String getTrainHeadStation() {
- return trainHeadStation;
- }
-
- public void setTrainHeadStation(String trainHeadStation) {
- this.trainHeadStation = trainHeadStation;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- DateFormat format = SimpleDateFormat.getTimeInstance();
- builder.append("ScheduleItem [origin=");
- builder.append(origin);
- builder.append(", destination=");
- builder.append(destination);
- builder.append(", fare=");
- builder.append(fare);
- builder.append(", departureTime=");
- builder.append(format.format(new Date(departureTime)));
- builder.append(", arrivalTime=");
- builder.append(format.format(new Date(arrivalTime)));
- builder.append(", bikesAllowed=");
- builder.append(bikesAllowed);
- builder.append(", trainHeadStation=");
- builder.append(trainHeadStation);
- builder.append("]");
- return builder.toString();
- }
-
-}
+package com.dougkeen.bart.model;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class ScheduleItem {
+
+ public ScheduleItem() {
+ super();
+ }
+
+ public ScheduleItem(Station origin, Station destination) {
+ super();
+ this.origin = origin;
+ this.destination = destination;
+ }
+
+ public static final int SCHEDULE_ITEM_DEPARTURE_EQUALS_TOLERANCE = 120000;
+
+ private Station origin;
+ private Station destination;
+ private String fare;
+ private long departureTime;
+ private long arrivalTime;
+ private boolean bikesAllowed;
+ private String trainHeadStation;
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(Station origin) {
+ this.origin = origin;
+ }
+
+ public Station getDestination() {
+ return destination;
+ }
+
+ public void setDestination(Station destination) {
+ this.destination = destination;
+ }
+
+ public String getFare() {
+ return fare;
+ }
+
+ public void setFare(String fare) {
+ this.fare = fare;
+ }
+
+ public long getDepartureTime() {
+ return departureTime;
+ }
+
+ public void setDepartureTime(long departureTime) {
+ this.departureTime = departureTime;
+ }
+
+ public long getArrivalTime() {
+ return arrivalTime;
+ }
+
+ public void setArrivalTime(long arrivalTime) {
+ this.arrivalTime = arrivalTime;
+ }
+
+ public int getTripLength() {
+ if (departureTime <= 0 || arrivalTime <= 0) {
+ return 0;
+ } else {
+ return (int) (arrivalTime - departureTime);
+ }
+ }
+
+ public boolean isBikesAllowed() {
+ return bikesAllowed;
+ }
+
+ public void setBikesAllowed(boolean bikesAllowed) {
+ this.bikesAllowed = bikesAllowed;
+ }
+
+ public String getTrainHeadStation() {
+ return trainHeadStation;
+ }
+
+ public void setTrainHeadStation(String trainHeadStation) {
+ this.trainHeadStation = trainHeadStation;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ DateFormat format = SimpleDateFormat.getTimeInstance();
+ builder.append("ScheduleItem [origin=");
+ builder.append(origin);
+ builder.append(", destination=");
+ builder.append(destination);
+ builder.append(", fare=");
+ builder.append(fare);
+ builder.append(", departureTime=");
+ builder.append(format.format(new Date(departureTime)));
+ builder.append(", arrivalTime=");
+ builder.append(format.format(new Date(arrivalTime)));
+ builder.append(", bikesAllowed=");
+ builder.append(bikesAllowed);
+ builder.append(", trainHeadStation=");
+ builder.append(trainHeadStation);
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/src/com/dougkeen/bart/model/Station.java b/src/com/dougkeen/bart/model/Station.java
index 3309e56..a85050b 100644
--- a/src/com/dougkeen/bart/model/Station.java
+++ b/src/com/dougkeen/bart/model/Station.java
@@ -1,287 +1,286 @@
-package com.dougkeen.bart.model;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import android.util.Log;
-
-public enum Station {
- _12TH("12th", "12th St./Oakland City Center", "12th St Oak", false, false,
- "bayf", "bayf"),
- _16TH("16th", "16th St. Mission", "16th St", false, false),
- _19TH("19th", "19th St./Oakland", "19th St Oak", false, false, "bayf",
- "bayf"),
- _24TH("24th", "24th St. Mission", "24th St", false, false),
- ASHB("ashb", "Ashby", "Ashby", false, false, "mcar", "mcar"),
- BALB("balb", "Balboa Park", "Balboa", false, false),
- BAYF("bayf", "Bay Fair", "Bay Fair", true, false, "mcar", "mcar"),
- CAST("cast", "Castro Valley", "Castro Vly", false, false, "bayf", "bayf"),
- CIVC("civc", "Civic Center", "Civic Ctr", false, false),
- COLS("cols", "Coliseum/Oakland Airport", "Coliseum/OAK", true, false,
- "mcar", "mcar"),
- COLM("colm", "Colma", "Colma", false, false, "balb", "balb"),
- CONC("conc", "Concord", "Concord", false, false, "mcar", "mcar"),
- DALY("daly", "Daly City", "Daly City", false, false),
- DBRK("dbrk", "Downtown Berkeley", "Dtwn Berk", false, false, "mcar",
- "mcar"),
- DUBL("dubl", "Dublin/Pleasanton", "Dbln/Plsntn", false, true, "bayf",
- "bayf", true, 719999),
- DELN("deln", "El Cerrito del Norte", "El Cer/Norte", false, false, "mcar",
- "mcar"),
- PLZA("plza", "El Cerrito Plaza", "El Cer/Plz", false, false, "mcar", "mcar"),
- EMBR("embr", "Embarcadero", "Embarcdro", false, false),
- FRMT("frmt", "Fremont", "Fremont", true, true, "bayf", "bayf", true, 299999),
- FTVL("ftvl", "Fruitvale", "Fruitvale", true, false, "mcar", "mcar"),
- GLEN("glen", "Glen Park", "Glen Park", false, false),
- HAYW("hayw", "Hayward", "Hayward", true, false, "bayf", "bayf"),
- LAFY("lafy", "Lafayette", "Lafayette", false, false, "mcar", "mcar"),
- LAKE("lake", "Lake Merritt", "Lk Merritt", true, false, "mcar", "mcar"),
- MCAR("mcar", "MacArthur", "MacArthur", false, false, "bayf", "bayf"),
- MLBR("mlbr", "Millbrae", "Millbrae", false, true, "balb", "balb", true,
- 719999),
- MONT("mont", "Montgomery St.", "Montgomery", false, false),
- NBRK("nbrk", "North Berkeley", "N Berkeley", false, false, "mcar", "mcar"),
- NCON("ncon", "North Concord/Martinez", "N Conc/Mrtnz", false, false,
- "mcar", "mcar"),
- ORIN("orin", "Orinda", "Orinda", false, false, "mcar", "mcar"),
- PITT("pitt", "Pittsburg/Bay Point", "Pitt/Bay Pt", false, true, "mcar",
- "mcar", true, 719999),
- PHIL("phil", "Pleasant Hill", "Plsnt Hill", false, false, "mcar", "mcar"),
- POWL("powl", "Powell St.", "Powell", false, false),
- RICH("rich", "Richmond", "Richmond", false, true, "mcar", "mcar", true,
- 299999),
- ROCK("rock", "Rockridge", "Rockridge", false, false, "mcar", "mcar"),
- SBRN("sbrn", "San Bruno", "San Bruno", false, false, "balb", "balb"),
- SANL("sanl", "San Leandro", "San Leandro", true, false, "mcar", "mcar"),
- SFIA("sfia", "SFO Airport", "SFO", false, false, "balb", "balb", true,
- 719999),
- SHAY("shay", "South Hayward", "S Hayward", true, false, "bayf", "bayf"),
- SSAN("ssan", "South San Francisco", "S San Fran", false, false, "balb",
- "balb"),
- UCTY("ucty", "Union City", "Union City", true, false, "bayf", "bayf"),
- WCRK("wcrk", "Walnut Creek", "Walnut Crk", false, false, "mcar", "mcar"),
- WDUB("wdub", "West Dublin/Pleasanton", "W Dbln/Plsntn", false, false,
- "bayf", "bayf"),
- WOAK("woak", "West Oakland", "W Oakland", false, false),
- SPCL("spcl", "Special", "Special", false, false);
-
- public final String abbreviation;
- public final String name;
- public final String shortName;
- public final boolean transferFriendly;
- public final boolean invertDirection;
- protected final String inboundTransferStation;
- protected final String outboundTransferStation;
- public final boolean endOfLine;
- public final boolean longStationLinger;
- public final int departureEqualityTolerance;
-
- public final static int DEFAULT_DEPARTURE_EQUALITY_TOLERANCE = 119999;
-
- private Station(String abbreviation, String name, String shortName,
- boolean invertDirection, boolean endOfLine) {
- this(abbreviation, name, shortName, invertDirection, endOfLine, null,
- null, false, DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
- }
-
- private Station(String abbreviation, String name, String shortName,
- boolean invertDirection, boolean endOfLine, String transferStation) {
- this(abbreviation, name, shortName, invertDirection, endOfLine,
- transferStation, null, false,
- DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
- }
-
- private Station(String abbreviation, String name, String shortName,
- boolean invertDirection, boolean endOfLine,
- String inboundTransferStation, String outboundTransferStation) {
- this(abbreviation, name, shortName, invertDirection, endOfLine,
- inboundTransferStation, outboundTransferStation, false,
- DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
- }
-
- private Station(String abbreviation, String name, String shortName,
- boolean invertDirection, boolean endOfLine,
- String inboundTransferStation, String outboundTransferStation,
- boolean longStationLinger, int departureEqualityTolerance) {
- this.abbreviation = abbreviation;
- this.name = name;
- this.shortName = shortName;
- this.invertDirection = invertDirection;
- this.inboundTransferStation = inboundTransferStation;
- this.transferFriendly = outboundTransferStation != null;
- this.outboundTransferStation = outboundTransferStation;
- this.endOfLine = endOfLine;
- this.longStationLinger = longStationLinger;
- this.departureEqualityTolerance = departureEqualityTolerance;
- }
-
- public static Station getByAbbreviation(String abbr) {
- try {
- if (abbr == null) {
- return null;
- } else if (Character.isDigit(abbr.charAt(0))) {
- return Station.valueOf("_" + abbr.toUpperCase());
- } else {
- return Station.valueOf(abbr.toUpperCase());
- }
- } catch (IllegalArgumentException e) {
- Log.e(Constants.TAG, "Could not find station for '" + abbr + "'", e);
- return null;
- }
- }
-
- public Station getInboundTransferStation() {
- return getByAbbreviation(inboundTransferStation);
- }
-
- public Station getOutboundTransferStation() {
- return getByAbbreviation(outboundTransferStation);
- }
-
- public boolean isValidEndpointForDestination(Station dest, Station endpoint) {
- for (Line line : Line.values()) {
- int origIndex = line.stations.indexOf(this);
- if (origIndex < 0)
- continue;
- int destIndex = line.stations.indexOf(dest);
- if (destIndex < 0)
- continue;
- int endpointIndex = line.stations.indexOf(endpoint);
- if (endpointIndex >= 0)
- return true;
- }
- return false;
- }
-
- public List getDirectRoutesForDestination(Station dest) {
- return getDirectRoutesForDestination(this, dest, null, null);
- }
-
- public List getDirectRoutesForDestination(Station origin,
- Station dest, Station transferStation,
- Collection transferLines) {
- if (dest == null)
- return null;
- Boolean isNorth = null;
- List returnList = new ArrayList();
- final Collection applicableLines = Line.getLinesWithStations(
- this, dest);
- if (transferLines != null && !transferLines.isEmpty()) {
- for (Line transferLine : transferLines) {
- int origIndex = transferLine.stations.indexOf(origin);
- int destIndex = transferLine.stations.indexOf(origin
- .getOutboundTransferStation());
-
- isNorth = (origIndex < destIndex);
- if (origin.invertDirection && transferLine.directionMayInvert) {
- isNorth = !isNorth;
- break;
- }
- }
- }
- for (Line line : applicableLines) {
- if (transferLines == null || transferLines.isEmpty()) {
- int origIndex = line.stations.indexOf(this);
- int destIndex = line.stations.indexOf(dest);
-
- isNorth = (origIndex < destIndex);
- if (line.directionMayInvert && this.invertDirection) {
- isNorth = !isNorth;
- }
- }
- Route route = new Route();
- route.setOrigin(origin);
- route.setDirectLine(line);
- if (this.equals(origin)) {
- route.setDestination(dest);
- } else {
- // This must be the outbound transfer station
- route.setDestination(origin.getOutboundTransferStation());
- route.setTransferLines(transferLines);
- }
- route.setDirection(isNorth ? "n" : "s");
- if (transferStation != null || line.requiresTransfer) {
- route.setTransfer(true);
- } else {
- route.setTransfer(false);
- }
-
- returnList.add(route);
- }
- return returnList;
- }
-
- public List getTransferRoutes(Station dest) {
- List returnList = new ArrayList();
-
- if (dest.getInboundTransferStation() != null) {
- // Try getting to the destination's inbound xfer station first
- returnList.addAll(getDirectRoutesForDestination(this,
- dest.getInboundTransferStation(),
- dest.getInboundTransferStation(), null));
- }
-
- if (returnList.isEmpty() && outboundTransferStation != null) {
- // Try getting from the outbound transfer station to the
- // destination next
- final Collection outboundTransferLines = Line
- .getLinesWithStations(this, getOutboundTransferStation());
- final List routesForDestination = getOutboundTransferStation()
- .getDirectRoutesForDestination(this, dest,
- getOutboundTransferStation(), outboundTransferLines);
- if (routesForDestination != null && !routesForDestination.isEmpty()) {
- returnList.addAll(routesForDestination);
- }
- }
-
- if (returnList.isEmpty()) {
- // Try getting from the outbound transfer station to the
- // destination's inbound xfer station
- final List routesForDestination = getDoubleTransferRoutes(dest);
- if (routesForDestination != null && !routesForDestination.isEmpty()) {
- returnList.addAll(routesForDestination);
- }
- }
-
- return returnList;
- }
-
- public List getDoubleTransferRoutes(Station dest) {
- if (getOutboundTransferStation() == null
- || dest.getInboundTransferStation() == null)
- return new ArrayList();
-
- // Get routes from the outbound transfer station to the
- // destination's inbound xfer station
- return getOutboundTransferStation().getDirectRoutesForDestination(this,
- dest.getInboundTransferStation(), getOutboundTransferStation(),
- Line.getLinesWithStations(this, getOutboundTransferStation()));
- }
-
- static public List getStationList() {
- List list = new ArrayList();
- for (Station station : values()) {
- if (!station.equals(Station.SPCL)) {
- list.add(station);
- }
- }
- return list;
- }
-
- public String toString() {
- return name;
- }
-
- public boolean isBetween(Station origin, Station destination, Line line) {
- int originIndex = line.stations.indexOf(origin);
- int destinationIndex = line.stations.indexOf(destination);
- int stationIndex = line.stations.indexOf(this);
- if (originIndex < 0 || destinationIndex < 0 || stationIndex < 0) {
- return false;
- }
-
- return Math.abs(stationIndex - originIndex) < Math.abs(destinationIndex
- - originIndex);
- }
-}
+package com.dougkeen.bart.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import android.util.Log;
+
+public enum Station {
+ _12TH("12th", "12th St./Oakland City Center", "12th St Oak", false, false,
+ "bayf", "bayf"),
+ _16TH("16th", "16th St. Mission", "16th St", false, false),
+ _19TH("19th", "19th St./Oakland", "19th St Oak", false, false, "bayf",
+ "bayf"),
+ _24TH("24th", "24th St. Mission", "24th St", false, false),
+ ASHB("ashb", "Ashby", "Ashby", false, false, "mcar", "mcar"),
+ BALB("balb", "Balboa Park", "Balboa", false, false),
+ BAYF("bayf", "Bay Fair", "Bay Fair", true, false, "mcar", "mcar"),
+ CAST("cast", "Castro Valley", "Castro Vly", false, false, "bayf", "bayf"),
+ CIVC("civc", "Civic Center", "Civic Ctr", false, false),
+ COLS("cols", "Coliseum/Oakland Airport", "Coliseum/OAK", true, false,
+ "mcar", "mcar"),
+ COLM("colm", "Colma", "Colma", false, false, "balb", "balb"),
+ CONC("conc", "Concord", "Concord", false, false, "mcar", "mcar"),
+ DALY("daly", "Daly City", "Daly City", false, false),
+ DBRK("dbrk", "Downtown Berkeley", "Dtwn Berk", false, false, "mcar", "mcar"),
+ DUBL("dubl", "Dublin/Pleasanton", "Dbln/Plsntn", false, true, "bayf",
+ "bayf", true, 719999),
+ DELN("deln", "El Cerrito del Norte", "El Cer/Norte", false, false, "mcar",
+ "mcar"),
+ PLZA("plza", "El Cerrito Plaza", "El Cer/Plz", false, false, "mcar", "mcar"),
+ EMBR("embr", "Embarcadero", "Embarcdro", false, false),
+ FRMT("frmt", "Fremont", "Fremont", true, true, "bayf", "bayf", true, 299999),
+ FTVL("ftvl", "Fruitvale", "Fruitvale", true, false, "mcar", "mcar"),
+ GLEN("glen", "Glen Park", "Glen Park", false, false),
+ HAYW("hayw", "Hayward", "Hayward", true, false, "bayf", "bayf"),
+ LAFY("lafy", "Lafayette", "Lafayette", false, false, "mcar", "mcar"),
+ LAKE("lake", "Lake Merritt", "Lk Merritt", true, false, "mcar", "mcar"),
+ MCAR("mcar", "MacArthur", "MacArthur", false, false, "bayf", "bayf"),
+ MLBR("mlbr", "Millbrae", "Millbrae", false, true, "balb", "balb", true,
+ 719999),
+ MONT("mont", "Montgomery St.", "Montgomery", false, false),
+ NBRK("nbrk", "North Berkeley", "N Berkeley", false, false, "mcar", "mcar"),
+ NCON("ncon", "North Concord/Martinez", "N Conc/Mrtnz", false, false,
+ "mcar", "mcar"),
+ ORIN("orin", "Orinda", "Orinda", false, false, "mcar", "mcar"),
+ PITT("pitt", "Pittsburg/Bay Point", "Pitt/Bay Pt", false, true, "mcar",
+ "mcar", true, 719999),
+ PHIL("phil", "Pleasant Hill", "Plsnt Hill", false, false, "mcar", "mcar"),
+ POWL("powl", "Powell St.", "Powell", false, false),
+ RICH("rich", "Richmond", "Richmond", false, true, "mcar", "mcar", true,
+ 299999),
+ ROCK("rock", "Rockridge", "Rockridge", false, false, "mcar", "mcar"),
+ SBRN("sbrn", "San Bruno", "San Bruno", false, false, "balb", "balb"),
+ SANL("sanl", "San Leandro", "San Leandro", true, false, "mcar", "mcar"),
+ SFIA("sfia", "SFO Airport", "SFO", false, false, "balb", "balb", true,
+ 719999),
+ SHAY("shay", "South Hayward", "S Hayward", true, false, "bayf", "bayf"),
+ SSAN("ssan", "South San Francisco", "S San Fran", false, false, "balb",
+ "balb"),
+ UCTY("ucty", "Union City", "Union City", true, false, "bayf", "bayf"),
+ WCRK("wcrk", "Walnut Creek", "Walnut Crk", false, false, "mcar", "mcar"),
+ WDUB("wdub", "West Dublin/Pleasanton", "W Dbln/Plsntn", false, false,
+ "bayf", "bayf"),
+ WOAK("woak", "West Oakland", "W Oakland", false, false),
+ SPCL("spcl", "Special", "Special", false, false);
+
+ public final String abbreviation;
+ public final String name;
+ public final String shortName;
+ public final boolean transferFriendly;
+ public final boolean invertDirection;
+ protected final String inboundTransferStation;
+ protected final String outboundTransferStation;
+ public final boolean endOfLine;
+ public final boolean longStationLinger;
+ public final int departureEqualityTolerance;
+
+ public final static int DEFAULT_DEPARTURE_EQUALITY_TOLERANCE = 119999;
+
+ private Station(String abbreviation, String name, String shortName,
+ boolean invertDirection, boolean endOfLine) {
+ this(abbreviation, name, shortName, invertDirection, endOfLine, null,
+ null, false, DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
+ }
+
+ private Station(String abbreviation, String name, String shortName,
+ boolean invertDirection, boolean endOfLine, String transferStation) {
+ this(abbreviation, name, shortName, invertDirection, endOfLine,
+ transferStation, null, false,
+ DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
+ }
+
+ private Station(String abbreviation, String name, String shortName,
+ boolean invertDirection, boolean endOfLine,
+ String inboundTransferStation, String outboundTransferStation) {
+ this(abbreviation, name, shortName, invertDirection, endOfLine,
+ inboundTransferStation, outboundTransferStation, false,
+ DEFAULT_DEPARTURE_EQUALITY_TOLERANCE);
+ }
+
+ private Station(String abbreviation, String name, String shortName,
+ boolean invertDirection, boolean endOfLine,
+ String inboundTransferStation, String outboundTransferStation,
+ boolean longStationLinger, int departureEqualityTolerance) {
+ this.abbreviation = abbreviation;
+ this.name = name;
+ this.shortName = shortName;
+ this.invertDirection = invertDirection;
+ this.inboundTransferStation = inboundTransferStation;
+ this.transferFriendly = outboundTransferStation != null;
+ this.outboundTransferStation = outboundTransferStation;
+ this.endOfLine = endOfLine;
+ this.longStationLinger = longStationLinger;
+ this.departureEqualityTolerance = departureEqualityTolerance;
+ }
+
+ public static Station getByAbbreviation(String abbr) {
+ try {
+ if (abbr == null) {
+ return null;
+ } else if (Character.isDigit(abbr.charAt(0))) {
+ return Station.valueOf("_" + abbr.toUpperCase());
+ } else {
+ return Station.valueOf(abbr.toUpperCase());
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(Constants.TAG, "Could not find station for '" + abbr + "'", e);
+ return null;
+ }
+ }
+
+ public Station getInboundTransferStation() {
+ return getByAbbreviation(inboundTransferStation);
+ }
+
+ public Station getOutboundTransferStation() {
+ return getByAbbreviation(outboundTransferStation);
+ }
+
+ public boolean isValidEndpointForDestination(Station dest, Station endpoint) {
+ for (Line line : Line.values()) {
+ int origIndex = line.stations.indexOf(this);
+ if (origIndex < 0)
+ continue;
+ int destIndex = line.stations.indexOf(dest);
+ if (destIndex < 0)
+ continue;
+ int endpointIndex = line.stations.indexOf(endpoint);
+ if (endpointIndex >= 0)
+ return true;
+ }
+ return false;
+ }
+
+ public List getDirectRoutesForDestination(Station dest) {
+ return getDirectRoutesForDestination(this, dest, null, null);
+ }
+
+ public List getDirectRoutesForDestination(Station origin,
+ Station dest, Station transferStation,
+ Collection transferLines) {
+ if (dest == null)
+ return null;
+ Boolean isNorth = null;
+ List returnList = new ArrayList();
+ final Collection applicableLines = Line.getLinesWithStations(
+ this, dest);
+ if (transferLines != null && !transferLines.isEmpty()) {
+ for (Line transferLine : transferLines) {
+ int origIndex = transferLine.stations.indexOf(origin);
+ int destIndex = transferLine.stations.indexOf(origin
+ .getOutboundTransferStation());
+
+ isNorth = (origIndex < destIndex);
+ if (origin.invertDirection && transferLine.directionMayInvert) {
+ isNorth = !isNorth;
+ break;
+ }
+ }
+ }
+ for (Line line : applicableLines) {
+ if (transferLines == null || transferLines.isEmpty()) {
+ int origIndex = line.stations.indexOf(this);
+ int destIndex = line.stations.indexOf(dest);
+
+ isNorth = (origIndex < destIndex);
+ if (line.directionMayInvert && this.invertDirection) {
+ isNorth = !isNorth;
+ }
+ }
+ Route route = new Route();
+ route.setOrigin(origin);
+ route.setDirectLine(line);
+ if (this.equals(origin)) {
+ route.setDestination(dest);
+ } else {
+ // This must be the outbound transfer station
+ route.setDestination(origin.getOutboundTransferStation());
+ route.setTransferLines(transferLines);
+ }
+ route.setDirection(isNorth ? "n" : "s");
+ if (transferStation != null || line.requiresTransfer) {
+ route.setTransfer(true);
+ } else {
+ route.setTransfer(false);
+ }
+
+ returnList.add(route);
+ }
+ return returnList;
+ }
+
+ public List getTransferRoutes(Station dest) {
+ List returnList = new ArrayList();
+
+ if (dest.getInboundTransferStation() != null) {
+ // Try getting to the destination's inbound xfer station first
+ returnList.addAll(getDirectRoutesForDestination(this,
+ dest.getInboundTransferStation(),
+ dest.getInboundTransferStation(), null));
+ }
+
+ if (returnList.isEmpty() && outboundTransferStation != null) {
+ // Try getting from the outbound transfer station to the
+ // destination next
+ final Collection outboundTransferLines = Line
+ .getLinesWithStations(this, getOutboundTransferStation());
+ final List routesForDestination = getOutboundTransferStation()
+ .getDirectRoutesForDestination(this, dest,
+ getOutboundTransferStation(), outboundTransferLines);
+ if (routesForDestination != null && !routesForDestination.isEmpty()) {
+ returnList.addAll(routesForDestination);
+ }
+ }
+
+ if (returnList.isEmpty()) {
+ // Try getting from the outbound transfer station to the
+ // destination's inbound xfer station
+ final List routesForDestination = getDoubleTransferRoutes(dest);
+ if (routesForDestination != null && !routesForDestination.isEmpty()) {
+ returnList.addAll(routesForDestination);
+ }
+ }
+
+ return returnList;
+ }
+
+ public List getDoubleTransferRoutes(Station dest) {
+ if (getOutboundTransferStation() == null
+ || dest.getInboundTransferStation() == null)
+ return new ArrayList();
+
+ // Get routes from the outbound transfer station to the
+ // destination's inbound xfer station
+ return getOutboundTransferStation().getDirectRoutesForDestination(this,
+ dest.getInboundTransferStation(), getOutboundTransferStation(),
+ Line.getLinesWithStations(this, getOutboundTransferStation()));
+ }
+
+ static public List getStationList() {
+ List list = new ArrayList();
+ for (Station station : values()) {
+ if (!station.equals(Station.SPCL)) {
+ list.add(station);
+ }
+ }
+ return list;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public boolean isBetween(Station origin, Station destination, Line line) {
+ int originIndex = line.stations.indexOf(origin);
+ int destinationIndex = line.stations.indexOf(destination);
+ int stationIndex = line.stations.indexOf(this);
+ if (originIndex < 0 || destinationIndex < 0 || stationIndex < 0) {
+ return false;
+ }
+
+ return Math.abs(stationIndex - originIndex) < Math.abs(destinationIndex
+ - originIndex);
+ }
+}
diff --git a/src/com/dougkeen/bart/model/StationPair.java b/src/com/dougkeen/bart/model/StationPair.java
index 3496f0a..c38a0f1 100644
--- a/src/com/dougkeen/bart/model/StationPair.java
+++ b/src/com/dougkeen/bart/model/StationPair.java
@@ -1,151 +1,151 @@
-package com.dougkeen.bart.model;
-
-import org.apache.commons.lang3.ObjectUtils;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.dougkeen.bart.data.CursorUtils;
-import com.dougkeen.bart.data.RoutesColumns;
-
-public class StationPair implements Parcelable {
- public StationPair(Station origin, Station destination) {
- super();
- this.origin = origin;
- this.destination = destination;
- }
-
- public StationPair(Long id, Station origin, Station destination) {
- super();
- this.origin = origin;
- this.destination = destination;
- this.id = id;
- }
-
- public StationPair(Parcel in) {
- readFromParcel(in);
- }
-
- public static StationPair createFromCursor(Cursor cursor) {
- StationPair pair = new StationPair(
- Station.getByAbbreviation(CursorUtils.getString(cursor,
- RoutesColumns.FROM_STATION)),
- Station.getByAbbreviation(CursorUtils.getString(cursor,
- RoutesColumns.TO_STATION)));
- pair.id = CursorUtils.getLong(cursor, RoutesColumns._ID);
- pair.fare = CursorUtils.getString(cursor, RoutesColumns.FARE);
- pair.fareLastUpdated = CursorUtils.getLong(cursor,
- RoutesColumns.FARE_LAST_UPDATED);
- return pair;
- }
-
- private Long id;
- private Station origin;
- private Station destination;
- private String fare;
- private Long fareLastUpdated;
-
- public Long getId() {
- return id;
- }
-
- public Station getOrigin() {
- return origin;
- }
-
- public Station getDestination() {
- return destination;
- }
-
- public String getFare() {
- return fare;
- }
-
- public void setFare(String fare) {
- this.fare = fare;
- }
-
- public Long getFareLastUpdated() {
- return fareLastUpdated;
- }
-
- public void setFareLastUpdated(Long fareLastUpdated) {
- this.fareLastUpdated = fareLastUpdated;
- }
-
- public boolean isBetweenStations(Station station1, Station station2) {
- return (origin.equals(station1) && destination.equals(station2))
- || (origin.equals(station2) && destination.equals(station1));
- }
-
- public Uri getUri() {
- if (getOrigin() != null && getDestination() != null) {
- return Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT.buildUpon()
- .appendPath(getOrigin().abbreviation)
- .appendPath(getDestination().abbreviation).build();
- } else {
- return null;
- }
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((destination == null) ? 0 : destination.hashCode());
- result = prime * result + ((origin == null) ? 0 : origin.hashCode());
- return result;
- }
-
- public boolean fareEquals(StationPair other) {
- if (other == null)
- return false;
- return ObjectUtils.equals(getFare(), other.getFare())
- && ObjectUtils.equals(getFareLastUpdated(),
- other.getFareLastUpdated());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- StationPair other = (StationPair) obj;
- if (destination != other.destination)
- return false;
- if (origin != other.origin)
- return false;
- return true;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(origin.abbreviation);
- dest.writeString(destination.abbreviation);
- }
-
- private void readFromParcel(Parcel in) {
- origin = Station.getByAbbreviation(in.readString());
- destination = Station.getByAbbreviation(in.readString());
- }
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- public StationPair createFromParcel(Parcel in) {
- return new StationPair(in);
- }
-
- public StationPair[] newArray(int size) {
- return new StationPair[size];
- }
- };
+package com.dougkeen.bart.model;
+
+import org.apache.commons.lang3.ObjectUtils;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.dougkeen.bart.data.CursorUtils;
+import com.dougkeen.bart.data.RoutesColumns;
+
+public class StationPair implements Parcelable {
+ public StationPair(Station origin, Station destination) {
+ super();
+ this.origin = origin;
+ this.destination = destination;
+ }
+
+ public StationPair(Long id, Station origin, Station destination) {
+ super();
+ this.origin = origin;
+ this.destination = destination;
+ this.id = id;
+ }
+
+ public StationPair(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static StationPair createFromCursor(Cursor cursor) {
+ StationPair pair = new StationPair(
+ Station.getByAbbreviation(CursorUtils.getString(cursor,
+ RoutesColumns.FROM_STATION)),
+ Station.getByAbbreviation(CursorUtils.getString(cursor,
+ RoutesColumns.TO_STATION)));
+ pair.id = CursorUtils.getLong(cursor, RoutesColumns._ID);
+ pair.fare = CursorUtils.getString(cursor, RoutesColumns.FARE);
+ pair.fareLastUpdated = CursorUtils.getLong(cursor,
+ RoutesColumns.FARE_LAST_UPDATED);
+ return pair;
+ }
+
+ private Long id;
+ private Station origin;
+ private Station destination;
+ private String fare;
+ private Long fareLastUpdated;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Station getOrigin() {
+ return origin;
+ }
+
+ public Station getDestination() {
+ return destination;
+ }
+
+ public String getFare() {
+ return fare;
+ }
+
+ public void setFare(String fare) {
+ this.fare = fare;
+ }
+
+ public Long getFareLastUpdated() {
+ return fareLastUpdated;
+ }
+
+ public void setFareLastUpdated(Long fareLastUpdated) {
+ this.fareLastUpdated = fareLastUpdated;
+ }
+
+ public boolean isBetweenStations(Station station1, Station station2) {
+ return (origin.equals(station1) && destination.equals(station2))
+ || (origin.equals(station2) && destination.equals(station1));
+ }
+
+ public Uri getUri() {
+ if (getOrigin() != null && getDestination() != null) {
+ return Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT.buildUpon()
+ .appendPath(getOrigin().abbreviation)
+ .appendPath(getDestination().abbreviation).build();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((destination == null) ? 0 : destination.hashCode());
+ result = prime * result + ((origin == null) ? 0 : origin.hashCode());
+ return result;
+ }
+
+ public boolean fareEquals(StationPair other) {
+ if (other == null)
+ return false;
+ return ObjectUtils.equals(getFare(), other.getFare())
+ && ObjectUtils.equals(getFareLastUpdated(),
+ other.getFareLastUpdated());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StationPair other = (StationPair) obj;
+ if (destination != other.destination)
+ return false;
+ if (origin != other.origin)
+ return false;
+ return true;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(origin.abbreviation);
+ dest.writeString(destination.abbreviation);
+ }
+
+ private void readFromParcel(Parcel in) {
+ origin = Station.getByAbbreviation(in.readString());
+ destination = Station.getByAbbreviation(in.readString());
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ public StationPair createFromParcel(Parcel in) {
+ return new StationPair(in);
+ }
+
+ public StationPair[] newArray(int size) {
+ return new StationPair[size];
+ }
+ };
}
\ No newline at end of file
diff --git a/src/com/dougkeen/bart/model/TextProvider.java b/src/com/dougkeen/bart/model/TextProvider.java
index 7272567..c659498 100644
--- a/src/com/dougkeen/bart/model/TextProvider.java
+++ b/src/com/dougkeen/bart/model/TextProvider.java
@@ -1,8 +1,7 @@
-package com.dougkeen.bart.model;
-
-
-public interface TextProvider {
-
- String getText(long tickNumber);
-
-}
+package com.dougkeen.bart.model;
+
+public interface TextProvider {
+
+ String getText(long tickNumber);
+
+}
diff --git a/src/com/dougkeen/bart/networktasks/EtdContentHandler.java b/src/com/dougkeen/bart/networktasks/EtdContentHandler.java
index d8d7e49..3826095 100644
--- a/src/com/dougkeen/bart/networktasks/EtdContentHandler.java
+++ b/src/com/dougkeen/bart/networktasks/EtdContentHandler.java
@@ -1,122 +1,122 @@
-package com.dougkeen.bart.networktasks;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import android.util.Log;
-
-import com.dougkeen.bart.model.Constants;
-import com.dougkeen.bart.model.Departure;
-import com.dougkeen.bart.model.Line;
-import com.dougkeen.bart.model.RealTimeDepartures;
-import com.dougkeen.bart.model.Route;
-import com.dougkeen.bart.model.Station;
-
-public class EtdContentHandler extends DefaultHandler {
- public EtdContentHandler(Station origin, Station destination,
- List routes) {
- super();
- realTimeDepartures = new RealTimeDepartures(origin, destination, routes);
- }
-
- private final static List TAGS = Arrays.asList("date", "time",
- "abbreviation", "minutes", "platform", "direction", "length",
- "color", "hexcolor", "bikeflag");
-
- private RealTimeDepartures realTimeDepartures;
-
- public RealTimeDepartures getRealTimeDepartures() {
- return realTimeDepartures;
- }
-
- private String date;
- private String currentDestination;
- private String currentValue;
- private Departure currentDeparture;
- private boolean isParsingTag;
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (isParsingTag) {
- currentValue = new String(ch, start, length);
- }
- }
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (TAGS.contains(localName)) {
- isParsingTag = true;
- }
- if (localName.equals("estimate")) {
- currentDeparture = new Departure();
- currentDeparture.setTrainDestination(Station
- .getByAbbreviation(currentDestination));
- currentDeparture.setOrigin(realTimeDepartures.getOrigin());
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if (localName.equals("date")) {
- date = currentValue;
- } else if (localName.equals("time")) {
- realTimeDepartures.setTime(Date.parse(date + " " + currentValue));
- } else if (localName.equals("abbreviation")) {
- currentDestination = currentValue;
- } else if (localName.equals("minutes")) {
- if (StringUtils.isNumeric(currentValue)) {
- currentDeparture.setMinutes(Integer.parseInt(currentValue));
- } else {
- currentDeparture.setMinutes(0);
- }
- } else if (localName.equals("platform")) {
- currentDeparture.setPlatform(currentValue);
- } else if (localName.equals("direction")) {
- currentDeparture.setDirection(currentValue);
- } else if (localName.equals("length")) {
- currentDeparture.setTrainLength(currentValue);
- } else if (localName.equals("color")) {
- try {
- if (currentValue.equalsIgnoreCase("WHITE")) {
- for (Line line : Line.values()) {
- if (line.stations.indexOf(currentDeparture
- .getTrainDestination()) >= 0
- && line.stations.indexOf(realTimeDepartures
- .getDestination()) >= 0) {
- currentDeparture.setLine(line);
- break;
- }
- }
- } else {
- currentDeparture.setLine(Line.valueOf(currentValue));
- }
- } catch (IllegalArgumentException e) {
- Log.w(Constants.TAG, "There is no line called '" + currentValue
- + "'");
- }
- } else if (localName.equals("hexcolor")) {
- currentDeparture.setTrainDestinationColor("#ff"
- + currentValue.substring(1));
- } else if (localName.equals("bikeflag")) {
- currentDeparture.setBikeAllowed(currentValue.equalsIgnoreCase("1"));
- } else if (localName.equals("estimate")) {
- realTimeDepartures.addDeparture(currentDeparture);
- currentDeparture = null;
- } else if (localName.equals("etd")) {
- currentDestination = null;
- } else if (localName.equals("station")) {
- realTimeDepartures.finalizeDeparturesList();
- }
- isParsingTag = false;
- currentValue = null;
- }
-}
+package com.dougkeen.bart.networktasks;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import android.util.Log;
+
+import com.dougkeen.bart.model.Constants;
+import com.dougkeen.bart.model.Departure;
+import com.dougkeen.bart.model.Line;
+import com.dougkeen.bart.model.RealTimeDepartures;
+import com.dougkeen.bart.model.Route;
+import com.dougkeen.bart.model.Station;
+
+public class EtdContentHandler extends DefaultHandler {
+ public EtdContentHandler(Station origin, Station destination,
+ List routes) {
+ super();
+ realTimeDepartures = new RealTimeDepartures(origin, destination, routes);
+ }
+
+ private final static List TAGS = Arrays.asList("date", "time",
+ "abbreviation", "minutes", "platform", "direction", "length",
+ "color", "hexcolor", "bikeflag");
+
+ private RealTimeDepartures realTimeDepartures;
+
+ public RealTimeDepartures getRealTimeDepartures() {
+ return realTimeDepartures;
+ }
+
+ private String date;
+ private String currentDestination;
+ private String currentValue;
+ private Departure currentDeparture;
+ private boolean isParsingTag;
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (isParsingTag) {
+ currentValue = new String(ch, start, length);
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ if (TAGS.contains(localName)) {
+ isParsingTag = true;
+ }
+ if (localName.equals("estimate")) {
+ currentDeparture = new Departure();
+ currentDeparture.setTrainDestination(Station
+ .getByAbbreviation(currentDestination));
+ currentDeparture.setOrigin(realTimeDepartures.getOrigin());
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (localName.equals("date")) {
+ date = currentValue;
+ } else if (localName.equals("time")) {
+ realTimeDepartures.setTime(Date.parse(date + " " + currentValue));
+ } else if (localName.equals("abbreviation")) {
+ currentDestination = currentValue;
+ } else if (localName.equals("minutes")) {
+ if (StringUtils.isNumeric(currentValue)) {
+ currentDeparture.setMinutes(Integer.parseInt(currentValue));
+ } else {
+ currentDeparture.setMinutes(0);
+ }
+ } else if (localName.equals("platform")) {
+ currentDeparture.setPlatform(currentValue);
+ } else if (localName.equals("direction")) {
+ currentDeparture.setDirection(currentValue);
+ } else if (localName.equals("length")) {
+ currentDeparture.setTrainLength(currentValue);
+ } else if (localName.equals("color")) {
+ try {
+ if (currentValue.equalsIgnoreCase("WHITE")) {
+ for (Line line : Line.values()) {
+ if (line.stations.indexOf(currentDeparture
+ .getTrainDestination()) >= 0
+ && line.stations.indexOf(realTimeDepartures
+ .getDestination()) >= 0) {
+ currentDeparture.setLine(line);
+ break;
+ }
+ }
+ } else {
+ currentDeparture.setLine(Line.valueOf(currentValue));
+ }
+ } catch (IllegalArgumentException e) {
+ Log.w(Constants.TAG, "There is no line called '" + currentValue
+ + "'");
+ }
+ } else if (localName.equals("hexcolor")) {
+ currentDeparture.setTrainDestinationColor("#ff"
+ + currentValue.substring(1));
+ } else if (localName.equals("bikeflag")) {
+ currentDeparture.setBikeAllowed(currentValue.equalsIgnoreCase("1"));
+ } else if (localName.equals("estimate")) {
+ realTimeDepartures.addDeparture(currentDeparture);
+ currentDeparture = null;
+ } else if (localName.equals("etd")) {
+ currentDestination = null;
+ } else if (localName.equals("station")) {
+ realTimeDepartures.finalizeDeparturesList();
+ }
+ isParsingTag = false;
+ currentValue = null;
+ }
+}
diff --git a/src/com/dougkeen/bart/networktasks/FareContentHandler.java b/src/com/dougkeen/bart/networktasks/FareContentHandler.java
index fa1c0fb..54e7b72 100644
--- a/src/com/dougkeen/bart/networktasks/FareContentHandler.java
+++ b/src/com/dougkeen/bart/networktasks/FareContentHandler.java
@@ -1,46 +1,46 @@
-package com.dougkeen.bart.networktasks;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-public class FareContentHandler extends DefaultHandler {
- public FareContentHandler() {
- super();
- }
-
- private String currentValue;
- private boolean isParsingTag;
- private String fare;
-
- public String getFare() {
- return fare;
- }
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (isParsingTag) {
- currentValue = new String(ch, start, length);
- }
- }
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (localName.equals("fare")) {
- isParsingTag = true;
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if (localName.equals("fare")) {
- fare = "$" + currentValue;
- }
- isParsingTag = false;
- currentValue = null;
- }
-
-}
+package com.dougkeen.bart.networktasks;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class FareContentHandler extends DefaultHandler {
+ public FareContentHandler() {
+ super();
+ }
+
+ private String currentValue;
+ private boolean isParsingTag;
+ private String fare;
+
+ public String getFare() {
+ return fare;
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (isParsingTag) {
+ currentValue = new String(ch, start, length);
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ if (localName.equals("fare")) {
+ isParsingTag = true;
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (localName.equals("fare")) {
+ fare = "$" + currentValue;
+ }
+ isParsingTag = false;
+ currentValue = null;
+ }
+
+}
diff --git a/src/com/dougkeen/bart/networktasks/GetRealTimeDeparturesTask.java b/src/com/dougkeen/bart/networktasks/GetRealTimeDeparturesTask.java
index 9e1f003..36d42b9 100644
--- a/src/com/dougkeen/bart/networktasks/GetRealTimeDeparturesTask.java
+++ b/src/com/dougkeen/bart/networktasks/GetRealTimeDeparturesTask.java
@@ -1,153 +1,153 @@
-package com.dougkeen.bart.networktasks;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.util.List;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.Xml;
-
-import com.dougkeen.bart.model.Constants;
-import com.dougkeen.bart.model.RealTimeDepartures;
-import com.dougkeen.bart.model.Route;
-import com.dougkeen.bart.model.StationPair;
-
-public abstract class GetRealTimeDeparturesTask extends
- AsyncTask {
-
- private final static String ETD_URL = "http://api.bart.gov/api/etd.aspx?cmd=etd&key="
- + Constants.API_KEY + "&orig=%1$s&dir=%2$s";
- private final static String ETD_URL_NO_DIRECTION = "http://api.bart.gov/api/etd.aspx?cmd=etd&key="
- + Constants.API_KEY + "&orig=%1$s";
- private final static int MAX_ATTEMPTS = 5;
-
- private Exception mException;
-
- private List mRoutes;
-
- private final boolean ignoreDirection;
-
- public GetRealTimeDeparturesTask(boolean ignoreDirection) {
- super();
- this.ignoreDirection = ignoreDirection;
- }
-
- @Override
- protected RealTimeDepartures doInBackground(StationPair... paramsArray) {
- // Always expect one param
- StationPair params = paramsArray[0];
-
- mRoutes = params.getOrigin().getDirectRoutesForDestination(
- params.getDestination());
-
- boolean hasDirectLine = false;
- for (Route route : mRoutes) {
- if (!route.hasTransfer()) {
- hasDirectLine = true;
- break;
- }
- }
-
- if (mRoutes.isEmpty()
- || (params.getOrigin().transferFriendly && !hasDirectLine)) {
- mRoutes.addAll(params.getOrigin().getTransferRoutes(
- params.getDestination()));
- }
-
- if (!isCancelled()) {
- return getDeparturesFromNetwork(params, 0);
- } else {
- return null;
- }
- }
-
- private RealTimeDepartures getDeparturesFromNetwork(StationPair params,
- int attemptNumber) {
- String xml = null;
- try {
- String url;
- if (ignoreDirection || params.getOrigin().endOfLine) {
- url = String.format(ETD_URL_NO_DIRECTION,
- params.getOrigin().abbreviation);
- } else {
- url = String.format(ETD_URL, params.getOrigin().abbreviation,
- mRoutes.get(0).getDirection());
- }
-
- HttpUriRequest request = new HttpGet(url);
-
- EtdContentHandler handler = new EtdContentHandler(
- params.getOrigin(), params.getDestination(), mRoutes);
- if (isCancelled()) {
- return null;
- }
-
- HttpResponse response = NetworkUtils.executeWithRecovery(request);
-
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new IOException("Server returned "
- + response.getStatusLine().toString());
- }
-
- StringWriter writer = new StringWriter();
- IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
-
- xml = writer.toString();
- if (xml.length() == 0) {
- throw new IOException("Server returned blank xml document");
- }
-
- try {
- Xml.parse(xml, handler);
- } catch (Exception e) {
- mException = new IOException("Server returned malformed xml: "
- + xml);
- return null;
- }
- final RealTimeDepartures realTimeDepartures = handler
- .getRealTimeDepartures();
- return realTimeDepartures;
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- if (attemptNumber < MAX_ATTEMPTS - 1) {
- try {
- Log.w(Constants.TAG,
- "Attempt to contact server failed... retrying in 3s",
- e);
- Thread.sleep(3000);
- } catch (InterruptedException interrupt) {
- // Ignore... just go on to next attempt
- }
- return getDeparturesFromNetwork(params, attemptNumber + 1);
- } else {
- mException = new Exception("Could not contact BART system", e);
- return null;
- }
- }
- }
-
- @Override
- protected void onPostExecute(RealTimeDepartures result) {
- if (result != null) {
- onResult(result);
- } else {
- onError(mException);
- }
- }
-
- public abstract void onResult(RealTimeDepartures result);
-
- public abstract void onError(Exception exception);
-}
+package com.dougkeen.bart.networktasks;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+
+import android.os.AsyncTask;
+import android.util.Log;
+import android.util.Xml;
+
+import com.dougkeen.bart.model.Constants;
+import com.dougkeen.bart.model.RealTimeDepartures;
+import com.dougkeen.bart.model.Route;
+import com.dougkeen.bart.model.StationPair;
+
+public abstract class GetRealTimeDeparturesTask extends
+ AsyncTask {
+
+ private final static String ETD_URL = "http://api.bart.gov/api/etd.aspx?cmd=etd&key="
+ + Constants.API_KEY + "&orig=%1$s&dir=%2$s";
+ private final static String ETD_URL_NO_DIRECTION = "http://api.bart.gov/api/etd.aspx?cmd=etd&key="
+ + Constants.API_KEY + "&orig=%1$s";
+ private final static int MAX_ATTEMPTS = 5;
+
+ private Exception mException;
+
+ private List mRoutes;
+
+ private final boolean ignoreDirection;
+
+ public GetRealTimeDeparturesTask(boolean ignoreDirection) {
+ super();
+ this.ignoreDirection = ignoreDirection;
+ }
+
+ @Override
+ protected RealTimeDepartures doInBackground(StationPair... paramsArray) {
+ // Always expect one param
+ StationPair params = paramsArray[0];
+
+ mRoutes = params.getOrigin().getDirectRoutesForDestination(
+ params.getDestination());
+
+ boolean hasDirectLine = false;
+ for (Route route : mRoutes) {
+ if (!route.hasTransfer()) {
+ hasDirectLine = true;
+ break;
+ }
+ }
+
+ if (mRoutes.isEmpty()
+ || (params.getOrigin().transferFriendly && !hasDirectLine)) {
+ mRoutes.addAll(params.getOrigin().getTransferRoutes(
+ params.getDestination()));
+ }
+
+ if (!isCancelled()) {
+ return getDeparturesFromNetwork(params, 0);
+ } else {
+ return null;
+ }
+ }
+
+ private RealTimeDepartures getDeparturesFromNetwork(StationPair params,
+ int attemptNumber) {
+ String xml = null;
+ try {
+ String url;
+ if (ignoreDirection || params.getOrigin().endOfLine) {
+ url = String.format(ETD_URL_NO_DIRECTION,
+ params.getOrigin().abbreviation);
+ } else {
+ url = String.format(ETD_URL, params.getOrigin().abbreviation,
+ mRoutes.get(0).getDirection());
+ }
+
+ HttpUriRequest request = new HttpGet(url);
+
+ EtdContentHandler handler = new EtdContentHandler(
+ params.getOrigin(), params.getDestination(), mRoutes);
+ if (isCancelled()) {
+ return null;
+ }
+
+ HttpResponse response = NetworkUtils.executeWithRecovery(request);
+
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ throw new IOException("Server returned "
+ + response.getStatusLine().toString());
+ }
+
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
+
+ xml = writer.toString();
+ if (xml.length() == 0) {
+ throw new IOException("Server returned blank xml document");
+ }
+
+ try {
+ Xml.parse(xml, handler);
+ } catch (Exception e) {
+ mException = new IOException("Server returned malformed xml: "
+ + xml);
+ return null;
+ }
+ final RealTimeDepartures realTimeDepartures = handler
+ .getRealTimeDepartures();
+ return realTimeDepartures;
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ if (attemptNumber < MAX_ATTEMPTS - 1) {
+ try {
+ Log.w(Constants.TAG,
+ "Attempt to contact server failed... retrying in 3s",
+ e);
+ Thread.sleep(3000);
+ } catch (InterruptedException interrupt) {
+ // Ignore... just go on to next attempt
+ }
+ return getDeparturesFromNetwork(params, attemptNumber + 1);
+ } else {
+ mException = new Exception("Could not contact BART system", e);
+ return null;
+ }
+ }
+ }
+
+ @Override
+ protected void onPostExecute(RealTimeDepartures result) {
+ if (result != null) {
+ onResult(result);
+ } else {
+ onError(mException);
+ }
+ }
+
+ public abstract void onResult(RealTimeDepartures result);
+
+ public abstract void onError(Exception exception);
+}
diff --git a/src/com/dougkeen/bart/networktasks/GetRouteFareTask.java b/src/com/dougkeen/bart/networktasks/GetRouteFareTask.java
index 6b98bfe..363d9e2 100644
--- a/src/com/dougkeen/bart/networktasks/GetRouteFareTask.java
+++ b/src/com/dougkeen/bart/networktasks/GetRouteFareTask.java
@@ -1,125 +1,125 @@
-package com.dougkeen.bart.networktasks;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.xml.sax.SAXException;
-
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.Xml;
-
-import com.dougkeen.bart.model.Constants;
-import com.dougkeen.bart.model.Station;
-
-public abstract class GetRouteFareTask extends
- AsyncTask {
-
- private final static int MAX_ATTEMPTS = 5;
- private final static String FARE_URL = "http://api.bart.gov/api/sched.aspx?cmd=fare&date=today&key="
- + Constants.API_KEY + "&orig=%1$s&dest=%2$s";
-
- private Exception mException;
-
- private String fare;
-
- @Override
- protected String doInBackground(Params... paramsArray) {
- Params params = paramsArray[0];
-
- if (!isCancelled()) {
- return getFareFromNetwork(params, 0);
- } else {
- return null;
- }
- }
-
- private String getFareFromNetwork(Params params, int attemptNumber) {
- String xml = null;
-
- try {
- HttpUriRequest request = new HttpGet(
- String.format(FARE_URL, params.origin.abbreviation,
- params.destination.abbreviation));
-
- FareContentHandler handler = new FareContentHandler();
- if (isCancelled()) {
- return null;
- }
-
- HttpResponse response = NetworkUtils.executeWithRecovery(request);
-
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new IOException("Server returned "
- + response.getStatusLine().toString());
- }
-
- StringWriter writer = new StringWriter();
- IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
-
- xml = writer.toString();
- if (xml.length() == 0) {
- throw new IOException("Server returned blank xml document");
- }
-
- Xml.parse(xml, handler);
- fare = handler.getFare();
- return fare;
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- if (attemptNumber < MAX_ATTEMPTS - 1) {
- try {
- Log.w(Constants.TAG,
- "Attempt to contact server failed... retrying in 3s",
- e);
- Thread.sleep(3000);
- } catch (InterruptedException interrupt) {
- // Ignore... just go on to next attempt
- }
- return getFareFromNetwork(params, attemptNumber + 1);
- } else {
- mException = new Exception("Could not contact BART system", e);
- return null;
- }
- } catch (SAXException e) {
- mException = new Exception(
- "Could not understand response from BART system: " + xml, e);
- return null;
- }
- }
-
- public static class Params {
- public Params(Station origin, Station destination) {
- super();
- this.origin = origin;
- this.destination = destination;
- }
-
- public final Station origin;
- public final Station destination;
- }
-
- @Override
- protected void onPostExecute(String result) {
- if (result != null) {
- onResult(fare);
- } else {
- onError(mException);
- }
- }
-
- public abstract void onResult(String fare);
-
- public abstract void onError(Exception exception);
-
+package com.dougkeen.bart.networktasks;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.xml.sax.SAXException;
+
+import android.os.AsyncTask;
+import android.util.Log;
+import android.util.Xml;
+
+import com.dougkeen.bart.model.Constants;
+import com.dougkeen.bart.model.Station;
+
+public abstract class GetRouteFareTask extends
+ AsyncTask {
+
+ private final static int MAX_ATTEMPTS = 5;
+ private final static String FARE_URL = "http://api.bart.gov/api/sched.aspx?cmd=fare&date=today&key="
+ + Constants.API_KEY + "&orig=%1$s&dest=%2$s";
+
+ private Exception mException;
+
+ private String fare;
+
+ @Override
+ protected String doInBackground(Params... paramsArray) {
+ Params params = paramsArray[0];
+
+ if (!isCancelled()) {
+ return getFareFromNetwork(params, 0);
+ } else {
+ return null;
+ }
+ }
+
+ private String getFareFromNetwork(Params params, int attemptNumber) {
+ String xml = null;
+
+ try {
+ HttpUriRequest request = new HttpGet(
+ String.format(FARE_URL, params.origin.abbreviation,
+ params.destination.abbreviation));
+
+ FareContentHandler handler = new FareContentHandler();
+ if (isCancelled()) {
+ return null;
+ }
+
+ HttpResponse response = NetworkUtils.executeWithRecovery(request);
+
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ throw new IOException("Server returned "
+ + response.getStatusLine().toString());
+ }
+
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
+
+ xml = writer.toString();
+ if (xml.length() == 0) {
+ throw new IOException("Server returned blank xml document");
+ }
+
+ Xml.parse(xml, handler);
+ fare = handler.getFare();
+ return fare;
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ if (attemptNumber < MAX_ATTEMPTS - 1) {
+ try {
+ Log.w(Constants.TAG,
+ "Attempt to contact server failed... retrying in 3s",
+ e);
+ Thread.sleep(3000);
+ } catch (InterruptedException interrupt) {
+ // Ignore... just go on to next attempt
+ }
+ return getFareFromNetwork(params, attemptNumber + 1);
+ } else {
+ mException = new Exception("Could not contact BART system", e);
+ return null;
+ }
+ } catch (SAXException e) {
+ mException = new Exception(
+ "Could not understand response from BART system: " + xml, e);
+ return null;
+ }
+ }
+
+ public static class Params {
+ public Params(Station origin, Station destination) {
+ super();
+ this.origin = origin;
+ this.destination = destination;
+ }
+
+ public final Station origin;
+ public final Station destination;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ if (result != null) {
+ onResult(fare);
+ } else {
+ onError(mException);
+ }
+ }
+
+ public abstract void onResult(String fare);
+
+ public abstract void onError(Exception exception);
+
}
\ No newline at end of file
diff --git a/src/com/dougkeen/bart/networktasks/GetScheduleInformationTask.java b/src/com/dougkeen/bart/networktasks/GetScheduleInformationTask.java
index 7774385..5012195 100644
--- a/src/com/dougkeen/bart/networktasks/GetScheduleInformationTask.java
+++ b/src/com/dougkeen/bart/networktasks/GetScheduleInformationTask.java
@@ -1,118 +1,118 @@
-package com.dougkeen.bart.networktasks;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.xml.sax.SAXException;
-
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.Xml;
-
-import com.dougkeen.bart.model.Constants;
-import com.dougkeen.bart.model.ScheduleInformation;
-import com.dougkeen.bart.model.StationPair;
-
-public abstract class GetScheduleInformationTask extends
- AsyncTask {
-
- private final static String SCHED_URL = "http://api.bart.gov/api/sched.aspx?cmd=depart&key="
- + Constants.API_KEY + "&orig=%1$s&dest=%2$s&b=1&a=4";
-
- private final static int MAX_ATTEMPTS = 5;
-
- private Exception mException;
-
- @Override
- protected ScheduleInformation doInBackground(StationPair... paramsArray) {
- // Always expect one param
- StationPair params = paramsArray[0];
-
- if (!isCancelled()) {
- return getScheduleFromNetwork(params, 0);
- } else {
- return null;
- }
- }
-
- private ScheduleInformation getScheduleFromNetwork(StationPair params,
- int attemptNumber) {
- String xml = null;
- try {
- String url = String.format(SCHED_URL,
- params.getOrigin().abbreviation,
- params.getDestination().abbreviation);
-
- HttpUriRequest request = new HttpGet(url);
-
- if (isCancelled()) {
- return null;
- }
-
- ScheduleContentHandler handler = new ScheduleContentHandler(
- params.getOrigin(), params.getDestination());
-
- HttpResponse response = NetworkUtils.executeWithRecovery(request);
-
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new IOException("Server returned "
- + response.getStatusLine().toString());
- }
-
- StringWriter writer = new StringWriter();
- IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
-
- xml = writer.toString();
- if (xml.length() == 0) {
- throw new IOException("Server returned blank xml document");
- }
-
- Xml.parse(xml, handler);
- final ScheduleInformation schedule = handler.getSchedule();
- return schedule;
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- if (attemptNumber < MAX_ATTEMPTS - 1) {
- try {
- Log.w(Constants.TAG,
- "Attempt to contact server failed... retrying in 3s",
- e);
- Thread.sleep(3000);
- } catch (InterruptedException interrupt) {
- // Ignore... just go on to next attempt
- }
- return getScheduleFromNetwork(params, attemptNumber + 1);
- } else {
- mException = new Exception("Could not contact BART system", e);
- return null;
- }
- } catch (SAXException e) {
- mException = new Exception(
- "Could not understand response from BART system: " + xml, e);
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(ScheduleInformation result) {
- if (result != null) {
- onResult(result);
- } else {
- onError(mException);
- }
- }
-
- public abstract void onResult(ScheduleInformation result);
-
- public abstract void onError(Exception exception);
-}
+package com.dougkeen.bart.networktasks;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.xml.sax.SAXException;
+
+import android.os.AsyncTask;
+import android.util.Log;
+import android.util.Xml;
+
+import com.dougkeen.bart.model.Constants;
+import com.dougkeen.bart.model.ScheduleInformation;
+import com.dougkeen.bart.model.StationPair;
+
+public abstract class GetScheduleInformationTask extends
+ AsyncTask {
+
+ private final static String SCHED_URL = "http://api.bart.gov/api/sched.aspx?cmd=depart&key="
+ + Constants.API_KEY + "&orig=%1$s&dest=%2$s&b=1&a=4";
+
+ private final static int MAX_ATTEMPTS = 5;
+
+ private Exception mException;
+
+ @Override
+ protected ScheduleInformation doInBackground(StationPair... paramsArray) {
+ // Always expect one param
+ StationPair params = paramsArray[0];
+
+ if (!isCancelled()) {
+ return getScheduleFromNetwork(params, 0);
+ } else {
+ return null;
+ }
+ }
+
+ private ScheduleInformation getScheduleFromNetwork(StationPair params,
+ int attemptNumber) {
+ String xml = null;
+ try {
+ String url = String.format(SCHED_URL,
+ params.getOrigin().abbreviation,
+ params.getDestination().abbreviation);
+
+ HttpUriRequest request = new HttpGet(url);
+
+ if (isCancelled()) {
+ return null;
+ }
+
+ ScheduleContentHandler handler = new ScheduleContentHandler(
+ params.getOrigin(), params.getDestination());
+
+ HttpResponse response = NetworkUtils.executeWithRecovery(request);
+
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ throw new IOException("Server returned "
+ + response.getStatusLine().toString());
+ }
+
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(response.getEntity().getContent(), writer, "UTF-8");
+
+ xml = writer.toString();
+ if (xml.length() == 0) {
+ throw new IOException("Server returned blank xml document");
+ }
+
+ Xml.parse(xml, handler);
+ final ScheduleInformation schedule = handler.getSchedule();
+ return schedule;
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ if (attemptNumber < MAX_ATTEMPTS - 1) {
+ try {
+ Log.w(Constants.TAG,
+ "Attempt to contact server failed... retrying in 3s",
+ e);
+ Thread.sleep(3000);
+ } catch (InterruptedException interrupt) {
+ // Ignore... just go on to next attempt
+ }
+ return getScheduleFromNetwork(params, attemptNumber + 1);
+ } else {
+ mException = new Exception("Could not contact BART system", e);
+ return null;
+ }
+ } catch (SAXException e) {
+ mException = new Exception(
+ "Could not understand response from BART system: " + xml, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(ScheduleInformation result) {
+ if (result != null) {
+ onResult(result);
+ } else {
+ onError(mException);
+ }
+ }
+
+ public abstract void onResult(ScheduleInformation result);
+
+ public abstract void onError(Exception exception);
+}
diff --git a/src/com/dougkeen/bart/networktasks/NetworkUtils.java b/src/com/dougkeen/bart/networktasks/NetworkUtils.java
index 6d06981..6d8914f 100644
--- a/src/com/dougkeen/bart/networktasks/NetworkUtils.java
+++ b/src/com/dougkeen/bart/networktasks/NetworkUtils.java
@@ -1,38 +1,40 @@
-package com.dougkeen.bart.networktasks;
-
-import java.io.IOException;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.params.ConnManagerParams;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-
-public class NetworkUtils {
-
- public static HttpClient getHttpClient() {
- HttpClient client = new DefaultHttpClient();
- final HttpParams params = client.getParams();
- HttpConnectionParams.setConnectionTimeout(params,
- NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
- HttpConnectionParams.setSoTimeout(params, NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
- ConnManagerParams.setTimeout(params, NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
- return client;
- }
-
- public static HttpResponse executeWithRecovery(final HttpUriRequest request)
- throws IOException, ClientProtocolException {
- try {
- return getHttpClient().execute(request);
- } catch (IllegalStateException e) {
- // try again... this is a rare error
- return getHttpClient().execute(request);
- }
- }
-
- static final int CONNECTION_TIMEOUT_MILLIS = 10000;
-
-}
+package com.dougkeen.bart.networktasks;
+
+import java.io.IOException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.params.ConnManagerParams;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+public class NetworkUtils {
+
+ public static HttpClient getHttpClient() {
+ HttpClient client = new DefaultHttpClient();
+ final HttpParams params = client.getParams();
+ HttpConnectionParams.setConnectionTimeout(params,
+ NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
+ HttpConnectionParams.setSoTimeout(params,
+ NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
+ ConnManagerParams.setTimeout(params,
+ NetworkUtils.CONNECTION_TIMEOUT_MILLIS);
+ return client;
+ }
+
+ public static HttpResponse executeWithRecovery(final HttpUriRequest request)
+ throws IOException, ClientProtocolException {
+ try {
+ return getHttpClient().execute(request);
+ } catch (IllegalStateException e) {
+ // try again... this is a rare error
+ return getHttpClient().execute(request);
+ }
+ }
+
+ static final int CONNECTION_TIMEOUT_MILLIS = 10000;
+
+}
diff --git a/src/com/dougkeen/bart/networktasks/ScheduleContentHandler.java b/src/com/dougkeen/bart/networktasks/ScheduleContentHandler.java
index 074fa88..412c618 100644
--- a/src/com/dougkeen/bart/networktasks/ScheduleContentHandler.java
+++ b/src/com/dougkeen/bart/networktasks/ScheduleContentHandler.java
@@ -1,167 +1,167 @@
-package com.dougkeen.bart.networktasks;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.List;
-import java.util.TimeZone;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import android.util.Log;
-
-import com.dougkeen.bart.model.Constants;
-import com.dougkeen.bart.model.ScheduleInformation;
-import com.dougkeen.bart.model.ScheduleItem;
-import com.dougkeen.bart.model.Station;
-
-public class ScheduleContentHandler extends DefaultHandler {
- public ScheduleContentHandler(Station origin, Station destination) {
- super();
- schedule = new ScheduleInformation(origin, destination);
- }
-
- private final static List TAGS = Arrays.asList("date", "time",
- "trip", "leg");
-
- private final static DateFormat TRIP_DATE_FORMAT;
- private final static DateFormat REQUEST_DATE_FORMAT;
-
- private final static TimeZone PACIFIC_TIME = TimeZone
- .getTimeZone("America/Los_Angeles");
-
- static {
- TRIP_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy h:mm a");
- REQUEST_DATE_FORMAT = new SimpleDateFormat("MMM d, yyyy h:mm a");
-
- TRIP_DATE_FORMAT.setTimeZone(PACIFIC_TIME);
- REQUEST_DATE_FORMAT.setTimeZone(PACIFIC_TIME);
- }
-
- private ScheduleInformation schedule;
-
- public ScheduleInformation getSchedule() {
- return schedule;
- }
-
- private String currentValue;
- private boolean isParsingTag;
-
- private String requestDate;
- private String requestTime;
-
- private ScheduleItem currentTrip;
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (isParsingTag) {
- currentValue = new String(ch, start, length);
- }
- }
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (TAGS.contains(localName)) {
- isParsingTag = true;
- }
- final int numberOfAttributes = attributes.getLength();
- if (localName.equals("trip")) {
- currentTrip = new ScheduleItem();
- String originDate = null;
- String originTime = null;
- String destinationDate = null;
- String destinationTime = null;
- for (int i = 0; i < numberOfAttributes; i++) {
- if (attributes.getLocalName(i).equalsIgnoreCase("origin")) {
- currentTrip.setOrigin(Station.getByAbbreviation(attributes
- .getValue(i)));
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "destination")) {
- currentTrip.setDestination(Station
- .getByAbbreviation(attributes.getValue(i)));
- } else if (attributes.getLocalName(i).equalsIgnoreCase("fare")) {
- currentTrip.setFare(attributes.getValue(i));
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "origTimeMin")) {
- originTime = attributes.getValue(i);
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "origTimeDate")) {
- originDate = attributes.getValue(i);
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "destTimeMin")) {
- destinationTime = attributes.getValue(i);
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "destTimeDate")) {
- destinationDate = attributes.getValue(i);
- } else if (attributes.getLocalName(i).equalsIgnoreCase(
- "bikeFlag")) {
- currentTrip.setBikesAllowed(attributes.getValue(i).equals(
- "1"));
- }
- }
-
- long departTime = parseDate(TRIP_DATE_FORMAT, originDate,
- originTime);
- if (departTime > 0)
- currentTrip.setDepartureTime(departTime);
-
- long arriveTime = parseDate(TRIP_DATE_FORMAT, destinationDate,
- destinationTime);
- if (arriveTime > 0)
- currentTrip.setArrivalTime(arriveTime);
-
- schedule.addTrip(currentTrip);
- }
- if (localName.equals("leg")) {
- String legNumber = null;
- for (int i = 0; i < numberOfAttributes; i++) {
- if (attributes.getLocalName(i).equals("order")) {
- legNumber = attributes.getValue(i);
- } else if (attributes.getLocalName(i)
- .equals("trainHeadStation") && "1".equals(legNumber)) {
- currentTrip.setTrainHeadStation(attributes.getValue(i)
- .toLowerCase());
- }
- }
- }
- }
-
- private long parseDate(DateFormat format, String dateString,
- String timeString) {
- if (dateString == null || timeString == null) {
- return -1;
- }
- try {
- return format.parse(dateString + " " + timeString).getTime();
- } catch (ParseException e) {
- Log.e(Constants.TAG, "Unable to parse datetime '" + dateString
- + " " + timeString + "'", e);
- return -1;
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if (localName.equals("date")) {
- requestDate = currentValue;
- } else if (localName.equals("time")) {
- requestTime = currentValue;
- }
- isParsingTag = false;
- currentValue = null;
- }
-
- @Override
- public void endDocument() {
- long date = parseDate(REQUEST_DATE_FORMAT, requestDate, requestTime);
- if (date > 0) {
- schedule.setDate(date);
- }
- }
-}
+package com.dougkeen.bart.networktasks;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import android.util.Log;
+
+import com.dougkeen.bart.model.Constants;
+import com.dougkeen.bart.model.ScheduleInformation;
+import com.dougkeen.bart.model.ScheduleItem;
+import com.dougkeen.bart.model.Station;
+
+public class ScheduleContentHandler extends DefaultHandler {
+ public ScheduleContentHandler(Station origin, Station destination) {
+ super();
+ schedule = new ScheduleInformation(origin, destination);
+ }
+
+ private final static List TAGS = Arrays.asList("date", "time",
+ "trip", "leg");
+
+ private final static DateFormat TRIP_DATE_FORMAT;
+ private final static DateFormat REQUEST_DATE_FORMAT;
+
+ private final static TimeZone PACIFIC_TIME = TimeZone
+ .getTimeZone("America/Los_Angeles");
+
+ static {
+ TRIP_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy h:mm a");
+ REQUEST_DATE_FORMAT = new SimpleDateFormat("MMM d, yyyy h:mm a");
+
+ TRIP_DATE_FORMAT.setTimeZone(PACIFIC_TIME);
+ REQUEST_DATE_FORMAT.setTimeZone(PACIFIC_TIME);
+ }
+
+ private ScheduleInformation schedule;
+
+ public ScheduleInformation getSchedule() {
+ return schedule;
+ }
+
+ private String currentValue;
+ private boolean isParsingTag;
+
+ private String requestDate;
+ private String requestTime;
+
+ private ScheduleItem currentTrip;
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (isParsingTag) {
+ currentValue = new String(ch, start, length);
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ if (TAGS.contains(localName)) {
+ isParsingTag = true;
+ }
+ final int numberOfAttributes = attributes.getLength();
+ if (localName.equals("trip")) {
+ currentTrip = new ScheduleItem();
+ String originDate = null;
+ String originTime = null;
+ String destinationDate = null;
+ String destinationTime = null;
+ for (int i = 0; i < numberOfAttributes; i++) {
+ if (attributes.getLocalName(i).equalsIgnoreCase("origin")) {
+ currentTrip.setOrigin(Station.getByAbbreviation(attributes
+ .getValue(i)));
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "destination")) {
+ currentTrip.setDestination(Station
+ .getByAbbreviation(attributes.getValue(i)));
+ } else if (attributes.getLocalName(i).equalsIgnoreCase("fare")) {
+ currentTrip.setFare(attributes.getValue(i));
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "origTimeMin")) {
+ originTime = attributes.getValue(i);
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "origTimeDate")) {
+ originDate = attributes.getValue(i);
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "destTimeMin")) {
+ destinationTime = attributes.getValue(i);
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "destTimeDate")) {
+ destinationDate = attributes.getValue(i);
+ } else if (attributes.getLocalName(i).equalsIgnoreCase(
+ "bikeFlag")) {
+ currentTrip.setBikesAllowed(attributes.getValue(i).equals(
+ "1"));
+ }
+ }
+
+ long departTime = parseDate(TRIP_DATE_FORMAT, originDate,
+ originTime);
+ if (departTime > 0)
+ currentTrip.setDepartureTime(departTime);
+
+ long arriveTime = parseDate(TRIP_DATE_FORMAT, destinationDate,
+ destinationTime);
+ if (arriveTime > 0)
+ currentTrip.setArrivalTime(arriveTime);
+
+ schedule.addTrip(currentTrip);
+ }
+ if (localName.equals("leg")) {
+ String legNumber = null;
+ for (int i = 0; i < numberOfAttributes; i++) {
+ if (attributes.getLocalName(i).equals("order")) {
+ legNumber = attributes.getValue(i);
+ } else if (attributes.getLocalName(i)
+ .equals("trainHeadStation") && "1".equals(legNumber)) {
+ currentTrip.setTrainHeadStation(attributes.getValue(i)
+ .toLowerCase());
+ }
+ }
+ }
+ }
+
+ private long parseDate(DateFormat format, String dateString,
+ String timeString) {
+ if (dateString == null || timeString == null) {
+ return -1;
+ }
+ try {
+ return format.parse(dateString + " " + timeString).getTime();
+ } catch (ParseException e) {
+ Log.e(Constants.TAG, "Unable to parse datetime '" + dateString
+ + " " + timeString + "'", e);
+ return -1;
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (localName.equals("date")) {
+ requestDate = currentValue;
+ } else if (localName.equals("time")) {
+ requestTime = currentValue;
+ }
+ isParsingTag = false;
+ currentValue = null;
+ }
+
+ @Override
+ public void endDocument() {
+ long date = parseDate(REQUEST_DATE_FORMAT, requestDate, requestTime);
+ if (date > 0) {
+ schedule.setDate(date);
+ }
+ }
+}
diff --git a/src/com/dougkeen/bart/receivers/AlarmBroadcastReceiver.java b/src/com/dougkeen/bart/receivers/AlarmBroadcastReceiver.java
index 0ecd8f3..4fb6826 100644
--- a/src/com/dougkeen/bart/receivers/AlarmBroadcastReceiver.java
+++ b/src/com/dougkeen/bart/receivers/AlarmBroadcastReceiver.java
@@ -24,7 +24,8 @@ public class AlarmBroadcastReceiver extends BroadcastReceiver {
application.setPlayAlarmRingtone(true);
- Intent targetIntent = new Intent(Intent.ACTION_VIEW, boardedDeparture.getStationPair().getUri());
+ Intent targetIntent = new Intent(Intent.ACTION_VIEW, boardedDeparture
+ .getStationPair().getUri());
targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(targetIntent);