aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2011-11-01 19:25:40 +0100
committerBananeweizen <bananeweizen@gmx.de>2011-11-01 19:25:40 +0100
commit6a8f40ccb8c7761e75e4041cb7e53c4df4064573 (patch)
treea890ed1a7a2f3d77cb3babe929e3316666333797 /main/src/cgeo
parenta5571fe16d358c91b60be1f45085d54f16df800b (diff)
parent96fbeff00e6793eed966c15f5829e3d18e16b326 (diff)
downloadcgeo-6a8f40ccb8c7761e75e4041cb7e53c4df4064573.zip
cgeo-6a8f40ccb8c7761e75e4041cb7e53c4df4064573.tar.gz
cgeo-6a8f40ccb8c7761e75e4041cb7e53c4df4064573.tar.bz2
Merge remote branch 'stephanme/importwpt'
Conflicts: main/src/cgeo/geocaching/files/GPXParser.java main/src/cgeo/geocaching/files/LocParser.java tests/src/cgeo/geocaching/files/LocParserTest.java
Diffstat (limited to 'main/src/cgeo')
-rw-r--r--main/src/cgeo/geocaching/cgeogpxes.java228
-rw-r--r--main/src/cgeo/geocaching/files/FileParser.java61
-rw-r--r--main/src/cgeo/geocaching/files/GPXParser.java126
-rw-r--r--main/src/cgeo/geocaching/files/LocParser.java64
-rw-r--r--main/src/cgeo/geocaching/files/ParserException.java24
5 files changed, 284 insertions, 219 deletions
diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java
index 865b9e7..0669f54 100644
--- a/main/src/cgeo/geocaching/cgeogpxes.java
+++ b/main/src/cgeo/geocaching/cgeogpxes.java
@@ -1,30 +1,45 @@
package cgeo.geocaching;
import cgeo.geocaching.files.FileList;
+import cgeo.geocaching.files.GPX10Parser;
+import cgeo.geocaching.files.GPX11Parser;
import cgeo.geocaching.files.GPXParser;
import cgeo.geocaching.files.LocParser;
+import cgeo.geocaching.files.ParserException;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
+import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
+import android.util.Log;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
+import java.util.Collection;
import java.util.List;
public class cgeogpxes extends FileList<cgGPXListAdapter> {
+ public static final String GPX_FILE_EXTENSION = ".gpx";
+ public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = "-wpts.gpx";
private static final String EXTRAS_LIST_ID = "list";
+ static final int IMPORT_STEP_READ_FILE = 1;
+ static final int IMPORT_STEP_READ_WPT_FILE = 2;
+ static final int IMPORT_STEP_STORE_CACHES = 3;
+ static final int IMPORT_STEP_FINISHED = 4;
+ static final int IMPORT_STEP_FINISHED_WITH_ERROR = 5;
+
public cgeogpxes() {
super(new String[] { "gpx", "loc" });
}
@@ -32,28 +47,35 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
private ProgressDialog parseDialog = null;
private int listId = 1;
- final private Handler changeParseDialogHandler = new Handler() {
-
+ final private Handler progressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- if (parseDialog != null) {
- parseDialog.setMessage(res.getString(msg.arg1) + " " + msg.arg2);
- if (msg.obj != null) {
- final int progress = (Integer) msg.obj;
- parseDialog.setProgress(progress);
- }
- }
+ parseDialog.setProgress(msg.arg1);
}
};
- final private Handler loadCachesHandler = new Handler() {
+ final private Handler importStepHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- if (parseDialog != null) {
- parseDialog.dismiss();
+ switch (msg.what) {
+ case IMPORT_STEP_READ_FILE:
+ case IMPORT_STEP_READ_WPT_FILE:
+ case IMPORT_STEP_STORE_CACHES:
+ parseDialog.setMessage(res.getString(msg.arg1));
+ parseDialog.setMax(msg.arg2);
+ parseDialog.setProgress(0);
+ break;
+
+ case IMPORT_STEP_FINISHED:
+ parseDialog.dismiss();
+ helpDialog(res.getString(R.string.gpx_import_title_caches_imported), msg.arg1 + " " + res.getString(R.string.gpx_import_caches_imported));
+ break;
+
+ case IMPORT_STEP_FINISHED_WITH_ERROR:
+ parseDialog.dismiss();
+ helpDialog(res.getString(R.string.gpx_import_title_caches_import_failed), res.getString(msg.arg1) + "\n\n" + msg.obj);
+ break;
}
-
- helpDialog(res.getString(R.string.gpx_import_title_caches_imported), msg.arg1 + " " + res.getString(R.string.gpx_import_caches_imported));
}
};
@@ -86,13 +108,7 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
.setCancelable(false)
.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- try {
- final InputStream attachment = getContentResolver().openInputStream(getIntent().getData());
- importGPX(attachment);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ importGPX((Uri) getIntent().getData(), getContentResolver());
}
})
.setNegativeButton(getString(android.R.string.no), new DialogInterface.OnClickListener() {
@@ -111,64 +127,167 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
}
public void importGPX(final File file) {
- createProgressDialog((int) file.length());
- new ImportFileThread(file).start();
+ createProgressDialog();
+ if (StringUtils.endsWithIgnoreCase(file.getName(), GPX_FILE_EXTENSION)) {
+ new ImportGpxFileThread(file, listId, importStepHandler, progressHandler).start();
+ } else {
+ new ImportLocFileThread(file, listId, importStepHandler, progressHandler).start();
+ }
}
- public void importGPX(final InputStream stream) {
- createProgressDialog(-1);
- new ImportStreamThread(stream).start();
+ public void importGPX(final Uri uri, ContentResolver contentResolver) {
+ createProgressDialog();
+ new ImportAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start();
}
- private void createProgressDialog(int maxBytes) {
+ private void createProgressDialog() {
parseDialog = new ProgressDialog(this);
parseDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
parseDialog.setTitle(res.getString(R.string.gpx_import_title_reading_file));
parseDialog.setMessage(res.getString(R.string.gpx_import_loading));
parseDialog.setCancelable(false);
- parseDialog.setMax(maxBytes);
+ parseDialog.setMax(-1);
parseDialog.show();
}
- private abstract class ImportThread extends Thread {
+ static abstract class ImportThread extends Thread {
+ final int listId;
+ final Handler importStepHandler;
+ final Handler progressHandler;
+
+ public ImportThread(int listId, Handler importStepHandler, Handler progressHandler) {
+ this.listId = listId;
+ this.importStepHandler = importStepHandler;
+ this.progressHandler = progressHandler;
+ }
@Override
public void run() {
- final cgSearch search = doImport();
- loadCachesHandler.sendMessage(loadCachesHandler.obtainMessage(0, cgeoapplication.getCount(search), 0));
+ final Collection<cgCache> caches;
+ try {
+ caches = doImport();
+
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_STORE_CACHES, R.string.gpx_import_storing, caches.size()));
+ cgSearch search = storeParsedCaches(caches);
+ Log.i(Settings.tag, "Imported successfully " + caches.size() + " caches.");
+
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, cgeoapplication.getCount(search), 0, search));
+ } catch (IOException e) {
+ Log.i(Settings.tag, "Importing caches failed - error reading data: " + e.getMessage());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_io, 0, e.getLocalizedMessage()));
+ } catch (ParserException e) {
+ Log.i(Settings.tag, "Importing caches failed - data format error" + e.getMessage());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_parser, 0, e.getLocalizedMessage()));
+ } catch (Exception e) {
+ Log.e(Settings.tag, "Importing caches failed - unknown error: ", e);
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_unexpected, 0, e.getLocalizedMessage()));
+ }
}
- protected abstract cgSearch doImport();
+ protected abstract Collection<cgCache> doImport() throws IOException, ParserException;
+
+ private cgSearch storeParsedCaches(Collection<cgCache> caches) {
+ final cgSearch search = new cgSearch();
+ final cgeoapplication app = cgeoapplication.getInstance();
+ int storedCaches = 0;
+ for (cgCache cache : caches) {
+ // remove from cache because a cache might be re-imported
+ app.removeCacheFromCache(cache.getGeocode());
+ app.addCacheToSearch(search, cache);
+ progressHandler.sendMessage(progressHandler.obtainMessage(0, ++storedCaches, 0));
+ }
+ return search;
+ }
}
- private class ImportFileThread extends ImportThread {
- private final File file;
+ static class ImportGpxFileThread extends ImportThread {
+ private final File cacheFile;
- public ImportFileThread(final File file) {
- this.file = file;
+ public ImportGpxFileThread(final File file, int listId, Handler importStepHandler, Handler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.cacheFile = file;
}
@Override
- protected cgSearch doImport() {
- if (StringUtils.endsWithIgnoreCase(file.getName(), GPXParser.GPX_FILE_EXTENSION)) {
- return GPXParser.importGPX(file, listId, changeParseDialogHandler);
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ Log.i(Settings.tag, "Import GPX file: " + cacheFile.getAbsolutePath());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) cacheFile.length()));
+ Collection<cgCache> caches;
+ GPXParser parser;
+ try {
+ // try to parse cache file as GPX 10
+ parser = new GPX10Parser(listId);
+ caches = parser.parse(cacheFile, progressHandler);
+ } catch (ParserException pe) {
+ // didn't work -> lets try GPX11
+ parser = new GPX11Parser(listId);
+ caches = parser.parse(cacheFile, progressHandler);
}
- else {
- return LocParser.parseLoc(file, listId, changeParseDialogHandler);
+
+ final File wptsFile = getWaypointsFileForGpx(cacheFile);
+ 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()));
+ caches = parser.parse(wptsFile, progressHandler);
}
+
+ return caches;
+ }
+ }
+
+ static class ImportLocFileThread extends ImportThread {
+ private final File file;
+
+ public ImportLocFileThread(final File file, int listId, Handler importStepHandler, Handler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.file = file;
+ }
+
+ @Override
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ Log.i(Settings.tag, "Import LOC file: " + file.getAbsolutePath());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) file.length()));
+ LocParser parser = new LocParser(listId);
+ return parser.parse(file, progressHandler);
}
}
- private class ImportStreamThread extends ImportThread {
- private final InputStream stream;
+ static class ImportAttachmentThread extends ImportThread {
+ private final Uri uri;
+ private ContentResolver contentResolver;
- public ImportStreamThread(InputStream stream) {
- this.stream = stream;
+ public ImportAttachmentThread(Uri uri, ContentResolver contentResolver, int listId, Handler importStepHandler, Handler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.uri = uri;
+ this.contentResolver = contentResolver;
}
@Override
- protected cgSearch doImport() {
- return GPXParser.importGPX(stream, listId, changeParseDialogHandler);
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ Log.i(Settings.tag, "Import GPX from uri: " + uri);
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, -1));
+
+ Collection<cgCache> caches;
+ GPXParser parser;
+ try {
+ // try to parse cache file as GPX 10
+ parser = new GPX10Parser(listId);
+ caches = parseAttachement(parser);
+ } catch (ParserException pe) {
+ // didn't work -> lets try GPX11
+ parser = new GPX11Parser(listId);
+ caches = parseAttachement(parser);
+ }
+ return caches;
+ }
+
+ private Collection<cgCache> parseAttachement(GPXParser parser) throws IOException, ParserException {
+ InputStream is = contentResolver.openInputStream(uri);
+ try {
+ return parser.parse(is, progressHandler);
+ } finally {
+ is.close();
+ }
}
}
@@ -182,8 +301,19 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
protected boolean filenameBelongsToList(final String filename) {
if (super.filenameBelongsToList(filename)) {
// filter out waypoint files
- return !StringUtils.endsWithIgnoreCase(filename, GPXParser.WAYPOINTS_FILE_SUFFIX_AND_EXTENSION);
+ return !StringUtils.endsWithIgnoreCase(filename, WAYPOINTS_FILE_SUFFIX_AND_EXTENSION);
}
return false;
}
+
+ // 1234567.gpx -> 1234567-wpts.gpx
+ static File getWaypointsFileForGpx(File file) {
+ final String name = file.getName();
+ 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);
+ } else {
+ return null;
+ }
+ }
}
diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java
index 1083c65..a803c2b 100644
--- a/main/src/cgeo/geocaching/files/FileParser.java
+++ b/main/src/cgeo/geocaching/files/FileParser.java
@@ -6,36 +6,66 @@ import android.os.Handler;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collection;
import java.util.Date;
public abstract class FileParser {
- protected static StringBuilder readFile(File file)
- throws FileNotFoundException, IOException {
+ /**
+ * Parses caches from input stream.
+ *
+ * @param stream
+ * @param progressHandler
+ * for reporting parsing progress (in bytes read from input stream)
+ * @return collection of parsed caches
+ * @throws IOException
+ * if the input stream can't be read
+ * @throws ParserException
+ * if the input stream contains data not matching the file format of the parser
+ */
+ public abstract Collection<cgCache> parse(final InputStream stream, final Handler progressHandler) throws IOException, ParserException;
+
+ /**
+ * Convenience method for parsing a file.
+ *
+ * @param file
+ * @param progressHandler
+ * @return
+ * @throws IOException
+ * @throws ParserException
+ */
+ public Collection<cgCache> parse(final File file, final Handler progressHandler) throws IOException, ParserException {
+ FileInputStream fis = new FileInputStream(file);
+ try {
+ return parse(fis, progressHandler);
+ } finally {
+ fis.close();
+ }
+ }
+
+ protected static StringBuilder readStream(InputStream is, Handler progressHandler) throws IOException {
final StringBuilder buffer = new StringBuilder();
- final BufferedReader input = new BufferedReader(new FileReader(file));
+ ProgressInputStream progressInputStream = new ProgressInputStream(is);
+ final BufferedReader input = new BufferedReader(new InputStreamReader(progressInputStream));
+
try {
String line = null;
while ((line = input.readLine()) != null) {
buffer.append(line);
+ showProgressMessage(progressHandler, progressInputStream.getProgress());
}
+ return buffer;
} finally {
input.close();
}
- return buffer;
}
- protected static void showCountMessage(final Handler handler, final int msgId, final int count) {
- if (handler != null && (count <= 1 || count % 10 == 0)) {
- handler.sendMessage(handler.obtainMessage(0, msgId, count));
- }
- }
-
- protected static void showCountMessage(final Handler handler, final int msgId, final int count, final int bytesRead) {
- if (handler != null && (count <= 1 || count % 10 == 0)) {
- handler.sendMessage(handler.obtainMessage(0, msgId, count, bytesRead));
+ protected static void showProgressMessage(final Handler handler, final int bytesRead) {
+ if (handler != null) {
+ handler.sendMessage(handler.obtainMessage(0, bytesRead, 0));
}
}
@@ -49,5 +79,4 @@ public abstract class FileParser {
cache.setUpdated(time);
cache.setDetailedUpdate(time);
}
-
}
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java
index 900c83b..01929c6 100644
--- a/main/src/cgeo/geocaching/files/GPXParser.java
+++ b/main/src/cgeo/geocaching/files/GPXParser.java
@@ -5,7 +5,6 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgLog;
-import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgTrackable;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
@@ -28,9 +27,6 @@ import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
@@ -66,15 +62,11 @@ public abstract class GPXParser extends FileParser {
*/
private static final String GSAK_NS = "http://www.gsak.net/xmlv1/5";
- public static final String GPX_FILE_EXTENSION = ".gpx";
- public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = "-wpts.gpx";
private static final Pattern PATTERN_MILLISECONDS = Pattern.compile("\\.\\d{3}");
private int listId = 1;
final protected String namespace;
final private String version;
- private Handler handler = null;
- private int importedRecords;
private cgCache cache = new cgCache();
private cgTrackable trackable = new cgTrackable();
@@ -243,10 +235,7 @@ public abstract class GPXParser extends FileParser {
return formatSimple.parse(input);
}
- boolean parse(final InputStream stream, Handler handlerIn) {
- importedRecords = 0;
- handler = handlerIn;
-
+ public Collection<cgCache> parse(final InputStream stream, final Handler progressHandler) throws IOException, ParserException {
final RootElement root = new RootElement(namespace, "gpx");
final Element waypoint = root.getChild(namespace, "wpt");
@@ -290,7 +279,7 @@ public abstract class GPXParser extends FileParser {
createNoteFromGSAKUserdata();
result.put(cache.getGeocode(), cache);
- showCountMessage(handler, R.string.gpx_import_loading_caches, ++importedRecords, progressStream.getProgress());
+ showProgressMessage(progressHandler, progressStream.getProgress());
} else if (StringUtils.isNotBlank(cache.getName())
&& cache.getCoords() != null
&& StringUtils.contains(type, "waypoint")) {
@@ -325,7 +314,7 @@ public abstract class GPXParser extends FileParser {
}
cgWaypoint.mergeWayPoints(cacheForWaypoint.getWaypoints(), Collections.singletonList(waypoint));
result.put(cacheGeocodeForWaypoint, cacheForWaypoint);
- showCountMessage(handler, R.string.gpx_import_loading_waypoints, ++importedRecords, progressStream.getProgress());
+ showProgressMessage(progressHandler, progressStream.getProgress());
}
}
}
@@ -740,41 +729,11 @@ public abstract class GPXParser extends FileParser {
try {
progressStream = new ProgressInputStream(stream);
Xml.parse(progressStream, Xml.Encoding.UTF_8, root.getContentHandler());
- return true;
- } catch (IOException e) {
- Log.e(Settings.tag, "Cannot parse .gpx file as GPX " + version + ": could not read file!");
+ return result.values();
} catch (SAXException e) {
Log.e(Settings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString());
+ throw new ParserException("Cannot parse .gpx file as GPX " + version + ": could not parse XML", e);
}
- return false;
- }
-
- private boolean parse(final File file, final Handler handlerIn) {
- if (file == null) {
- return false;
- }
-
- FileInputStream fis = null;
- boolean parsed = false;
- try {
- fis = new FileInputStream(file);
- parsed = parse(fis, handlerIn);
- } catch (FileNotFoundException e) {
- Log.e(Settings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!");
- } finally {
- try {
- if (fis != null) {
- fis.close();
- }
- } catch (IOException e) {
- Log.e(Settings.tag, "Error after parsing .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not close file!");
- }
- }
- return parsed;
- }
-
- public Collection<cgCache> getParsedCaches() {
- return result.values();
}
/**
@@ -855,79 +814,4 @@ public abstract class GPXParser extends FileParser {
}
}
}
-
- public static cgSearch importGPX(File file, int listId, Handler handler) {
- try {
- // parse cache file
- GPXParser parser = new GPX10Parser(listId);
- boolean parsed = parser.parse(file, handler);
- if (!parsed) {
- parser = new GPX11Parser(listId);
- parsed = parser.parse(file, handler);
- }
-
- // parse waypoint file if exists
- if (parsed) {
- final File wptsFile = getWaypointsFileForGpx(file);
- if (wptsFile != null && wptsFile.canRead()) {
- parser.parse(wptsFile, handler);
- }
- }
-
- if (parsed) {
- return storeParsedCaches(handler, parser);
- }
-
- } catch (Exception e) {
- Log.e(Settings.tag, "GPXParser.importGPX: " + e.toString());
- }
-
- return null;
- }
-
- public static cgSearch importGPX(InputStream stream, int listId, Handler handler) {
- try {
- // parse cache file
- GPXParser parser = new GPX10Parser(listId);
- boolean parsed = parser.parse(stream, handler);
- if (!parsed) {
- parser = new GPX11Parser(listId);
- parsed = parser.parse(stream, handler);
- }
-
- if (parsed) {
- return storeParsedCaches(handler, parser);
- }
-
- } catch (Exception e) {
- Log.e(Settings.tag, "GPXParser.importGPX: " + e.toString());
- }
-
- return null;
- }
-
- private static cgSearch storeParsedCaches(Handler handler, GPXParser parser) {
- final cgSearch search = new cgSearch();
- final cgeoapplication app = cgeoapplication.getInstance();
- int storedCaches = 0;
- for (cgCache cache : parser.getParsedCaches()) {
- // remove from cache, cache can be re-imported
- app.removeCacheFromCache(cache.getGeocode());
- app.addCacheToSearch(search, cache);
- showCountMessage(handler, R.string.gpx_import_storing, ++storedCaches);
- }
- Log.i(Settings.tag, "Caches found in .gpx file: " + parser.getParsedCaches().size());
- return search;
- }
-
- // 1234567.gpx -> 1234567-wpts.gpx
- static File getWaypointsFileForGpx(File file) {
- final String name = file.getName();
- 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);
- } else {
- return null;
- }
- }
}
diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java
index 5baaeac..e21b2c2 100644
--- a/main/src/cgeo/geocaching/files/LocParser.java
+++ b/main/src/cgeo/geocaching/files/LocParser.java
@@ -1,12 +1,9 @@
package cgeo.geocaching.files;
-import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgCacheWrap;
import cgeo.geocaching.cgCoord;
-import cgeo.geocaching.cgSearch;
-import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.GeopointParser;
@@ -16,8 +13,12 @@ import org.apache.commons.lang3.StringUtils;
import android.os.Handler;
import android.util.Log;
-import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
@@ -39,6 +40,8 @@ public final class LocParser extends FileParser {
.compile("<container>([^<]+)</container>");
private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
+ private int listId;
+
public static void parseLoc(final cgCacheWrap caches,
final String fileContent) {
final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
@@ -64,7 +67,7 @@ public final class LocParser extends FileParser {
}
}
- public static Map<String, cgCoord> parseCoordinates(
+ static Map<String, cgCoord> parseCoordinates(
final String fileContent) {
final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
if (StringUtils.isBlank(fileContent)) {
@@ -137,36 +140,31 @@ public final class LocParser extends FileParser {
return coords;
}
- public static cgSearch parseLoc(File file, int listId,
- Handler handler) {
- final cgSearch search = new cgSearch();
-
- try {
- final Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
- final cgCacheWrap caches = new cgCacheWrap();
- for (Entry<String, cgCoord> entry : coords.entrySet()) {
- cgCoord coord = entry.getValue();
- if (StringUtils.isBlank(coord.getGeocode()) || StringUtils.isBlank(coord.getName())) {
- continue;
- }
- cgCache cache = new cgCache();
- copyCoordToCache(coord, cache);
- caches.cacheList.add(cache);
-
- fixCache(cache);
- cache.setCacheType(CacheType.UNKNOWN); // type is not given in the LOC file
- cache.setReason(listId);
- cache.setDetailed(true);
+ public LocParser(int listId) {
+ this.listId = listId;
+ }
- cgeoapplication.getInstance().addCacheToSearch(search, cache);
+ @Override
+ public Collection<cgCache> parse(InputStream stream, Handler progressHandler) throws IOException, ParserException {
+ // TODO: progress reporting happens during reading stream only, not during parsing
+ String streamContent = readStream(stream, progressHandler).toString();
+ final Map<String, cgCoord> coords = parseCoordinates(streamContent);
+ final List<cgCache> caches = new ArrayList<cgCache>();
+ for (Entry<String, cgCoord> entry : coords.entrySet()) {
+ cgCoord coord = entry.getValue();
+ if (StringUtils.isBlank(coord.getGeocode()) || StringUtils.isBlank(coord.getName())) {
+ continue;
}
- caches.totalCnt = caches.cacheList.size();
- showCountMessage(handler, R.string.gpx_import_loading_stored, search.getCount());
- Log.i(Settings.tag, "Caches found in .loc file: " + caches.totalCnt);
- } catch (Exception e) {
- Log.e(Settings.tag, "LocParser.parseLoc: " + e.toString());
+ cgCache cache = new cgCache();
+ copyCoordToCache(coord, cache);
+ caches.add(cache);
+
+ fixCache(cache);
+ cache.setCacheType(CacheType.UNKNOWN); // type is not given in the LOC file
+ cache.setReason(listId);
+ cache.setDetailed(true);
}
-
- return search;
+ Log.i(Settings.tag, "Caches found in .loc file: " + caches.size());
+ return caches;
}
}
diff --git a/main/src/cgeo/geocaching/files/ParserException.java b/main/src/cgeo/geocaching/files/ParserException.java
new file mode 100644
index 0000000..5aa152c
--- /dev/null
+++ b/main/src/cgeo/geocaching/files/ParserException.java
@@ -0,0 +1,24 @@
+package cgeo.geocaching.files;
+
+/**
+ * Exception indicating that a FileParser (GPX or LOC) could not parse the file due to bad file format.
+ */
+public class ParserException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public ParserException() {
+ }
+
+ public ParserException(String detailMessage) {
+ super(detailMessage);
+ }
+
+ public ParserException(Throwable throwable) {
+ super(throwable);
+ }
+
+ public ParserException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+}