diff options
| author | Bananeweizen <bananeweizen@gmx.de> | 2011-09-19 16:57:53 +0200 |
|---|---|---|
| committer | Bananeweizen <bananeweizen@gmx.de> | 2011-09-19 16:57:53 +0200 |
| commit | 035e145e4cfea3434481d9182843efec6ce258d5 (patch) | |
| tree | 355386e4ecb57b93cc6c9f7d7b778533954660bb /main/src/cgeo/geocaching/files | |
| parent | 418a3902ef9c3b6a51a78fe9c024d4ad2ab07f4f (diff) | |
| download | cgeo-035e145e4cfea3434481d9182843efec6ce258d5.zip cgeo-035e145e4cfea3434481d9182843efec6ce258d5.tar.gz cgeo-035e145e4cfea3434481d9182843efec6ce258d5.tar.bz2 | |
* have static dictionaries in cgBase initialized in static section
(necessary for some unit tests)
* have singleton of application instance, allows removing all the "app"
fields everywhere afterwards
* refactor GPX parser to be independent of c:geo application classes, so
it can be tested much easier
* new unit tests for different GPX versions and sources
* new unit tests for LOC file parsing
Diffstat (limited to 'main/src/cgeo/geocaching/files')
| -rw-r--r-- | main/src/cgeo/geocaching/files/FileParser.java | 9 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPX10Parser.java | 8 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPX11Parser.java | 8 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPXParser.java | 118 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/LocParser.java | 16 |
5 files changed, 87 insertions, 72 deletions
diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java index 158d390..c92b6d2 100644 --- a/main/src/cgeo/geocaching/files/FileParser.java +++ b/main/src/cgeo/geocaching/files/FileParser.java @@ -2,7 +2,6 @@ package cgeo.geocaching.files; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSearch; import android.os.Handler; import android.os.Message; @@ -17,8 +16,8 @@ import java.util.Date; public abstract class FileParser { protected static StringBuilder readFile(File file) throws FileNotFoundException, IOException { - StringBuilder buffer = new StringBuilder(); - BufferedReader input = new BufferedReader(new FileReader(file)); + final StringBuilder buffer = new StringBuilder(); + final BufferedReader input = new BufferedReader(new FileReader(file)); try { String line = null; while ((line = input.readLine()) != null) { @@ -30,10 +29,10 @@ public abstract class FileParser { return buffer; } - static void showFinishedMessage(Handler handler, cgSearch search) { + protected static void showCountMessage(final Handler handler, final int count) { if (handler != null) { final Message msg = new Message(); - msg.obj = search.getCount(); + msg.obj = count; handler.sendMessage(msg); } } diff --git a/main/src/cgeo/geocaching/files/GPX10Parser.java b/main/src/cgeo/geocaching/files/GPX10Parser.java index c3b95b2..85884de 100644 --- a/main/src/cgeo/geocaching/files/GPX10Parser.java +++ b/main/src/cgeo/geocaching/files/GPX10Parser.java @@ -1,15 +1,11 @@ package cgeo.geocaching.files; -import cgeo.geocaching.cgSearch; -import cgeo.geocaching.cgeoapplication; - import android.sax.Element; public final class GPX10Parser extends GPXParser { - public GPX10Parser(cgeoapplication appIn, int listIdIn, - cgSearch searchIn) { - super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/0", "1.0"); + public GPX10Parser(int listIdIn) { + super(listIdIn, "http://www.topografix.com/GPX/1/0", "1.0"); } @Override diff --git a/main/src/cgeo/geocaching/files/GPX11Parser.java b/main/src/cgeo/geocaching/files/GPX11Parser.java index 4c8960b..52a6ae3 100644 --- a/main/src/cgeo/geocaching/files/GPX11Parser.java +++ b/main/src/cgeo/geocaching/files/GPX11Parser.java @@ -1,15 +1,11 @@ package cgeo.geocaching.files; -import cgeo.geocaching.cgSearch; -import cgeo.geocaching.cgeoapplication; - import android.sax.Element; public final class GPX11Parser extends GPXParser { - public GPX11Parser(cgeoapplication appIn, int listIdIn, - cgSearch searchIn) { - super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/1", "1.1"); + public GPX11Parser(int listIdIn) { + super(listIdIn, "http://www.topografix.com/GPX/1/1", "1.1"); } @Override diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 6412564..a424532 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -34,6 +34,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,17 +46,21 @@ public abstract class GPXParser extends FileParser { private static final Pattern patternGeocode = Pattern.compile("([A-Z]{2}[0-9A-Z]+)", Pattern.CASE_INSENSITIVE); private static final Pattern patternGuid = Pattern.compile(".*" + Pattern.quote("guid=") + "([0-9a-z\\-]+)", Pattern.CASE_INSENSITIVE); + /** + * supported groundspeak extensions of the GPX format + */ private static final String[] nsGCList = new String[] { "http://www.groundspeak.com/cache/1/1", // PQ 1.1 "http://www.groundspeak.com/cache/1/0/1", // PQ 1.0.1 "http://www.groundspeak.com/cache/1/0", // PQ 1.0 }; + /** + * supported GSAK extension of the GPX format + */ private static final String GSAK_NS = "http://www.gsak.net/xmlv1/5"; - private static cgeoapplication app = null; private int listId = 1; - private cgSearch search = null; final protected String namespace; final private String version; private Handler handler = null; @@ -69,10 +74,10 @@ public abstract class GPXParser extends FileParser { private String name = null; private String cmt = null; private String desc = null; - protected String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier + protected final String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier private final class UserDataListener implements EndTextElementListener { - private int index; + private final int index; public UserDataListener(int index) { this.index = index; @@ -175,7 +180,7 @@ public abstract class GPXParser extends FileParser { // get text for string String stringName = null; try { - stringName = app.getResources().getResourceName(stringId); + stringName = cgeoapplication.getInstance().getResources().getResourceName(stringId); } catch (NullPointerException e) { return null; } @@ -200,10 +205,8 @@ public abstract class GPXParser extends FileParser { } } - protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) { - app = appIn; + protected GPXParser(int listIdIn, String namespaceIn, String versionIn) { listId = listIdIn; - search = searchIn; namespace = namespaceIn; version = versionIn; } @@ -217,8 +220,9 @@ public abstract class GPXParser extends FileParser { return formatSimple.parse(input); } - public UUID parse(final InputStream stream, Handler handlerIn) { + public List<cgCache> parse(final InputStream stream, Handler handlerIn) { handler = handlerIn; + final List<cgCache> result = new ArrayList<cgCache>(); final RootElement root = new RootElement(namespace, "gpx"); final Element waypoint = root.getChild(namespace, "wpt"); @@ -260,24 +264,12 @@ public abstract class GPXParser extends FileParser { cache.reason = listId; cache.detailed = true; - if (StringUtils.isBlank(cache.personalNote)) { - StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < userData.length; i++) { - if (StringUtils.isNotBlank(userData[i])) { - buffer.append(' ').append(userData[i]); - } - } - String note = buffer.toString().trim(); - if (StringUtils.isNotBlank(note)) { - cache.personalNote = note; - } - } + createNoteFromGSAKUserdata(); - app.addCacheToSearch(search, cache); + result.add(cache); + showCountMessage(handler, result.size()); } - showFinishedMessage(handler, search); - resetCache(); } }); @@ -364,7 +356,7 @@ public abstract class GPXParser extends FileParser { public void end(String url) { final Matcher matcher = patternGuid.matcher(url); if (matcher.matches()) { - String guid = matcher.group(1); + final String guid = matcher.group(1); if (StringUtils.isNotBlank(guid)) { cache.guid = guid; } @@ -698,16 +690,17 @@ public abstract class GPXParser extends FileParser { } catch (SAXException e) { Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString()); } - return parsed ? search.getCurrentId() : null; + + return parsed ? result : null; } - private UUID parse(final File file, final Handler handlerIn) { + private List<cgCache> parse(final File file, final Handler handlerIn) { if (file == null) { return null; } FileInputStream fis = null; - UUID result = null; + List<cgCache> result = null; try { fis = new FileInputStream(file); result = parse(fis, handlerIn); @@ -724,6 +717,13 @@ public abstract class GPXParser extends FileParser { return result; } + /** + * GPX 1.0 and 1.1 use different XML elements to put the cache into, therefore needs to be overwritten in the + * version specific subclasses + * + * @param waypoint + * @return + */ protected abstract Element getCacheParent(Element waypoint); protected static String validate(String input) { @@ -733,8 +733,9 @@ public abstract class GPXParser extends FileParser { return input.trim(); } - private void setType(String parsedString) { - final String knownType = cgBase.cacheTypes.get(parsedString); + private void setType(final String parsedString) { + String lowercase = parsedString.toLowerCase().trim(); + final String knownType = cgBase.cacheTypes.get(lowercase); if (knownType != null) { cache.type = knownType; } @@ -751,15 +752,16 @@ public abstract class GPXParser extends FileParser { } final Matcher matcherGeocode = patternGeocode.matcher(input); if (matcherGeocode.find()) { - if (matcherGeocode.groupCount() > 0) { - final String geocode = matcherGeocode.group(1); - if (ConnectorFactory.canHandle(geocode)) { - cache.geocode = geocode; - } + final String geocode = matcherGeocode.group(1); + if (ConnectorFactory.canHandle(geocode)) { + cache.geocode = geocode; } } } + /** + * reset all fields that are used to store cache fields over the duration of parsing a single cache + */ private void resetCache() { type = null; sym = null; @@ -773,23 +775,47 @@ public abstract class GPXParser extends FileParser { } } - public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) { - final cgSearch search = new cgSearch(); - UUID searchId = null; + /** + * create a cache note from the UserData1 to UserData4 fields supported by GSAK + */ + private void createNoteFromGSAKUserdata() { + if (StringUtils.isBlank(cache.personalNote)) { + final StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < userData.length; i++) { + if (StringUtils.isNotBlank(userData[i])) { + buffer.append(' ').append(userData[i]); + } + } + final String note = buffer.toString().trim(); + if (StringUtils.isNotBlank(note)) { + cache.personalNote = note; + } + } + } + public static UUID parseGPX(File file, int listId, Handler handler) { try { - GPXParser parser = new GPX10Parser(app, listId, search); - searchId = parser.parse(file, handler); - if (searchId == null) { - parser = new GPX11Parser(app, listId, search); - searchId = parser.parse(file, handler); + GPXParser parser = new GPX10Parser(listId); + List<cgCache> caches = parser.parse(file, handler); + if (caches == null) { + parser = new GPX11Parser(listId); + caches = parser.parse(file, handler); } + + if (caches != null) { + final cgSearch search = new cgSearch(); + final cgeoapplication app = cgeoapplication.getInstance(); + for (cgCache cache : caches) { + app.addCacheToSearch(search, cache); + } + Log.i(cgSettings.tag, "Caches found in .gpx file: " + caches.size()); + return search.getCurrentId(); + } + } catch (Exception e) { Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString()); } - Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId)); - - return search.getCurrentId(); + return null; } } diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java index 240d61d..3bb69cd 100644 --- a/main/src/cgeo/geocaching/files/LocParser.java +++ b/main/src/cgeo/geocaching/files/LocParser.java @@ -63,7 +63,7 @@ public final class LocParser extends FileParser { } } - private static Map<String, cgCoord> parseCoordinates( + public static Map<String, cgCoord> parseCoordinates( final String fileContent) { final Map<String, cgCoord> coords = new HashMap<String, cgCoord>(); if (StringUtils.isBlank(fileContent)) { @@ -141,13 +141,12 @@ public final class LocParser extends FileParser { return coords; } - public static UUID parseLoc(cgeoapplication app, File file, int listId, + public static UUID parseLoc(File file, int listId, Handler handler) { - cgSearch search = new cgSearch(); - UUID searchId = null; + final cgSearch search = new cgSearch(); try { - Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString()); + 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(); @@ -162,16 +161,15 @@ public final class LocParser extends FileParser { cache.reason = listId; cache.detailed = false; - app.addCacheToSearch(search, cache); + cgeoapplication.getInstance().addCacheToSearch(search, cache); } caches.totalCnt = caches.cacheList.size(); - showFinishedMessage(handler, search); + showCountMessage(handler, search.getCount()); + Log.i(cgSettings.tag, "Caches found in .gpx file: " + caches.totalCnt); } catch (Exception e) { Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString()); } - Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId)); - return search.getCurrentId(); } } |
