diff options
Diffstat (limited to 'main/src/cgeo/geocaching/files/GPXParser.java')
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPXParser.java | 118 |
1 files changed, 72 insertions, 46 deletions
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; } } |
