Changed "departed" to "leaving". Abstracted out string value.
This commit is contained in:
parent
f5ba6d27cc
commit
8955bd209b
@ -42,5 +42,6 @@
|
||||
<string name="silence_alarm">Silence alarm</string>
|
||||
<string name="cancel_alarm">Cancel alarm</string>
|
||||
<string name="set_alarm">Set alarm</string>
|
||||
<string name="leaving">Leaving</string>
|
||||
|
||||
</resources>
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
/**
|
||||
|
@ -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<TickSubscriber, Object> mSubscribers;
|
||||
|
||||
private WeakHashMap<Context, Object> 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<TickSubscriber> 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<TickSubscriber, Object>();
|
||||
mTickerHosts = new WeakHashMap<Context, Object>();
|
||||
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<TickSubscriber, Object> mSubscribers;
|
||||
|
||||
private WeakHashMap<Context, Object> 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<TickSubscriber> 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<TickSubscriber, Object>();
|
||||
mTickerHosts = new WeakHashMap<Context, Object>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<String, String> 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<String, String>();
|
||||
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<String, String> 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<String, String>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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<String> 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<String> getColumns(SQLiteDatabase db, String tableName) {
|
||||
List<String> ar = null;
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.rawQuery("select * from " + tableName + " limit 1", null);
|
||||
if (c != null) {
|
||||
ar = new ArrayList<String>(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<String> 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<String> 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<String> getColumns(SQLiteDatabase db, String tableName) {
|
||||
List<String> ar = null;
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.rawQuery("select * from " + tableName + " limit 1", null);
|
||||
if (c != null) {
|
||||
ar = new ArrayList<String>(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<String> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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<Station> 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<Line> getLinesForStation(Station station) {
|
||||
Collection<Line> lines = new ArrayList<Line>();
|
||||
for (Line line : Line.values()) {
|
||||
if (line.stations.contains(station)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static Collection<Line> getLinesWithStations(Station station1, Station station2) {
|
||||
Collection<Line> lines = new ArrayList<Line>();
|
||||
for (Line line : Line.values()) {
|
||||
if (line.stations.contains(station1) && line.stations.contains(station2)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static Set<Station> getPotentialDestinations(Station station) {
|
||||
Set<Station> destinations = new TreeSet<Station>();
|
||||
|
||||
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<Station> 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<Line> getLinesForStation(Station station) {
|
||||
Collection<Line> lines = new ArrayList<Line>();
|
||||
for (Line line : Line.values()) {
|
||||
if (line.stations.contains(station)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static Collection<Line> getLinesWithStations(Station station1,
|
||||
Station station2) {
|
||||
Collection<Line> lines = new ArrayList<Line>();
|
||||
for (Line line : Line.values()) {
|
||||
if (line.stations.contains(station1)
|
||||
&& line.stations.contains(station2)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static Set<Station> getPotentialDestinations(Station station) {
|
||||
Set<Station> destinations = new TreeSet<Station>();
|
||||
|
||||
for (Line line : getLinesForStation(station)) {
|
||||
destinations.addAll(line.stations);
|
||||
}
|
||||
|
||||
destinations.remove(station);
|
||||
|
||||
return destinations;
|
||||
}
|
||||
}
|
||||
|
@ -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<Route> routes) {
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
this.routes = routes;
|
||||
this.unfilteredDepartures = new ArrayList<Departure>();
|
||||
}
|
||||
|
||||
private Station origin;
|
||||
private Station destination;
|
||||
private long time;
|
||||
|
||||
private List<Departure> departures;
|
||||
|
||||
final private List<Departure> unfilteredDepartures;
|
||||
|
||||
private List<Route> 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<Departure> getDepartures() {
|
||||
if (departures == null) {
|
||||
departures = new ArrayList<Departure>();
|
||||
}
|
||||
return departures;
|
||||
}
|
||||
|
||||
public void setDepartures(List<Departure> 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<Departure> 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<Route> getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
|
||||
public void setRoutes(List<Route> 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<Route> routes) {
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
this.routes = routes;
|
||||
this.unfilteredDepartures = new ArrayList<Departure>();
|
||||
}
|
||||
|
||||
private Station origin;
|
||||
private Station destination;
|
||||
private long time;
|
||||
|
||||
private List<Departure> departures;
|
||||
|
||||
final private List<Departure> unfilteredDepartures;
|
||||
|
||||
private List<Route> 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<Departure> getDepartures() {
|
||||
if (departures == null) {
|
||||
departures = new ArrayList<Departure>();
|
||||
}
|
||||
return departures;
|
||||
}
|
||||
|
||||
public void setDepartures(List<Departure> 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<Departure> 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<Route> getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
|
||||
public void setRoutes(List<Route> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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<Line> 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<Line> getTransferLines() {
|
||||
return transferLines;
|
||||
}
|
||||
|
||||
public void setTransferLines(Collection<Line> 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<Line> 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<Line> getTransferLines() {
|
||||
return transferLines;
|
||||
}
|
||||
|
||||
public void setTransferLines(Collection<Line> 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ScheduleItem> 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<ScheduleItem> getTrips() {
|
||||
if (trips == null) {
|
||||
trips = new ArrayList<ScheduleItem>();
|
||||
}
|
||||
return trips;
|
||||
}
|
||||
|
||||
public void setTrips(List<ScheduleItem> 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<ScheduleItem> 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<ScheduleItem> getTrips() {
|
||||
if (trips == null) {
|
||||
trips = new ArrayList<ScheduleItem>();
|
||||
}
|
||||
return trips;
|
||||
}
|
||||
|
||||
public void setTrips(List<ScheduleItem> 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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Route> getDirectRoutesForDestination(Station dest) {
|
||||
return getDirectRoutesForDestination(this, dest, null, null);
|
||||
}
|
||||
|
||||
public List<Route> getDirectRoutesForDestination(Station origin,
|
||||
Station dest, Station transferStation,
|
||||
Collection<Line> transferLines) {
|
||||
if (dest == null)
|
||||
return null;
|
||||
Boolean isNorth = null;
|
||||
List<Route> returnList = new ArrayList<Route>();
|
||||
final Collection<Line> 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<Route> getTransferRoutes(Station dest) {
|
||||
List<Route> returnList = new ArrayList<Route>();
|
||||
|
||||
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<Line> outboundTransferLines = Line
|
||||
.getLinesWithStations(this, getOutboundTransferStation());
|
||||
final List<Route> 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<Route> routesForDestination = getDoubleTransferRoutes(dest);
|
||||
if (routesForDestination != null && !routesForDestination.isEmpty()) {
|
||||
returnList.addAll(routesForDestination);
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<Route> getDoubleTransferRoutes(Station dest) {
|
||||
if (getOutboundTransferStation() == null
|
||||
|| dest.getInboundTransferStation() == null)
|
||||
return new ArrayList<Route>();
|
||||
|
||||
// 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<Station> getStationList() {
|
||||
List<Station> list = new ArrayList<Station>();
|
||||
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<Route> getDirectRoutesForDestination(Station dest) {
|
||||
return getDirectRoutesForDestination(this, dest, null, null);
|
||||
}
|
||||
|
||||
public List<Route> getDirectRoutesForDestination(Station origin,
|
||||
Station dest, Station transferStation,
|
||||
Collection<Line> transferLines) {
|
||||
if (dest == null)
|
||||
return null;
|
||||
Boolean isNorth = null;
|
||||
List<Route> returnList = new ArrayList<Route>();
|
||||
final Collection<Line> 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<Route> getTransferRoutes(Station dest) {
|
||||
List<Route> returnList = new ArrayList<Route>();
|
||||
|
||||
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<Line> outboundTransferLines = Line
|
||||
.getLinesWithStations(this, getOutboundTransferStation());
|
||||
final List<Route> 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<Route> routesForDestination = getDoubleTransferRoutes(dest);
|
||||
if (routesForDestination != null && !routesForDestination.isEmpty()) {
|
||||
returnList.addAll(routesForDestination);
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<Route> getDoubleTransferRoutes(Station dest) {
|
||||
if (getOutboundTransferStation() == null
|
||||
|| dest.getInboundTransferStation() == null)
|
||||
return new ArrayList<Route>();
|
||||
|
||||
// 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<Station> getStationList() {
|
||||
List<Station> list = new ArrayList<Station>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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<StationPair> CREATOR = new Parcelable.Creator<StationPair>() {
|
||||
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<StationPair> CREATOR = new Parcelable.Creator<StationPair>() {
|
||||
public StationPair createFromParcel(Parcel in) {
|
||||
return new StationPair(in);
|
||||
}
|
||||
|
||||
public StationPair[] newArray(int size) {
|
||||
return new StationPair[size];
|
||||
}
|
||||
};
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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<Route> routes) {
|
||||
super();
|
||||
realTimeDepartures = new RealTimeDepartures(origin, destination, routes);
|
||||
}
|
||||
|
||||
private final static List<String> 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<Route> routes) {
|
||||
super();
|
||||
realTimeDepartures = new RealTimeDepartures(origin, destination, routes);
|
||||
}
|
||||
|
||||
private final static List<String> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<StationPair, Integer, RealTimeDepartures> {
|
||||
|
||||
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<Route> 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<StationPair, Integer, RealTimeDepartures> {
|
||||
|
||||
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<Route> 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);
|
||||
}
|
||||
|
@ -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<GetRouteFareTask.Params, Integer, String> {
|
||||
|
||||
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<GetRouteFareTask.Params, Integer, String> {
|
||||
|
||||
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);
|
||||
|
||||
}
|
@ -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<StationPair, Integer, ScheduleInformation> {
|
||||
|
||||
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<StationPair, Integer, ScheduleInformation> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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<String> 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<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user