code format

This commit is contained in:
Steffen Horlacher
2010-05-23 11:26:41 +02:00
parent 2b56acf164
commit 9a2f028843
3 changed files with 454 additions and 455 deletions
@@ -950,46 +950,46 @@ public class MyTracks extends TabActivity implements OnTouchListener,
showDialogSafely(DIALOG_IMPORT_PROGRESS); showDialogSafely(DIALOG_IMPORT_PROGRESS);
Thread t = new Thread() { Thread t = new Thread() {
@Override @Override
public void run() { public void run() {
int message = R.string.success; int message = R.string.success;
long[] trackIdsImported = null; long[] trackIdsImported = null;
try { try {
try { try {
InputStream is = new FileInputStream(fileName); InputStream is = new FileInputStream(fileName);
trackIdsImported = GpxSaxImporter.importGPXFile(is, providerUtils); trackIdsImported = GpxSaxImporter.importGPXFile(is, providerUtils);
} catch (SAXException e) { } catch (SAXException e) {
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e); Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
message = R.string.error_generic; message = R.string.error_generic;
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e); Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
message = R.string.error_generic; message = R.string.error_generic;
} catch (IOException e) { } catch (IOException e) {
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e); Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
message = R.string.error_unable_to_read_file; message = R.string.error_unable_to_read_file;
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e); Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
message = R.string.error_invalid_gpx_format; message = R.string.error_invalid_gpx_format;
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e); Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
message = R.string.error_out_of_memory; message = R.string.error_out_of_memory;
} }
if (trackIdsImported != null && trackIdsImported.length > 0) { if (trackIdsImported != null && trackIdsImported.length > 0) {
// select last track from import file // select last track from import file
setSelectedTrack(trackIdsImported[trackIdsImported.length - 1]); setSelectedTrack(trackIdsImported[trackIdsImported.length - 1]);
} else { } else {
MyTracks.this.showMessageDialog(message, false/* success */); MyTracks.this.showMessageDialog(message, false/* success */);
} }
} finally { } finally {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
dismissDialog(DIALOG_IMPORT_PROGRESS); dismissDialog(DIALOG_IMPORT_PROGRESS);
} }
}); });
} }
} }
}; };
t.start(); t.start();
} }
@@ -47,384 +47,384 @@ import com.google.android.apps.mytracks.util.MyTracksUtils;
*/ */
public class GpxSaxImporter extends DefaultHandler { public class GpxSaxImporter extends DefaultHandler {
/** /**
* Different data formats used in GPX files * Different data formats used in GPX files
*/ */
private static final SimpleDateFormat DATE_FORMAT1 = new SimpleDateFormat( private static final SimpleDateFormat DATE_FORMAT1 = new SimpleDateFormat(
"yyyy-MM-dd'T'hh:mm:ssZ"); "yyyy-MM-dd'T'hh:mm:ssZ");
private static final SimpleDateFormat DATE_FORMAT2 = new SimpleDateFormat( private static final SimpleDateFormat DATE_FORMAT2 = new SimpleDateFormat(
"yyyy-MM-dd'T'hh:mm:ss'Z'"); "yyyy-MM-dd'T'hh:mm:ss'Z'");
private static final SimpleDateFormat DATE_FORMAT3 = new SimpleDateFormat( private static final SimpleDateFormat DATE_FORMAT3 = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"); "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
/** /**
* GPX-XML tag names and attributes * GPX-XML tag names and attributes
*/ */
private static final String TAG_TRACK = "trk"; private static final String TAG_TRACK = "trk";
private static final String TAG_TRACK_POINT = "trkpt"; private static final String TAG_TRACK_POINT = "trkpt";
private static final String TAG_NAME = "name"; private static final String TAG_NAME = "name";
private static final String TAG_DESCRIPTION = "desc"; private static final String TAG_DESCRIPTION = "desc";
private static final String TAG_ALTITUDE = "ele"; private static final String TAG_ALTITUDE = "ele";
private static final String TAG_TIME = "time"; private static final String TAG_TIME = "time";
private static final String ATT_LAT = "lat"; private static final String ATT_LAT = "lat";
private static final String ATT_LON = "lon"; private static final String ATT_LON = "lon";
/** /**
* Contains the current elements content * Contains the current elements content
*/ */
private StringBuilder content; private StringBuilder content;
/** /**
* Currently reading location * Currently reading location
*/ */
private Location location; private Location location;
/** /**
* Previous location, required for calculations * Previous location, required for calculations
*/ */
private Location lastLocation; private Location lastLocation;
/** /**
* Currently reading track * Currently reading track
*/ */
private Track track; private Track track;
/** /**
* Statistics object for the current track * Statistics object for the current track
*/ */
private TripStatistics stats; private TripStatistics stats;
/** /**
* Number of locations already processed * Number of locations already processed
*/ */
private int numberOfLocations; private int numberOfLocations;
/** /**
* List of track ids written in the database does only contain successful * List of track ids written in the database does only contain successful
* finished ones * finished ones
*/ */
private List<Long> tracksWritten; private List<Long> tracksWritten;
/** /**
* used to identify if a track was written to the database but not yet finish * used to identify if a track was written to the database but not yet finish
* successfully * successfully
*/ */
private boolean isCurrentTrackRollbackable; private boolean isCurrentTrackRollbackable;
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
/** /**
* flag to indicate if we in a track xml element some sub elements like name * flag to indicate if we in a track xml element some sub elements like name
* may be used in other parts of the gpx file - ignore them * may be used in other parts of the gpx file - ignore them
*/ */
private boolean isInTrackElement; private boolean isInTrackElement;
/** /**
* Reads GPS tracks from a GPX file and append tracks and their coordinates to * Reads GPS tracks from a GPX file and append tracks and their coordinates to
* the given list of tracks. * the given list of tracks.
* *
* Callers must execute * Callers must execute
* *
* <pre> * <pre>
* rollbackUnfinishedTrack * rollbackUnfinishedTrack
* </pre> * </pre>
* *
* in case of an exception to avoid inconsistent data * in case of an exception to avoid inconsistent data
* *
* @param tracks * @param tracks
* a list of tracks * a list of tracks
* @param is * @param is
* a input steam with gpx-xml data * a input steam with gpx-xml data
* @throws SAXException * @throws SAXException
* a parsing error * a parsing error
* @throws ParserConfigurationException * @throws ParserConfigurationException
* internal error * internal error
* @throws IOException * @throws IOException
* a file reading problem * a file reading problem
*/ */
public static long[] importGPXFile(final InputStream is, public static long[] importGPXFile(final InputStream is,
final MyTracksProviderUtils providerUtils) final MyTracksProviderUtils providerUtils)
throws ParserConfigurationException, SAXException, IOException { throws ParserConfigurationException, SAXException, IOException {
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParserFactory factory = SAXParserFactory.newInstance();
GpxSaxImporter handler = new GpxSaxImporter(providerUtils); GpxSaxImporter handler = new GpxSaxImporter(providerUtils);
SAXParser parser = factory.newSAXParser(); SAXParser parser = factory.newSAXParser();
long[] trackIds = null; long[] trackIds = null;
try { try {
parser.parse(is, handler); parser.parse(is, handler);
trackIds = handler.getImportedTrackIds(); trackIds = handler.getImportedTrackIds();
} finally { } finally {
// delete track if not finished // delete track if not finished
handler.rollbackUnfinishedTracks(); handler.rollbackUnfinishedTracks();
} }
return trackIds; return trackIds;
} }
/** /**
* Constructor, requires providerUtils for writing tracks the database. * Constructor, requires providerUtils for writing tracks the database.
*/ */
public GpxSaxImporter(MyTracksProviderUtils providerUtils) { public GpxSaxImporter(MyTracksProviderUtils providerUtils) {
this.providerUtils = providerUtils; this.providerUtils = providerUtils;
tracksWritten = new ArrayList<Long>(); tracksWritten = new ArrayList<Long>();
content = new StringBuilder(); content = new StringBuilder();
} }
@Override @Override
public void characters(char[] ch, int start, int length) throws SAXException { public void characters(char[] ch, int start, int length) throws SAXException {
content.append(ch, start, length); content.append(ch, start, length);
} }
@Override @Override
public void startElement(String uri, String localName, String name, public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException { Attributes attributes) throws SAXException {
if (localName.equalsIgnoreCase(TAG_TRACK)) { if (localName.equalsIgnoreCase(TAG_TRACK)) {
isInTrackElement = true; isInTrackElement = true;
onTrackElementStart(); onTrackElementStart();
// process this element only as sub-elements of track // process this element only as sub-elements of track
} else if (isInTrackElement) { } else if (isInTrackElement) {
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) { if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
onTrackPointElementStart(attributes); onTrackPointElementStart(attributes);
} }
} }
} }
@Override @Override
public void endElement(String uri, String localName, String name) public void endElement(String uri, String localName, String name)
throws SAXException { throws SAXException {
if (localName.equalsIgnoreCase(TAG_TRACK)) { if (localName.equalsIgnoreCase(TAG_TRACK)) {
onTrackElementEnd(); onTrackElementEnd();
isInTrackElement = false; isInTrackElement = false;
// process these elements only as sub-elements of track // process these elements only as sub-elements of track
} else if (isInTrackElement) { } else if (isInTrackElement) {
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) { if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
onTrackPointElementEnd(); onTrackPointElementEnd();
} else if (localName.equalsIgnoreCase(TAG_ALTITUDE)) { } else if (localName.equalsIgnoreCase(TAG_ALTITUDE)) {
onAltitudeElementEnd(); onAltitudeElementEnd();
} else if (localName.equalsIgnoreCase(TAG_TIME)) { } else if (localName.equalsIgnoreCase(TAG_TIME)) {
onTimeElementEnd(); onTimeElementEnd();
} else if (localName.equalsIgnoreCase(TAG_NAME)) { } else if (localName.equalsIgnoreCase(TAG_NAME)) {
onNameElementEnd(); onNameElementEnd();
} else if (localName.equalsIgnoreCase(TAG_DESCRIPTION)) { } else if (localName.equalsIgnoreCase(TAG_DESCRIPTION)) {
onDescriptionElementEnd(); onDescriptionElementEnd();
} }
} }
// reset element content // reset element content
content.setLength(0); content.setLength(0);
} }
/** /**
* Create a new Track object and insert empty track in database. Track will be * Create a new Track object and insert empty track in database. Track will be
* updated with missing values later. * updated with missing values later.
*/ */
private void onTrackElementStart() { private void onTrackElementStart() {
track = new Track(); track = new Track();
numberOfLocations = 0; numberOfLocations = 0;
Uri trackUri = providerUtils.insertTrack(track); Uri trackUri = providerUtils.insertTrack(track);
long trackId = Long.parseLong(trackUri.getLastPathSegment()); long trackId = Long.parseLong(trackUri.getLastPathSegment());
track.setId(trackId); track.setId(trackId);
isCurrentTrackRollbackable = true; isCurrentTrackRollbackable = true;
} }
/** /**
* Reads trackpoint attributes and assigns them to the current location * Reads trackpoint attributes and assigns them to the current location
* *
* @param attributes * @param attributes
* xml attributes * xml attributes
*/ */
private void onTrackPointElementStart(Attributes attributes) { private void onTrackPointElementStart(Attributes attributes) {
location = createLocationFromAttributes(attributes); location = createLocationFromAttributes(attributes);
} }
private Location createLocationFromAttributes(Attributes attributes) { private Location createLocationFromAttributes(Attributes attributes) {
String latitude = null; String latitude = null;
String longitude = null; String longitude = null;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
if (attributes.getLocalName(i).equals(ATT_LAT)) { if (attributes.getLocalName(i).equals(ATT_LAT)) {
latitude = attributes.getValue(i); latitude = attributes.getValue(i);
} else if (attributes.getLocalName(i).equals(ATT_LON)) { } else if (attributes.getLocalName(i).equals(ATT_LON)) {
longitude = attributes.getValue(i); longitude = attributes.getValue(i);
} }
} }
// create new location and set attributes // create new location and set attributes
Location loc = new Location(LocationManager.GPS_PROVIDER); Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(Double.parseDouble(latitude)); loc.setLatitude(Double.parseDouble(latitude));
loc.setLongitude(Double.parseDouble(longitude)); loc.setLongitude(Double.parseDouble(longitude));
return loc; return loc;
} }
private void onDescriptionElementEnd() { private void onDescriptionElementEnd() {
track.setDescription(content.toString().trim()); track.setDescription(content.toString().trim());
} }
private void onNameElementEnd() { private void onNameElementEnd() {
track.setName(content.toString().trim()); track.setName(content.toString().trim());
} }
/** /**
* Track point finished, write in database * Track point finished, write in database
*/ */
private void onTrackPointElementEnd() { private void onTrackPointElementEnd() {
if (MyTracksUtils.isValidLocation(location)) { if (MyTracksUtils.isValidLocation(location)) {
stats.addLocation(location, location.getTime()); stats.addLocation(location, location.getTime());
// insert in db // insert in db
Uri trackPointIdUri = providerUtils.insertTrackPoint(location, track Uri trackPointIdUri = providerUtils.insertTrackPoint(location, track
.getId()); .getId());
// set start and stop id for track // set start and stop id for track
long trackPointId = Long.parseLong(trackPointIdUri.getLastPathSegment()); long trackPointId = Long.parseLong(trackPointIdUri.getLastPathSegment());
// first track point? // first track point?
if (lastLocation == null) { if (lastLocation == null) {
track.setStartId(trackPointId); track.setStartId(trackPointId);
} }
// location has no setId method // location has no setId method
// updating stop id on track every time... // updating stop id on track every time...
track.setStopId(trackPointId); track.setStopId(trackPointId);
lastLocation = location; lastLocation = location;
numberOfLocations++; numberOfLocations++;
} }
} }
/** /**
* Track finished - update in database * Track finished - update in database
*/ */
private void onTrackElementEnd() { private void onTrackElementEnd() {
if (lastLocation != null) { if (lastLocation != null) {
// Calculate statistics for the imported track and update // Calculate statistics for the imported track and update
stats.pauseAt(lastLocation.getTime()); stats.pauseAt(lastLocation.getTime());
track.setStopTime(lastLocation.getTime()); track.setStopTime(lastLocation.getTime());
track.setNumberOfPoints(numberOfLocations); track.setNumberOfPoints(numberOfLocations);
stats.fillStatisticsForTrack(track); stats.fillStatisticsForTrack(track);
providerUtils.updateTrack(track); providerUtils.updateTrack(track);
tracksWritten.add(new Long(track.getId())); tracksWritten.add(new Long(track.getId()));
} else { } else {
// track contains no track points makes not really // track contains no track points makes not really
// sense to import it as we have no location // sense to import it as we have no location
// information -> roll back // information -> roll back
rollbackUnfinishedTracks(); rollbackUnfinishedTracks();
} }
isCurrentTrackRollbackable = false; isCurrentTrackRollbackable = false;
} }
/** /**
* setting time and doing additional calculations as this is the last value * setting time and doing additional calculations as this is the last value
* required. Also sets the start time for track and statistics as there is no * required. Also sets the start time for track and statistics as there is no
* start time in the track root element * start time in the track root element
*/ */
private void onTimeElementEnd() { private void onTimeElementEnd() {
long time = parseTimeForAllFormats(content.toString().trim()); long time = parseTimeForAllFormats(content.toString().trim());
if (location != null) { if (location != null) {
location.setTime(time); location.setTime(time);
// initialize start time with time of first track point // initialize start time with time of first track point
if (stats == null) { if (stats == null) {
stats = new TripStatistics(time); stats = new TripStatistics(time);
track.setStartTime(time); track.setStartTime(time);
} }
// We don't have a speed and bearing in GPX, make // We don't have a speed and bearing in GPX, make
// something up from // something up from
// the last two points: // the last two points:
if (lastLocation != null) { if (lastLocation != null) {
final long dt = location.getTime() - lastLocation.getTime(); final long dt = location.getTime() - lastLocation.getTime();
if (dt > 0) { if (dt > 0) {
final float speed = location.distanceTo(lastLocation) / (dt / 1000); final float speed = location.distanceTo(lastLocation) / (dt / 1000);
location.setSpeed(speed); location.setSpeed(speed);
} }
location.setBearing(lastLocation.bearingTo(location)); location.setBearing(lastLocation.bearingTo(location));
} }
} }
} }
private void onAltitudeElementEnd() { private void onAltitudeElementEnd() {
if (location != null) { if (location != null) {
String altitude = content.toString().trim(); String altitude = content.toString().trim();
// make altitude optional // make altitude optional
if (altitude != null) { if (altitude != null) {
location.setAltitude(Double.parseDouble(altitude)); location.setAltitude(Double.parseDouble(altitude));
} }
} }
} }
/** /**
* If a exception is thrown during the import callers must execute this method * If a exception is thrown during the import callers must execute this method
* in the catch clause to avoid inconsistent data * in the catch clause to avoid inconsistent data
*/ */
public void rollbackUnfinishedTracks() { public void rollbackUnfinishedTracks() {
if (isCurrentTrackRollbackable) { if (isCurrentTrackRollbackable) {
providerUtils.deleteTrack(track.getId()); providerUtils.deleteTrack(track.getId());
} }
} }
/** /**
* Get all track ids of the tracks created by this importer run * Get all track ids of the tracks created by this importer run
* *
* @return array of track ids * @return array of track ids
*/ */
private long[] getImportedTrackIds() { private long[] getImportedTrackIds() {
// Convert from java.lang.Long for convenience // Convert from java.lang.Long for convenience
long[] result = new long[tracksWritten.size()]; long[] result = new long[tracksWritten.size()];
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
result[i] = tracksWritten.get(i); result[i] = tracksWritten.get(i);
} }
return result; return result;
} }
/** /**
* Parse time trying different formats used in GPX files * Parse time trying different formats used in GPX files
* *
* @param timeContents * @param timeContents
* string with time infomation * string with time infomation
* @return time as long * @return time as long
*/ */
private long parseTimeForAllFormats(String timeContents) { private long parseTimeForAllFormats(String timeContents) {
long t = -1; long t = -1;
try { try {
// 1st try with time zone at end a la "+0000" // 1st try with time zone at end a la "+0000"
t = DATE_FORMAT1.parse(timeContents).getTime(); t = DATE_FORMAT1.parse(timeContents).getTime();
} catch (ParseException e) { } catch (ParseException e) {
// if that fails, try with a literal "Z" at the end // if that fails, try with a literal "Z" at the end
// (this is not // (this is not
// according to xml standard, but some gpx files are // according to xml standard, but some gpx files are
// like that): // like that):
try { try {
t = DATE_FORMAT2.parse(timeContents).getTime(); t = DATE_FORMAT2.parse(timeContents).getTime();
} catch (ParseException ex) { } catch (ParseException ex) {
// some gpx timestamps have 3 additional digits // some gpx timestamps have 3 additional digits
// at the end. // at the end.
try { try {
t = DATE_FORMAT3.parse(timeContents).getTime(); t = DATE_FORMAT3.parse(timeContents).getTime();
} catch (ParseException exc) { } catch (ParseException exc) {
t = 0; t = 0;
} }
} }
} }
return t; return t;
} }
} }
@@ -36,132 +36,131 @@ import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
*/ */
public class GpxImporterTest extends AndroidTestCase { public class GpxImporterTest extends AndroidTestCase {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
"yyyy-MM-dd'T'hh:mm:ss'Z'"); "yyyy-MM-dd'T'hh:mm:ss'Z'");
private static final String TRACK_NAME = "blablub"; private static final String TRACK_NAME = "blablub";
private static final String TRACK_DESC = "s'Laebe isch koi Schlotzer"; private static final String TRACK_DESC = "s'Laebe isch koi Schlotzer";
private static final String TRACK_LAT_1 = "48.768364"; private static final String TRACK_LAT_1 = "48.768364";
private static final String TRACK_LON_1 = "9.177886"; private static final String TRACK_LON_1 = "9.177886";
private static final String TRACK_ELE_1 = "324.0"; private static final String TRACK_ELE_1 = "324.0";
private static final String TRACK_TIME_1 = "2010-04-22T18:21:00Z"; private static final String TRACK_TIME_1 = "2010-04-22T18:21:00Z";
private static final String TRACK_LAT_2 = "48.768374"; private static final String TRACK_LAT_2 = "48.768374";
private static final String TRACK_LON_2 = "9.177816"; private static final String TRACK_LON_2 = "9.177816";
private static final String TRACK_ELE_2 = "333.0"; private static final String TRACK_ELE_2 = "333.0";
private static final String TRACK_TIME_2 = "2010-04-22T18:21:50Z"; private static final String TRACK_TIME_2 = "2010-04-22T18:21:50Z";
// TODO use real files from different sources with more track points // TODO use real files from different sources with more track points
private static final String VALID_TEST_GPX = "<gpx><trk><name><![CDATA[" private static final String VALID_TEST_GPX = "<gpx><trk><name><![CDATA["
+ TRACK_NAME + "]]></name><desc><![CDATA[" + TRACK_DESC + TRACK_NAME + "]]></name><desc><![CDATA[" + TRACK_DESC
+ "]]></desc><trkseg>" + "<trkpt lat=\"" + TRACK_LAT_1 + "\" lon=\"" + "]]></desc><trkseg>" + "<trkpt lat=\"" + TRACK_LAT_1 + "\" lon=\""
+ TRACK_LON_1 + "\"><ele>" + TRACK_ELE_1 + "</ele><time>" + TRACK_TIME_1 + TRACK_LON_1 + "\"><ele>" + TRACK_ELE_1 + "</ele><time>" + TRACK_TIME_1
+ "</time></trkpt> +" + "<trkpt lat=\"" + TRACK_LAT_2 + "\" lon=\"" + "</time></trkpt> +" + "<trkpt lat=\"" + TRACK_LAT_2 + "\" lon=\""
+ TRACK_LON_2 + "\"><ele>" + TRACK_ELE_2 + "</ele><time>" + TRACK_TIME_2 + TRACK_LON_2 + "\"><ele>" + TRACK_ELE_2 + "</ele><time>" + TRACK_TIME_2
+ "</time></trkpt>" + "</trkseg></trk></gpx>"; + "</time></trkpt>" + "</trkseg></trk></gpx>";
// invalid xml // invalid xml
private static final String INVALID_TEST_GPX = VALID_TEST_GPX.substring(0, private static final String INVALID_TEST_GPX = VALID_TEST_GPX.substring(0,
VALID_TEST_GPX.length() - 50); VALID_TEST_GPX.length() - 50);
private static final long TRACK_ID = 1; private static final long TRACK_ID = 1;
private static final long TRACK_POINT_ID = 1; private static final long TRACK_POINT_ID = 1;
private static final Uri TRACK_ID_URI = ContentUris.appendId( private static final Uri TRACK_ID_URI = ContentUris.appendId(
TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build(); TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build();
private static final Uri TRACK_POINT_ID_URI = ContentUris.appendId( private static final Uri TRACK_POINT_ID_URI = ContentUris.appendId(
TrackPointsColumns.CONTENT_URI.buildUpon(), TRACK_POINT_ID).build(); TrackPointsColumns.CONTENT_URI.buildUpon(), TRACK_POINT_ID).build();
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
private Factory oldProviderUtilsFactory; private Factory oldProviderUtilsFactory;
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
providerUtils = EasyMock.createMock(MyTracksProviderUtils.class); providerUtils = EasyMock.createMock(MyTracksProviderUtils.class);
oldProviderUtilsFactory = TestingProviderUtilsFactory oldProviderUtilsFactory = TestingProviderUtilsFactory
.installWithInstance(providerUtils); .installWithInstance(providerUtils);
} }
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory); TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory);
super.tearDown(); super.tearDown();
} }
/** /**
* Test import success * Test import success
*/ */
public void testImportSuccess() throws Exception { public void testImportSuccess() throws Exception {
Capture<Track> trackParam = new Capture<Track>(); Capture<Track> trackParam = new Capture<Track>();
Capture<Location> locParam = new Capture<Location>(); Capture<Location> locParam = new Capture<Location>();
Capture<Long> idParam = new Capture<Long>(); Capture<Long> idParam = new Capture<Long>();
expect(providerUtils.insertTrack(capture(trackParam))).andReturn( expect(providerUtils.insertTrack(capture(trackParam)))
TRACK_ID_URI); .andReturn(TRACK_ID_URI);
expect(providerUtils.insertTrackPoint(capture(locParam), capture(idParam))) expect(providerUtils.insertTrackPoint(capture(locParam), capture(idParam)))
.andReturn(TRACK_POINT_ID_URI); .andReturn(TRACK_POINT_ID_URI);
expectLastCall().times(2); expectLastCall().times(2);
providerUtils.updateTrack(capture(trackParam)); providerUtils.updateTrack(capture(trackParam));
replay(providerUtils); replay(providerUtils);
InputStream is = new ByteArrayInputStream(VALID_TEST_GPX.getBytes()); InputStream is = new ByteArrayInputStream(VALID_TEST_GPX.getBytes());
GpxSaxImporter.importGPXFile(is, providerUtils); GpxSaxImporter.importGPXFile(is, providerUtils);
verify(); verify();
// verify track parameter // verify track parameter
Track track = trackParam.getValue(); Track track = trackParam.getValue();
assertEquals(TRACK_NAME, track.getName()); assertEquals(TRACK_NAME, track.getName());
assertEquals(TRACK_DESC, track.getDescription()); assertEquals(TRACK_DESC, track.getDescription());
assertEquals(DATE_FORMAT.parse(TRACK_TIME_1).getTime(), track assertEquals(DATE_FORMAT.parse(TRACK_TIME_1).getTime(), track.getStartTime());
.getStartTime()); assertNotSame(-1, track.getStartId());
assertNotSame(-1, track.getStartId()); assertNotSame(-1, track.getStopId());
assertNotSame(-1, track.getStopId());
// verify last location parameter // verify last location parameter
Location loc = locParam.getValue(); Location loc = locParam.getValue();
assertEquals(Double.parseDouble(TRACK_LAT_2), loc.getLatitude()); assertEquals(Double.parseDouble(TRACK_LAT_2), loc.getLatitude());
assertEquals(Double.parseDouble(TRACK_LON_2), loc.getLongitude()); assertEquals(Double.parseDouble(TRACK_LON_2), loc.getLongitude());
assertEquals(Double.parseDouble(TRACK_ELE_2), loc.getAltitude()); assertEquals(Double.parseDouble(TRACK_ELE_2), loc.getAltitude());
assertEquals(DATE_FORMAT.parse(TRACK_TIME_2).getTime(), loc.getTime()); assertEquals(DATE_FORMAT.parse(TRACK_TIME_2).getTime(), loc.getTime());
} }
/** /**
* Test if created track will be deleted on parsing errors * Test if created track will be deleted on parsing errors
*/ */
public void testImportFailure() throws ParserConfigurationException, public void testImportFailure() throws ParserConfigurationException,
SAXException, IOException { SAXException, IOException {
expect(providerUtils.insertTrack((Track) EasyMock.anyObject())).andReturn( expect(
TRACK_ID_URI); providerUtils.insertTrack((Track) EasyMock.anyObject())).andReturn(TRACK_ID_URI);
expect( expect(
providerUtils.insertTrackPoint((Location) EasyMock.anyObject(), providerUtils.insertTrackPoint((Location) EasyMock.anyObject(),
EasyMock.anyLong())).andReturn(TRACK_POINT_ID_URI); EasyMock.anyLong())).andReturn(TRACK_POINT_ID_URI);
expectLastCall().anyTimes(); expectLastCall().anyTimes();
providerUtils.deleteTrack(TRACK_ID); providerUtils.deleteTrack(TRACK_ID);
replay(providerUtils); replay(providerUtils);
InputStream is = new ByteArrayInputStream(INVALID_TEST_GPX.getBytes()); InputStream is = new ByteArrayInputStream(INVALID_TEST_GPX.getBytes());
try { try {
GpxSaxImporter.importGPXFile(is, providerUtils); GpxSaxImporter.importGPXFile(is, providerUtils);
} catch (SAXException e) { } catch (SAXException e) {
// expected exception // expected exception
} }
verify(); verify();
} }
} }