Cleanup: refactored importers.

This commit is contained in:
Dennis Guse
2021-05-01 00:51:13 +02:00
parent f277347529
commit 92004b0ec7
6 changed files with 49 additions and 69 deletions
@@ -22,7 +22,6 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.Instant; import java.time.Instant;
@@ -154,7 +153,7 @@ public class ExportImportTest {
@LargeTest @LargeTest
@Test @Test
public void kml_with_trackdetail() throws TimeoutException, FileNotFoundException { public void kml_with_trackdetail() throws TimeoutException, IOException {
setUp(false); setUp(false);
// given // given
@@ -194,7 +193,7 @@ public class ExportImportTest {
@LargeTest @LargeTest
@Test @Test
public void kml_with_trackdetail_and_sensordata() throws TimeoutException, FileNotFoundException { public void kml_with_trackdetail_and_sensordata() throws TimeoutException, IOException {
setUp(true); setUp(true);
// given // given
@@ -248,9 +247,8 @@ public class ExportImportTest {
contentProviderUtils.deleteTrack(context, trackId); contentProviderUtils.deleteTrack(context, trackId);
// 2. import // 2. import
InputStream inputStream = context.getContentResolver().openInputStream(tmpFileUri); KmzTrackImporter trackImporter = new KmzTrackImporter();
TrackImporter trackImporter = new KmzTrackImporter(context, tmpFileUri); importTrackId = trackImporter.importFile(context, tmpFileUri).get(0);
importTrackId = trackImporter.importFile(inputStream).get(0);
// then // then
// 1. track // 1. track
@@ -273,7 +271,7 @@ public class ExportImportTest {
@LargeTest @LargeTest
@Test(expected = ImportAlreadyExistsException.class) @Test(expected = ImportAlreadyExistsException.class)
public void kml_with_trackdetail_and_sensordata_duplicate_trackUUID() throws TimeoutException, FileNotFoundException { public void kml_with_trackdetail_and_sensordata_duplicate_trackUUID() throws TimeoutException, IOException {
setUp(false); setUp(false);
// given // given
@@ -299,7 +297,7 @@ public class ExportImportTest {
@LargeTest @LargeTest
@Test @Test
public void gpx() throws TimeoutException, FileNotFoundException { public void gpx() throws TimeoutException, IOException {
setUp(true); setUp(true);
// given // given
@@ -346,7 +344,7 @@ public class ExportImportTest {
@LargeTest @LargeTest
@Test(expected = ImportAlreadyExistsException.class) @Test(expected = ImportAlreadyExistsException.class)
public void gpx_duplicate_trackUUID() throws TimeoutException, FileNotFoundException { public void gpx_duplicate_trackUUID() throws TimeoutException, IOException {
setUp(false); setUp(false);
// given // given
@@ -11,6 +11,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
@@ -48,7 +49,7 @@ public class LegacyImportTest {
*/ */
@LargeTest @LargeTest
@Test @Test
public void kml_with_statistics_marker() { public void kml_with_statistics_marker() throws IOException {
// given // given
XMLImporter trackImporter = new XMLImporter(new KmlFileTrackImporter(context)); XMLImporter trackImporter = new XMLImporter(new KmlFileTrackImporter(context));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_statistics_marker); InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_statistics_marker);
@@ -90,7 +91,7 @@ public class LegacyImportTest {
*/ */
@LargeTest @LargeTest
@Test(expected = ImportParserException.class) @Test(expected = ImportParserException.class)
public void kml_without_locations() { public void kml_without_locations() throws IOException {
// given // given
XMLImporter trackImporter = new XMLImporter(new KmlFileTrackImporter(context)); XMLImporter trackImporter = new XMLImporter(new KmlFileTrackImporter(context));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_empty); InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_empty);
@@ -104,7 +105,7 @@ public class LegacyImportTest {
*/ */
@LargeTest @LargeTest
@Test @Test
public void gpx_with_pause_resume() { public void gpx_with_pause_resume() throws IOException {
// given // given
XMLImporter trackImporter = new XMLImporter(new GpxFileTrackImporter(context)); XMLImporter trackImporter = new XMLImporter(new GpxFileTrackImporter(context));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_gpx_pause_resume); InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_gpx_pause_resume);
@@ -13,7 +13,6 @@ import androidx.core.app.JobIntentService;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
@@ -49,21 +48,21 @@ public class ImportService extends JobIntentService {
private void importFile(DocumentFile file) { private void importFile(DocumentFile file) {
TrackImporter trackImporter; TrackImporter trackImporter;
String fileExtension = FileUtils.getExtension(file); String fileExtension = FileUtils.getExtension(file);
try {
if (TrackFileFormat.GPX.getExtension().equals(fileExtension)) { if (TrackFileFormat.GPX.getExtension().equals(fileExtension)) {
trackImporter = new XMLImporter(new GpxFileTrackImporter(this)); trackImporter = new XMLImporter(new GpxFileTrackImporter(this));
} else if (TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getExtension().equals(fileExtension)) { } else if (TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getExtension().equals(fileExtension)) {
trackImporter = new XMLImporter(new KmlFileTrackImporter(this)); trackImporter = new XMLImporter(new KmlFileTrackImporter(this));
} else if (TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getExtension().equals(fileExtension)) { } else if (TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getExtension().equals(fileExtension)) {
trackImporter = new KmzTrackImporter(this, file.getUri()); trackImporter = new KmzTrackImporter();
} else { } else {
Log.d(TAG, "Unsupported file format."); Log.d(TAG, "Unsupported file format.");
sendResult(ImportServiceResultReceiver.RESULT_CODE_ERROR, null, file, getString(R.string.import_unsupported_format)); sendResult(ImportServiceResultReceiver.RESULT_CODE_ERROR, null, file, getString(R.string.import_unsupported_format));
return; return;
} }
try (InputStream inputStream = getContentResolver().openInputStream(file.getUri())) { ArrayList<Track.Id> trackIds = new ArrayList<>(trackImporter.importFile(this, file.getUri()));
ArrayList<Track.Id> trackIds = new ArrayList<>(trackImporter.importFile(inputStream));
if (!trackIds.isEmpty()) { if (!trackIds.isEmpty()) {
sendResult(ImportServiceResultReceiver.RESULT_CODE_IMPORTED, trackIds, file, getString(R.string.import_file_imported, file.getName())); sendResult(ImportServiceResultReceiver.RESULT_CODE_IMPORTED, trackIds, file, getString(R.string.import_file_imported, file.getName()));
@@ -54,27 +54,17 @@ public class KmzTrackImporter implements TrackImporter {
private static final int BUFFER_SIZE = 4096; private static final int BUFFER_SIZE = 4096;
private final Context context; private Context context;
private final Uri uriKmzFile;
/** @NonNull
* @param context the context public List<Track.Id> importFile(Context context, Uri fileUri) throws IOException {
* @param uriFile URI of the kmz file.
*/
public KmzTrackImporter(Context context, Uri uriFile) {
this.context = context; this.context = context;
this.uriKmzFile = uriFile; List<Track.Id> trackIds = findAndParseKmlFile(fileUri);
}
@Override
public @NonNull
List<Track.Id> importFile(InputStream inputStream) {
List<Track.Id> trackIds = findAndParseKmlFile(inputStream);
List<Track.Id> trackIdsWithImages = new ArrayList<>(); List<Track.Id> trackIdsWithImages = new ArrayList<>();
for (Track.Id trackId : trackIds) { for (Track.Id trackId : trackIds) {
if (copyKmzImages(trackId)) { if (copyKmzImages(fileUri, trackId)) {
trackIdsWithImages.add(trackId); trackIdsWithImages.add(trackId);
deleteOrphanImages(trackId); deleteOrphanImages(trackId);
} else { } else {
@@ -90,8 +80,8 @@ public class KmzTrackImporter implements TrackImporter {
* *
* @return false if there are errors or true otherwise. * @return false if there are errors or true otherwise.
*/ */
private boolean copyKmzImages(Track.Id trackId) { private boolean copyKmzImages(Uri uri, Track.Id trackId) throws IOException {
try (InputStream inputStream = context.getContentResolver().openInputStream(uriKmzFile); try (InputStream inputStream = context.getContentResolver().openInputStream(uri);
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry; ZipEntry zipEntry;
@@ -110,9 +100,6 @@ public class KmzTrackImporter implements TrackImporter {
} }
return true; return true;
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
return false;
} }
} }
@@ -154,13 +141,9 @@ public class KmzTrackImporter implements TrackImporter {
return KMZ_IMAGES_EXT.contains(fileExt); return KMZ_IMAGES_EXT.contains(fileExt);
} }
/** private List<Track.Id> findAndParseKmlFile(Uri uri) throws IOException {
* Finds KmzTrackExporter.KMZ_KML_FILE file inside kmz file (inputStream) and it parses it. try (InputStream inputStream = context.getContentResolver().openInputStream(uri);
* ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
* @param inputStream kmz input stream.
*/
private List<Track.Id> findAndParseKmlFile(InputStream inputStream) {
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry; ZipEntry zipEntry;
ArrayList<Track.Id> trackIds = new ArrayList<>(); ArrayList<Track.Id> trackIds = new ArrayList<>();
@@ -190,9 +173,6 @@ public class KmzTrackImporter implements TrackImporter {
} catch (ImportParserException | ImportAlreadyExistsException e) { } catch (ImportParserException | ImportAlreadyExistsException e) {
Log.e(TAG, "Unable to import file", e); Log.e(TAG, "Unable to import file", e);
throw e; throw e;
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
throw new ImportParserException(e);
} }
} }
@@ -15,9 +15,10 @@
*/ */
package de.dennisguse.opentracks.io.file.importer; package de.dennisguse.opentracks.io.file.importer;
import androidx.annotation.NonNull; import android.content.Context;
import android.net.Uri;
import java.io.InputStream; import java.io.IOException;
import java.util.List; import java.util.List;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
@@ -29,11 +30,5 @@ import de.dennisguse.opentracks.content.data.Track;
*/ */
public interface TrackImporter { public interface TrackImporter {
/** List<Track.Id> importFile(Context context, Uri uri) throws IOException, ImportParserException;
* Import a file.
*
* @param inputStream the file's input stream
*/
@NonNull
List<Track.Id> importFile(InputStream inputStream) throws ImportParserException;
} }
@@ -1,6 +1,8 @@
package de.dennisguse.opentracks.io.file.importer; package de.dennisguse.opentracks.io.file.importer;
import android.content.Context;
import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteConstraintException;
import android.net.Uri;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -29,12 +31,17 @@ public class XMLImporter implements TrackImporter {
@Override @Override
@NonNull @NonNull
public List<Track.Id> importFile(InputStream inputStream) throws ImportParserException, ImportAlreadyExistsException { public List<Track.Id> importFile(Context context, Uri uri) throws ImportParserException, ImportAlreadyExistsException, IOException {
try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
return importFile(inputStream);
}
}
public List<Track.Id> importFile(InputStream inputStream) throws ImportParserException, ImportAlreadyExistsException, IOException {
try { try {
SAXParserFactory.newInstance().newSAXParser().parse(inputStream, parser.getHandler()); SAXParserFactory.newInstance().newSAXParser().parse(inputStream, parser.getHandler());
List<Track.Id> trackIds = parser.getImportTrackIds(); return parser.getImportTrackIds();
return trackIds; } catch (SAXException | ParserConfigurationException | AbstractFileTrackImporter.ParsingException e) {
} catch (IOException | SAXException | ParserConfigurationException | AbstractFileTrackImporter.ParsingException e) {
Log.e(TAG, "Unable to import file", e); Log.e(TAG, "Unable to import file", e);
if (parser.getImportTrackIds().size() > 0) { if (parser.getImportTrackIds().size() > 0) {
parser.cleanImport(); parser.cleanImport();