Implement Track.Id and Waypoint.Id (without tests).

Fixes #276.
This commit is contained in:
Dennis Guse
2020-08-18 22:06:26 +02:00
parent b2e8713db0
commit bcbaf4985a
49 changed files with 678 additions and 483 deletions
@@ -98,7 +98,7 @@ public class FileTrackExporter implements TrackExporter {
* I am leaving the number of waypoints very high which should not be a problem, because we don't try to load them into objects all at the same time.
*/
boolean hasWaypoints = false;
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), -1L, ContentProviderUtils.MAX_LOADED_WAYPOINTS_POINTS)) {
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), null, ContentProviderUtils.MAX_LOADED_WAYPOINTS_POINTS)) {
if (cursor != null && cursor.moveToFirst()) {
for (int i = 0; i < cursor.getCount(); i++) {
if (Thread.interrupted()) {
@@ -388,7 +388,7 @@ public class KmlTrackWriter implements TrackWriter {
* @param trackId the track id containing the location
* @param location the location
*/
private float getHeading(long trackId, Location location) {
private float getHeading(Track.Id trackId, Location location) {
long trackPointId = contentProviderUtils.getTrackPointId(trackId, location);
if (trackPointId == -1L) {
return location.getBearing();
@@ -110,7 +110,7 @@ public class KmzTrackExporter implements TrackExporter {
private void addImages(Context context, Track[] tracks, ZipOutputStream zipOutputStream) throws InterruptedException, IOException {
for (Track track : tracks) {
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), -1L, -1)) {
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), null, -1)) {
if (cursor != null && cursor.moveToFirst()) {
for (int i = 0; i < cursor.getCount(); i++) {
if (Thread.interrupted()) {
@@ -68,8 +68,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
private final ContentProviderUtils contentProviderUtils;
private final int recordingDistanceInterval;
private long importTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
private final List<Long> trackIds = new ArrayList<>();
private Track.Id importTrackId;
private final List<Track.Id> trackIds = new ArrayList<>();
private final List<Waypoint> waypoints = new ArrayList<>();
// The current element content
@@ -104,7 +104,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
this.recordingDistanceInterval = PreferencesUtils.getRecordingDistanceInterval(context);
}
AbstractFileTrackImporter(Context context, ContentProviderUtils contentProviderUtils, long importTrackId) {
AbstractFileTrackImporter(Context context, ContentProviderUtils contentProviderUtils, Track.Id importTrackId) {
this(context, contentProviderUtils);
this.importTrackId = importTrackId;
}
@@ -126,7 +126,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
}
@Override
public long importFile(InputStream inputStream) {
public Track.Id importFile(InputStream inputStream) {
try {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
long start = System.currentTimeMillis();
@@ -140,7 +140,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
} catch (MultiTracksImportException | IOException | SAXException | SQLiteConstraintException | ParserConfigurationException e) {
Log.e(TAG, "Unable to import file", e);
cleanImport();
return -1L;
return null;
}
}
@@ -153,7 +153,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
if (size == 0) {
return;
}
long trackId = trackIds.get(size - 1);
Track.Id trackId = trackIds.get(size - 1);
Track track = contentProviderUtils.getTrack(trackId);
if (track == null) {
return;
@@ -225,10 +225,10 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
*/
protected void onTrackStart() throws SAXException {
trackData = new TrackData();
long trackId;
if (importTrackId == -1L) {
Track.Id trackId;
if (importTrackId == null) {
Uri uri = contentProviderUtils.insertTrack(trackData.track);
trackId = Long.parseLong(uri.getLastPathSegment());
trackId = new Track.Id(Long.parseLong(uri.getLastPathSegment()));
} else {
if (trackIds.size() > 0) {
throw new SAXException(createErrorMessage("Cannot import more than one track to an existing track " + importTrackId));
@@ -399,7 +399,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
* @param externalPhotoUrl the file name
*/
protected String getInternalPhotoUrl(String externalPhotoUrl) {
if (importTrackId == -1L) {
if (importTrackId == null) {
Log.e(TAG, "Track id is invalid.");
return null;
}
@@ -517,7 +517,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
* Cleans up import.
*/
private void cleanImport() {
for (long trackId : trackIds) {
for (Track.Id trackId : trackIds) {
contentProviderUtils.deleteTrack(context, trackId);
}
}
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.Waypoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
@@ -52,7 +53,7 @@ public class KmzTrackImporter implements TrackImporter {
private static final int BUFFER_SIZE = 4096;
private final Context context;
private long importTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
private Track.Id importTrackId; //TODO needed?
private final Uri uriKmzFile;
/**
@@ -65,18 +66,18 @@ public class KmzTrackImporter implements TrackImporter {
}
@Override
public long importFile(InputStream inputStream) {
long trackId;
public Track.Id importFile(InputStream inputStream) {
Track.Id trackId;
if (!copyKmzImages()) {
cleanImport(context, importTrackId);
return -1L;
return null;
}
trackId = findAndParseKmlFile(inputStream);
if (trackId == -1L) {
if (trackId == null) {
cleanImport(context, importTrackId);
return -1L;
return null;
}
deleteOrphanImages(context, trackId);
@@ -91,7 +92,7 @@ public class KmzTrackImporter implements TrackImporter {
*/
private boolean copyKmzImages() {
try (InputStream inputStream = context.getContentResolver().openInputStream(uriKmzFile);
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
@@ -140,7 +141,7 @@ public class KmzTrackImporter implements TrackImporter {
* Returns true if fileName ends with some of the KMZ_IMAGES_EXT suffixes.
* Otherwise returns false.
*/
private boolean hasImageExtension(String fileName) {
private boolean hasImageExtension(String fileName) {
if (fileName == null) {
return false;
}
@@ -155,27 +156,28 @@ public class KmzTrackImporter implements TrackImporter {
/**
* Finds KmzTrackExporter.KMZ_KML_FILE file inside kmz file (inputStream) and it parses it.
* TODO: May load multiple tracks, but only returns the last Track.Id.
*
* @param inputStream kmz input stream.
* @return -1 if error or the id of the track otherwise.
* @return null if error or the id of the track otherwise.
*/
private long findAndParseKmlFile(InputStream inputStream) {
private Track.Id findAndParseKmlFile(InputStream inputStream) {
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry;
long trackId = -1L;
Track.Id trackId = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (Thread.interrupted()) {
Log.d(TAG, "Thread interrupted");
return -1L;
return null;
}
String fileName = zipEntry.getName();
if (KmzTrackExporter.KMZ_KML_FILE.equals(fileName)) {
trackId = parseKml(zipInputStream);
if (trackId == -1L) {
if (trackId != null) {
Log.d(TAG, "Unable to parse kml in kmz");
return -1L;
return null;
}
}
@@ -184,7 +186,7 @@ public class KmzTrackImporter implements TrackImporter {
return trackId;
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
return -1L;
return null;
}
}
@@ -194,8 +196,8 @@ public class KmzTrackImporter implements TrackImporter {
* @param context the Context object.
* @param trackId the id of the Track.
*/
private void deleteOrphanImages(Context context, long trackId) {
if (trackId != 1L) {
private void deleteOrphanImages(Context context, Track.Id trackId) {
if (!trackId.isValid()) {
// 1.- Gets all photo names in the waypoints of the track identified by id.
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
List<Waypoint> waypoints = contentProviderUtils.getWaypoints(trackId);
@@ -227,7 +229,7 @@ public class KmzTrackImporter implements TrackImporter {
*
* @param trackId the trackId
*/
private void cleanImport(Context context, long trackId) {
private void cleanImport(Context context, Track.Id trackId) {
if (PreferencesUtils.isRecording(trackId)) {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
contentProviderUtils.deleteTrack(context, trackId);
@@ -240,7 +242,7 @@ public class KmzTrackImporter implements TrackImporter {
* @param zipInputStream the zip input stream
* @return the imported track id or -1L
*/
private long parseKml(ZipInputStream zipInputStream) throws IOException {
private Track.Id parseKml(ZipInputStream zipInputStream) throws IOException {
KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(context);
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getKml(zipInputStream))) {
@@ -271,7 +273,7 @@ public class KmzTrackImporter implements TrackImporter {
* @param fileName the file name
*/
private void readAndSaveImageFile(ZipInputStream zipInputStream, String fileName) throws IOException {
if (importTrackId == -1L || fileName.equals("")) {
if (importTrackId == null || fileName.equals("")) {
return;
}
@@ -17,6 +17,8 @@ package de.dennisguse.opentracks.io.file.importer;
import java.io.InputStream;
import de.dennisguse.opentracks.content.data.Track;
/**
* Interface for a track importer.
*
@@ -28,8 +30,8 @@ public interface TrackImporter {
* Import a file.
*
* @param inputStream the file's input stream
* @return the imported track id or RECORDING_TRACK_ID_DEFAULT.
* @return the imported track id or null.
*/
//TODO Figure out how can make the import an atomic operation (incl. database transaction rollback).
long importFile(InputStream inputStream);
Track.Id importFile(InputStream inputStream);
}