diff options
author | Bananeweizen <bananeweizen@gmx.de> | 2011-11-01 19:25:40 +0100 |
---|---|---|
committer | Bananeweizen <bananeweizen@gmx.de> | 2011-11-01 19:25:40 +0100 |
commit | 6a8f40ccb8c7761e75e4041cb7e53c4df4064573 (patch) | |
tree | a890ed1a7a2f3d77cb3babe929e3316666333797 /main/src/cgeo | |
parent | a5571fe16d358c91b60be1f45085d54f16df800b (diff) | |
parent | 96fbeff00e6793eed966c15f5829e3d18e16b326 (diff) | |
download | cgeo-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.java | 228 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/files/FileParser.java | 61 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/files/GPXParser.java | 126 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/files/LocParser.java | 64 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/files/ParserException.java | 24 |
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); + } + +} |