aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/src/cgeo/geocaching/cgeogpxes.java8
-rw-r--r--main/src/cgeo/geocaching/files/GPXImporter.java71
-rw-r--r--tests/res/raw/pq7545915.zipbin0 -> 5086 bytes
-rw-r--r--tests/src/cgeo/geocaching/cgeogpxesTest.java5
-rw-r--r--tests/src/cgeo/geocaching/files/GPXImporterTest.java72
5 files changed, 138 insertions, 18 deletions
diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java
index 6ac2f0c..ce9b437 100644
--- a/main/src/cgeo/geocaching/cgeogpxes.java
+++ b/main/src/cgeo/geocaching/cgeogpxes.java
@@ -12,12 +12,15 @@ import android.os.Environment;
import java.io.File;
import java.util.List;
+import java.util.regex.Pattern;
public class cgeogpxes extends FileList<cgGPXListAdapter> {
private static final String EXTRAS_LIST_ID = "list";
+ private static final Pattern gpxZipFilePattern = Pattern.compile("\\d+\\.zip", Pattern.CASE_INSENSITIVE);
+
public cgeogpxes() {
- super(new String[] { "gpx", "loc" });
+ super(new String[] { "gpx", "loc", "zip" });
}
private int listId = 1;
@@ -59,6 +62,9 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
@Override
protected boolean filenameBelongsToList(final String filename) {
if (super.filenameBelongsToList(filename)) {
+ if (StringUtils.endsWithIgnoreCase(filename, GPXImporter.ZIP_FILE_EXTENSION)) {
+ return gpxZipFilePattern.matcher(filename).matches();
+ }
// filter out waypoint files
return !StringUtils.endsWithIgnoreCase(filename, GPXImporter.WAYPOINTS_FILE_SUFFIX_AND_EXTENSION);
}
diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java
index 4ee7e99..65b0189 100644
--- a/main/src/cgeo/geocaching/files/GPXImporter.java
+++ b/main/src/cgeo/geocaching/files/GPXImporter.java
@@ -27,6 +27,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.concurrent.CancellationException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
public class GPXImporter {
static final int IMPORT_STEP_READ_FILE = 1;
@@ -38,6 +40,7 @@ public class GPXImporter {
static final int IMPORT_STEP_CANCELED = 7;
public static final String GPX_FILE_EXTENSION = ".gpx";
+ public static final String ZIP_FILE_EXTENSION = ".zip";
public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = "-wpts.gpx";
private Progress progress = new Progress();
@@ -57,6 +60,8 @@ public class GPXImporter {
public void importGPX(final File file) {
if (StringUtils.endsWithIgnoreCase(file.getName(), GPX_FILE_EXTENSION)) {
new ImportGpxFileThread(file, listId, importStepHandler, progressHandler).start();
+ } else if (StringUtils.endsWithIgnoreCase(file.getName(), ZIP_FILE_EXTENSION)) {
+ new ImportGpxZipFileThread(file, listId, importStepHandler, progressHandler).start();
} else {
new ImportLocFileThread(file, listId, importStepHandler, progressHandler).start();
}
@@ -148,7 +153,7 @@ public class GPXImporter {
caches = parser.parse(cacheFile, progressHandler);
}
- final File wptsFile = getWaypointsFileForGpx(cacheFile);
+ final File wptsFile = new File(cacheFile.getParentFile(), getWaypointsFileNameForGpxFileName(cacheFile.getName()));
if (wptsFile != null && wptsFile.canRead()) {
Log.i(Settings.tag, "Import GPX waypoint file: " + wptsFile.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) wptsFile.length()));
@@ -159,6 +164,55 @@ public class GPXImporter {
}
}
+ static class ImportGpxZipFileThread extends ImportThread {
+ private final File cacheFile;
+
+ public ImportGpxZipFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.cacheFile = file;
+ }
+
+ @Override
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ Log.i(Settings.tag, "Import GPX zip file: " + cacheFile.getAbsolutePath());
+ ZipFile zipFile = new ZipFile(cacheFile);
+ try {
+ final String gpxName = getGpxFileNameForZipFileName(cacheFile.getName());
+ if (gpxName == null) {
+ throw new ParserException(cacheFile.getName() + " is not a GPX zip file");
+ }
+ final ZipEntry gpxEntry = zipFile.getEntry(gpxName);
+ if (gpxEntry == null) {
+ throw new ParserException(cacheFile.getName() + " is not a GPX zip file");
+ }
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) gpxEntry.getSize()));
+
+ Collection<cgCache> caches;
+ GPXParser parser;
+ try {
+ // try to parse cache file as GPX 10
+ parser = new GPX10Parser(listId);
+ caches = parser.parse(zipFile.getInputStream(gpxEntry), progressHandler);
+ } catch (ParserException pe) {
+ // didn't work -> lets try GPX11
+ parser = new GPX11Parser(listId);
+ caches = parser.parse(zipFile.getInputStream(gpxEntry), progressHandler);
+ }
+
+ final ZipEntry gpxWptsEntry = zipFile.getEntry(getWaypointsFileNameForGpxFileName(gpxName));
+ if (gpxWptsEntry != null) {
+ Log.i(Settings.tag, "Import GPX waypoint file: " + gpxWptsEntry.getName());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) gpxWptsEntry.getSize()));
+ caches = parser.parse(zipFile.getInputStream(gpxWptsEntry), progressHandler);
+ }
+
+ return caches;
+ } finally {
+ zipFile.close();
+ }
+ }
+ }
+
static class ImportLocFileThread extends ImportThread {
private final File file;
@@ -263,12 +317,19 @@ public class GPXImporter {
}
};
+ // 1234567.zip -> 1234567.gpx
+ static String getGpxFileNameForZipFileName(String name) {
+ if (StringUtils.endsWithIgnoreCase(name, ZIP_FILE_EXTENSION) && (StringUtils.length(name) > ZIP_FILE_EXTENSION.length())) {
+ return StringUtils.substringBeforeLast(name, ".") + GPX_FILE_EXTENSION;
+ } else {
+ return null;
+ }
+ }
+
// 1234567.gpx -> 1234567-wpts.gpx
- static File getWaypointsFileForGpx(File file) {
- final String name = file.getName();
+ static String getWaypointsFileNameForGpxFileName(String name) {
if (StringUtils.endsWithIgnoreCase(name, GPX_FILE_EXTENSION) && (StringUtils.length(name) > GPX_FILE_EXTENSION.length())) {
- final String wptsName = StringUtils.substringBeforeLast(name, ".") + WAYPOINTS_FILE_SUFFIX_AND_EXTENSION;
- return new File(file.getParentFile(), wptsName);
+ return StringUtils.substringBeforeLast(name, ".") + WAYPOINTS_FILE_SUFFIX_AND_EXTENSION;
} else {
return null;
}
diff --git a/tests/res/raw/pq7545915.zip b/tests/res/raw/pq7545915.zip
new file mode 100644
index 0000000..e23751f
--- /dev/null
+++ b/tests/res/raw/pq7545915.zip
Binary files differ
diff --git a/tests/src/cgeo/geocaching/cgeogpxesTest.java b/tests/src/cgeo/geocaching/cgeogpxesTest.java
index bc0f99e..884bd03 100644
--- a/tests/src/cgeo/geocaching/cgeogpxesTest.java
+++ b/tests/src/cgeo/geocaching/cgeogpxesTest.java
@@ -15,12 +15,17 @@ public class cgeogpxesTest extends ActivityInstrumentationTestCase2<cgeogpxes> {
assertTrue(importGpxActivity.filenameBelongsToList(".gpx"));
assertTrue(importGpxActivity.filenameBelongsToList("1234567.loc"));
assertTrue(importGpxActivity.filenameBelongsToList("1234567.LOC"));
+ assertTrue(importGpxActivity.filenameBelongsToList("1234567.zip"));
+ assertTrue(importGpxActivity.filenameBelongsToList("1234567.ZIP"));
assertFalse(importGpxActivity.filenameBelongsToList("1234567.gpy"));
assertFalse(importGpxActivity.filenameBelongsToList("1234567.agpx"));
assertFalse(importGpxActivity.filenameBelongsToList("1234567"));
assertFalse(importGpxActivity.filenameBelongsToList(""));
assertFalse(importGpxActivity.filenameBelongsToList("gpx"));
+ assertFalse(importGpxActivity.filenameBelongsToList("test.zip"));
+ assertFalse(importGpxActivity.filenameBelongsToList("zip"));
+ assertFalse(importGpxActivity.filenameBelongsToList(".zip"));
assertFalse(importGpxActivity.filenameBelongsToList("1234567-wpts.gpx"));
}
diff --git a/tests/src/cgeo/geocaching/files/GPXImporterTest.java b/tests/src/cgeo/geocaching/files/GPXImporterTest.java
index d23521b..76648e6 100644
--- a/tests/src/cgeo/geocaching/files/GPXImporterTest.java
+++ b/tests/src/cgeo/geocaching/files/GPXImporterTest.java
@@ -21,18 +21,32 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
private int listId;
private File tempDir;
- public static void testGetWaypointsFileForGpx() {
- assertEquals(new File("1234567-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("1234567.gpx")));
- assertEquals(new File("/mnt/sdcard/1234567-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("/mnt/sdcard/1234567.gpx")));
- assertEquals(new File("/mnt/sdcard/1-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("/mnt/sdcard/1.gpx")));
- assertEquals(new File("/mnt/sd.card/1-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("/mnt/sd.card/1.gpx")));
- assertEquals(new File("1234567.9-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("1234567.9.gpx")));
- assertEquals(new File("1234567-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("1234567.GPX")));
- assertEquals(new File("gpx.gpx-wpts.gpx"), GPXImporter.getWaypointsFileForGpx(new File("gpx.gpx.gpx")));
- assertNull(GPXImporter.getWaypointsFileForGpx(new File("123.gpy")));
- assertNull(GPXImporter.getWaypointsFileForGpx(new File("gpx")));
- assertNull(GPXImporter.getWaypointsFileForGpx(new File(".gpx")));
- assertNull(GPXImporter.getWaypointsFileForGpx(new File("/mnt/sdcard/.gpx")));
+ public void testGetWaypointsFileNameForGpxFileName() {
+ assertEquals("1234567-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("1234567.gpx"));
+ assertEquals("/mnt/sdcard/1234567-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("/mnt/sdcard/1234567.gpx"));
+ assertEquals("/mnt/sdcard/1-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("/mnt/sdcard/1.gpx"));
+ assertEquals("/mnt/sd.card/1-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("/mnt/sd.card/1.gpx"));
+ assertEquals("1234567.9-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("1234567.9.gpx"));
+ assertEquals("1234567-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("1234567.GPX"));
+ assertEquals("gpx.gpx-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("gpx.gpx.gpx"));
+ assertEquals("/mnt/sdcard/-wpts.gpx", GPXImporter.getWaypointsFileNameForGpxFileName("/mnt/sdcard/.gpx"));
+ assertNull(GPXImporter.getWaypointsFileNameForGpxFileName("123.gpy"));
+ assertNull(GPXImporter.getWaypointsFileNameForGpxFileName("gpx"));
+ assertNull(GPXImporter.getWaypointsFileNameForGpxFileName(".gpx"));
+ }
+
+ public void testGetGpxFileNameForZipFileName() {
+ assertEquals("1234567.gpx", GPXImporter.getGpxFileNameForZipFileName("1234567.zip"));
+ assertEquals("/mnt/sdcard/1234567.gpx", GPXImporter.getGpxFileNameForZipFileName("/mnt/sdcard/1234567.zip"));
+ assertEquals("1.gpx", GPXImporter.getGpxFileNameForZipFileName("1.zip"));
+ assertEquals("/mnt/sd.card/1.gpx", GPXImporter.getGpxFileNameForZipFileName("/mnt/sd.card/1.zip"));
+ assertEquals("1234567.9.gpx", GPXImporter.getGpxFileNameForZipFileName("1234567.9.zip"));
+ assertEquals("1234567.gpx", GPXImporter.getGpxFileNameForZipFileName("1234567.ZIP"));
+ assertEquals("zip.zip.gpx", GPXImporter.getGpxFileNameForZipFileName("zip.zip.zip"));
+ assertEquals("/mnt/sdcard/.gpx", GPXImporter.getGpxFileNameForZipFileName("/mnt/sdcard/.zip"));
+ assertNull(GPXImporter.getGpxFileNameForZipFileName("123.zap"));
+ assertNull(GPXImporter.getGpxFileNameForZipFileName("zip"));
+ assertNull(GPXImporter.getGpxFileNameForZipFileName(".zip"));
}
public void testImportGpx() throws IOException {
@@ -130,6 +144,40 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
assertEquals(GPXImporter.IMPORT_STEP_CANCELED, importStepHandler.messages.get(1).what);
}
+ public void testImportGpxZip() throws IOException {
+ File pq7545915 = new File(tempDir, "7545915.zip");
+ copyResourceToFile(R.raw.pq7545915, pq7545915);
+
+ GPXImporter.ImportGpxZipFileThread importThread = new GPXImporter.ImportGpxZipFileThread(pq7545915, listId, importStepHandler, progressHandler);
+ importThread.run();
+ importStepHandler.waitForCompletion();
+
+ assertEquals(4, importStepHandler.messages.size());
+ assertEquals(GPXImporter.IMPORT_STEP_READ_FILE, importStepHandler.messages.get(0).what);
+ assertEquals(GPXImporter.IMPORT_STEP_READ_WPT_FILE, importStepHandler.messages.get(1).what);
+ assertEquals(GPXImporter.IMPORT_STEP_STORE_CACHES, importStepHandler.messages.get(2).what);
+ assertEquals(GPXImporter.IMPORT_STEP_FINISHED, importStepHandler.messages.get(3).what);
+ cgSearch search = (cgSearch) importStepHandler.messages.get(3).obj;
+ assertEquals(Collections.singletonList("GC31J2H"), search.getGeocodes());
+
+ cgCache cache = cgeoapplication.getInstance().getCacheByGeocode("GC31J2H");
+ assertCacheProperties(cache);
+ assertEquals(1, cache.getWaypoints().size()); // this is the original pocket query result without test waypoint
+ }
+
+ public void testImportGpxZipErr() throws IOException {
+ // zip file name doesn't match name of gpx entry
+ File pq1 = new File(tempDir, "1.zip");
+ copyResourceToFile(R.raw.pq7545915, pq1);
+
+ GPXImporter.ImportGpxZipFileThread importThread = new GPXImporter.ImportGpxZipFileThread(pq1, listId, importStepHandler, progressHandler);
+ importThread.run();
+ importStepHandler.waitForCompletion();
+
+ assertEquals(1, importStepHandler.messages.size());
+ assertEquals(GPXImporter.IMPORT_STEP_FINISHED_WITH_ERROR, importStepHandler.messages.get(0).what);
+ }
+
static class TestHandler extends CancellableHandler {
private final List<Message> messages = new ArrayList<Message>();
private long lastMessage = System.currentTimeMillis();