diff options
Diffstat (limited to 'main/src/cgeo/geocaching/files/GPXParser.java')
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPXParser.java | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 7ea0a39..3e96291 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -1,13 +1,12 @@ package cgeo.geocaching.files; +import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; -import cgeo.geocaching.StoredList; import cgeo.geocaching.Trackable; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; -import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; @@ -17,9 +16,11 @@ import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.list.StoredList; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.SynchronizedDateFormat; import org.apache.commons.lang3.StringUtils; import org.xml.sax.Attributes; @@ -35,7 +36,6 @@ import android.util.Xml; import java.io.IOException; import java.io.InputStream; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -47,9 +47,9 @@ import java.util.regex.Pattern; public abstract class GPXParser extends FileParser { - private static final SimpleDateFormat formatSimple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); // 2010-04-20T07:00:00 - private static final SimpleDateFormat formatSimpleZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); // 2010-04-20T07:00:00Z - private static final SimpleDateFormat formatTimezone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US); // 2010-04-20T01:01:03-04:00 + private static final SynchronizedDateFormat formatSimple = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); // 2010-04-20T07:00:00 + private static final SynchronizedDateFormat formatSimpleZ = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); // 2010-04-20T07:00:00Z + private static final SynchronizedDateFormat formatTimezone = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US); // 2010-04-20T01:01:03-04:00 /** * Attention: case sensitive geocode pattern to avoid matching normal words in the name or description of the cache. @@ -70,9 +70,14 @@ public abstract class GPXParser extends FileParser { * supported GSAK extension of the GPX format */ private static final String[] GSAK_NS = new String[] { + "http://www.gsak.net/xmlv1/4", "http://www.gsak.net/xmlv1/5", "http://www.gsak.net/xmlv1/6" }; + /** + * c:geo extensions of the gpx format + */ + private static final String CGEO_NS = "http://www.cgeo.org/wptext/1/0"; private static final Pattern PATTERN_MILLISECONDS = Pattern.compile("\\.\\d{3,7}"); @@ -90,6 +95,9 @@ public abstract class GPXParser extends FileParser { private String cmt = null; private String desc = null; protected final String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier + private String parentCacheCode = null; + private boolean wptVisited = false; + private boolean wptUserDefined = false; /** * Parser result. Maps geocode to cache. @@ -205,7 +213,7 @@ public abstract class GPXParser extends FileParser { // get text for string String stringName; try { - stringName = cgeoapplication.getInstance().getResources().getResourceName(stringId); + stringName = CgeoApplication.getInstance().getResources().getResourceName(stringId); } catch (final NullPointerException e) { return null; } @@ -272,7 +280,7 @@ public abstract class GPXParser extends FileParser { Double.valueOf(longitude))); } } - } catch (final Exception e) { + } catch (final NumberFormatException e) { Log.w("Failed to parse waypoint's latitude and/or longitude."); } } @@ -312,10 +320,10 @@ public abstract class GPXParser extends FileParser { // finally store the cache in the database result.add(geocode); - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); // avoid the cachecache using lots of memory for caches which the user did not actually look at - cgData.removeAllFromCache(); + DataStore.removeAllFromCache(); showProgressMessage(progressHandler, progressStream.getProgress()); } else if (StringUtils.isNotBlank(cache.getName()) && StringUtils.containsIgnoreCase(type, "waypoint")) { @@ -328,20 +336,25 @@ public abstract class GPXParser extends FileParser { private void addWaypointToCache() { fixCache(cache); - if (cache.getName().length() > 2) { - final String cacheGeocodeForWaypoint = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); + if (cache.getName().length() > 2 || StringUtils.isNotBlank(parentCacheCode)) { + if (StringUtils.isBlank(parentCacheCode)) { + parentCacheCode = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); + } // lookup cache for waypoint in already parsed caches - final Geocache cacheForWaypoint = cgData.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cacheForWaypoint = DataStore.loadCache(parentCacheCode, LoadFlags.LOAD_CACHE_OR_DB); if (cacheForWaypoint != null) { final Waypoint waypoint = new Waypoint(cache.getShortDescription(), convertWaypointSym2Type(sym), false); + if (wptUserDefined) { + waypoint.setUserDefined(); + } waypoint.setId(-1); - waypoint.setGeocode(cacheGeocodeForWaypoint); - waypoint.setPrefix(cache.getName().substring(0, 2)); + waypoint.setGeocode(parentCacheCode); + waypoint.setPrefix(cacheForWaypoint.getWaypointPrefix(cache.getName())); waypoint.setLookup("---"); // there is no lookup code in gpx file waypoint.setCoords(cache.getCoords()); waypoint.setNote(cache.getDescription()); - + waypoint.setVisited(wptVisited); final ArrayList<Waypoint> mergedWayPoints = new ArrayList<Waypoint>(); mergedWayPoints.addAll(cacheForWaypoint.getWaypoints()); @@ -349,7 +362,7 @@ public abstract class GPXParser extends FileParser { newPoints.add(waypoint); Waypoint.mergeWayPoints(newPoints, mergedWayPoints, true); cacheForWaypoint.setWaypoints(newPoints, false); - cgData.saveCache(cacheForWaypoint, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cacheForWaypoint, EnumSet.of(SaveFlag.SAVE_DB)); showProgressMessage(progressHandler, progressStream.getProgress()); } } @@ -480,8 +493,37 @@ public abstract class GPXParser extends FileParser { for (int i = 2; i <= 4; i++) { gsak.getChild(gsakNamespace, "User" + i).setEndTextElementListener(new UserDataListener(i)); } + + gsak.getChild(gsakNamespace, "Parent").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + parentCacheCode = body; + } + }); } + // c:geo extensions + final Element cgeoVisited = cacheParent.getChild(CGEO_NS, "visited"); + + cgeoVisited.setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String visited) { + wptVisited = Boolean.valueOf(visited.trim()); + } + }); + + final Element cgeoUserDefined = cacheParent.getChild(CGEO_NS, "userdefined"); + + cgeoUserDefined.setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String userDefined) { + wptUserDefined = Boolean.valueOf(userDefined.trim()); + } + }); + // 3 different versions of the GC schema for (final String nsGC : GROUNDSPEAK_NAMESPACE) { // waypoints.cache @@ -501,7 +543,7 @@ public abstract class GPXParser extends FileParser { if (attrs.getIndex("available") > -1) { cache.setDisabled(!attrs.getValue("available").equalsIgnoreCase("true")); } - } catch (final Exception e) { + } catch (final RuntimeException e) { Log.w("Failed to parse cache attributes."); } } @@ -680,7 +722,7 @@ public abstract class GPXParser extends FileParser { if (attrs.getIndex("ref") > -1) { trackable.setGeocode(attrs.getValue("ref")); } - } catch (final Exception e) { + } catch (final RuntimeException e) { // nothing } } @@ -724,7 +766,7 @@ public abstract class GPXParser extends FileParser { if (attrs.getIndex("id") > -1) { log.id = Integer.parseInt(attrs.getValue("id")); } - } catch (final Exception e) { + } catch (final NumberFormatException e) { // nothing } } @@ -785,9 +827,8 @@ public abstract class GPXParser extends FileParser { try { progressStream = new ProgressInputStream(stream); Xml.parse(progressStream, Xml.Encoding.UTF_8, root.getContentHandler()); - return cgData.loadCaches(result, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); + return DataStore.loadCaches(result, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); } catch (final SAXException e) { - Log.w("Cannot parse .gpx file as GPX " + version + ": could not parse XML - ", e); throw new ParserException("Cannot parse .gpx file as GPX " + version + ": could not parse XML", e); } } @@ -870,6 +911,9 @@ public abstract class GPXParser extends FileParser { name = null; desc = null; cmt = null; + parentCacheCode = null; + wptVisited = false; + wptUserDefined = false; cache = new Geocache(this); |
