From 508af45449548009aa880ff40d4bb6fc91aa6c19 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sun, 28 Feb 2021 18:37:11 +0100 Subject: [PATCH] Refactored TrackImporter interface. --- .../io/file/importer/ExportImportTest.java | 10 ++-- .../io/file/importer/LegacyImportTest.java | 6 +-- .../importer/AbstractFileTrackImporter.java | 5 +- .../io/file/importer/ImportService.java | 14 +++--- .../io/file/importer/KmzTrackImporter.java | 46 ++++++++++--------- .../io/file/importer/TrackImporter.java | 8 ++-- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index 742626b85..3f20f46e3 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -148,7 +148,7 @@ public class ExportImportTest { // 2. import InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); AbstractFileTrackImporter trackImporter = new KmlFileTrackImporter(context); - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track @@ -187,7 +187,7 @@ public class ExportImportTest { // 2. import InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); AbstractFileTrackImporter trackImporter = new KmlFileTrackImporter(context); - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track @@ -225,7 +225,7 @@ public class ExportImportTest { // 2. import InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); AbstractFileTrackImporter trackImporter = new KmlFileTrackImporter(context); - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then Track importedTrack = contentProviderUtils.getTrack(importTrackId); @@ -281,7 +281,7 @@ public class ExportImportTest { // 2. import InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); AbstractFileTrackImporter trackImporter = new GpxFileTrackImporter(context, contentProviderUtils); - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track @@ -327,7 +327,7 @@ public class ExportImportTest { // 2. import InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); AbstractFileTrackImporter trackImporter = new GpxFileTrackImporter(context, contentProviderUtils); - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java index 397415fee..a863fe02d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java @@ -54,7 +54,7 @@ public class LegacyImportTest { // when // 1. import - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track @@ -95,7 +95,7 @@ public class LegacyImportTest { InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_empty); // when - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); } /** @@ -110,7 +110,7 @@ public class LegacyImportTest { // when // 1. import - importTrackId = trackImporter.importFile(inputStream); + importTrackId = trackImporter.importFile(inputStream).get(0); // then // 1. track diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java index add4516eb..8dca607c5 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java @@ -120,10 +120,11 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track } @Override - public Track.Id importFile(InputStream inputStream) { + @NonNull + public List importFile(InputStream inputStream) { try { SAXParserFactory.newInstance().newSAXParser().parse(inputStream, this); - return trackIds.get(0); + return trackIds; } catch (IOException | SAXException | ParserConfigurationException | ParsingException e) { Log.e(TAG, "Unable to import file", e); if (trackIds.size() > 0) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportService.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportService.java index dc7d30511..d316bdfea 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportService.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportService.java @@ -14,6 +14,7 @@ import androidx.documentfile.provider.DocumentFile; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Track; @@ -62,11 +63,12 @@ public class ImportService extends JobIntentService { } try (InputStream inputStream = getContentResolver().openInputStream(file.getUri())) { - Track.Id trackId = trackImporter.importFile(inputStream); - if (trackId != null) { - sendResult(ImportServiceResultReceiver.RESULT_CODE_IMPORTED, trackId, file, getString(R.string.import_file_imported, file.getName())); + ArrayList trackIds = new ArrayList<>(trackImporter.importFile(inputStream)); + + if (!trackIds.isEmpty()) { + sendResult(ImportServiceResultReceiver.RESULT_CODE_IMPORTED, trackIds, file, getString(R.string.import_file_imported, file.getName())); } else { - sendResult(ImportServiceResultReceiver.RESULT_CODE_ERROR, trackId, file, getString(R.string.import_unable_to_import_file, file.getName())); + sendResult(ImportServiceResultReceiver.RESULT_CODE_ERROR, trackIds, file, getString(R.string.import_unable_to_import_file, file.getName())); } } catch (IOException e) { Log.d(TAG, "Unable to import file", e); @@ -80,9 +82,9 @@ public class ImportService extends JobIntentService { } } - private void sendResult(int resultCode, Track.Id trackId, DocumentFile file, String message) { + private void sendResult(int resultCode, ArrayList trackId, DocumentFile file, String message) { Bundle bundle = new Bundle(); - bundle.putParcelable(ImportServiceResultReceiver.RESULT_EXTRA_TRACK_ID, trackId); + bundle.putParcelableArrayList(ImportServiceResultReceiver.RESULT_EXTRA_TRACK_ID, trackId); bundle.putString(ImportServiceResultReceiver.RESULT_EXTRA_FILENAME, file.getName()); bundle.putString(ImportServiceResultReceiver.RESULT_EXTRA_MESSAGE, message); resultReceiver.send(resultCode, bundle); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java index ea22b26fd..39725f0ce 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmzTrackImporter.java @@ -20,6 +20,8 @@ import android.content.Context; import android.net.Uri; import android.util.Log; +import androidx.annotation.NonNull; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -66,17 +68,23 @@ public class KmzTrackImporter implements TrackImporter { } @Override - public Track.Id importFile(InputStream inputStream) { - Track.Id trackId = findAndParseKmlFile(inputStream); + public @NonNull + List importFile(InputStream inputStream) { + List trackIds = findAndParseKmlFile(inputStream); - if (!copyKmzImages(trackId)) { - cleanImport(context, trackId); - return null; + ArrayList trackIdsWithImages = new ArrayList<>(); + + for (Track.Id trackId : trackIds) { + if (copyKmzImages(trackId)) { + trackIdsWithImages.add(trackId); + deleteOrphanImages(context, trackId); + } else { + cleanImport(context, trackId); + return new ArrayList<>(); + } } - deleteOrphanImages(context, trackId); - - return trackId; + return trackIdsWithImages; } /** @@ -150,14 +158,13 @@ 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. */ - private Track.Id findAndParseKmlFile(InputStream inputStream) { + private List findAndParseKmlFile(InputStream inputStream) { try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { ZipEntry zipEntry; - Track.Id trackId = null; + ArrayList trackIds = new ArrayList<>(); while ((zipEntry = zipInputStream.getNextEntry()) != null) { if (Thread.interrupted()) { @@ -167,20 +174,21 @@ public class KmzTrackImporter implements TrackImporter { String fileName = zipEntry.getName(); if (KmzTrackExporter.KMZ_KML_FILE.equals(fileName)) { - trackId = parseKml(zipInputStream); - if (trackId == null) { + List trackId = parseKml(zipInputStream); + if (trackId.isEmpty()) { Log.d(TAG, "Unable to parse kml in kmz"); throw new ImportParserException(context.getString(R.string.import_unable_to_import_file, fileName)); } + trackIds.addAll(trackId); } zipInputStream.closeEntry(); } - if (trackId == null) { + if (trackIds.isEmpty()) { Log.d(TAG, "Unable to find doc.kml in kmz"); throw new ImportParserException(context.getString(R.string.import_no_kml_file_found)); } - return trackId; + return trackIds; } catch (ImportParserException | ImportAlreadyExistsException e) { Log.e(TAG, "Unable to import file", e); throw e; @@ -234,13 +242,7 @@ public class KmzTrackImporter implements TrackImporter { } } - /** - * Parses kml - * - * @param zipInputStream the zip input stream - * @return the imported track id or -1L - */ - private Track.Id parseKml(ZipInputStream zipInputStream) { + private List parseKml(ZipInputStream zipInputStream) { KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(context); try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getKml(zipInputStream))) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java index 26259f1af..b12dd4ac8 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java @@ -15,7 +15,10 @@ */ package de.dennisguse.opentracks.io.file.importer; +import androidx.annotation.NonNull; + import java.io.InputStream; +import java.util.List; import de.dennisguse.opentracks.content.data.Track; @@ -30,8 +33,7 @@ public interface TrackImporter { * Import a file. * * @param inputStream the file's input stream - * @return the imported track id or null. */ - //TODO Figure out how can make the import an atomic operation (incl. database transaction rollback). - Track.Id importFile(InputStream inputStream); + @NonNull + List importFile(InputStream inputStream) throws ImportParserException; }