aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching/files/GPXParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgeo/geocaching/files/GPXParser.java')
-rw-r--r--src/cgeo/geocaching/files/GPXParser.java176
1 files changed, 169 insertions, 7 deletions
diff --git a/src/cgeo/geocaching/files/GPXParser.java b/src/cgeo/geocaching/files/GPXParser.java
index c96e30c..e6b5748 100644
--- a/src/cgeo/geocaching/files/GPXParser.java
+++ b/src/cgeo/geocaching/files/GPXParser.java
@@ -23,6 +23,7 @@ import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;
+import cgeo.geocaching.R;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgLog;
@@ -54,6 +55,7 @@ public abstract class GPXParser extends FileParser {
private cgCache cache = new cgCache();
private cgTrackable trackable = new cgTrackable();
private cgLog log = new cgLog();
+ private CacheAttribute cacheAttribute = null;
private String type = null;
private String sym = null;
@@ -61,7 +63,123 @@ public abstract class GPXParser extends FileParser {
private String cmt = null;
private String desc = null;
- public GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) {
+ private class CacheAttribute {
+ // List of cache attributes matching IDs used in GPX files.
+ // The ID is represented by the position of the String in the array.
+ // Strings are not used as text but as resource IDs of strings, just to be aware of changes
+ // made in strings.xml which then will lead to compile errors here and not to runtime errors.
+ private final int[] CACHE_ATTRIBUTES = {
+ -1, // 0
+ R.string.attribute_dogs_yes, // 1
+ R.string.attribute_fee_yes, // 2
+ R.string.attribute_rappelling_yes, // 3
+ R.string.attribute_boat_yes, // 4
+ R.string.attribute_scuba_yes, // 5
+ R.string.attribute_kids_yes, // 6
+ R.string.attribute_onehour_yes, // 7
+ R.string.attribute_scenic_yes, // 8
+ R.string.attribute_hiking_yes, // 9
+ R.string.attribute_climbing_yes, // 10
+ R.string.attribute_wading_yes, // 11
+ R.string.attribute_swimming_yes, // 12
+ R.string.attribute_available_yes, // 13
+ R.string.attribute_night_yes, // 14
+ R.string.attribute_winter_yes, // 15
+ -1, // 16
+ R.string.attribute_poisonoak_yes, // 17
+ R.string.attribute_dangerousanimals_yes, // 18
+ R.string.attribute_ticks_yes, // 19
+ R.string.attribute_mine_yes, // 20
+ R.string.attribute_cliff_yes, // 21
+ R.string.attribute_hunting_yes, // 22
+ R.string.attribute_danger_yes, // 23
+ R.string.attribute_wheelchair_yes, // 24
+ R.string.attribute_parking_yes, // 25
+ R.string.attribute_public_yes, // 26
+ R.string.attribute_water_yes, // 27
+ R.string.attribute_restrooms_yes, // 28
+ R.string.attribute_phone_yes, // 29
+ R.string.attribute_picnic_yes, // 30
+ R.string.attribute_camping_yes, // 31
+ R.string.attribute_bicycles_yes, // 32
+ R.string.attribute_motorcycles_yes, // 33
+ R.string.attribute_quads_yes, // 34
+ R.string.attribute_jeeps_yes, // 35
+ R.string.attribute_snowmobiles_yes, // 36
+ R.string.attribute_horses_yes, // 37
+ R.string.attribute_campfires_yes, // 38
+ R.string.attribute_thorn_yes, // 39
+ R.string.attribute_stealth_yes, // 40
+ R.string.attribute_stroller_yes, // 41
+ R.string.attribute_firstaid_yes, // 42
+ R.string.attribute_cow_yes, // 43
+ R.string.attribute_flashlight_yes, // 44
+ R.string.attribute_landf_yes, // 45
+ R.string.attribute_rv_yes, // 46
+ R.string.attribute_field_puzzle_yes, // 47
+ R.string.attribute_uv_yes, // 48
+ R.string.attribute_snowshoes_yes, // 49
+ R.string.attribute_skiis_yes, // 50
+ R.string.attribute_s_tool_yes, // 51
+ R.string.attribute_nightcache_yes, // 52
+ R.string.attribute_parkngrab_yes, // 53
+ R.string.attribute_abandonedbuilding_yes, // 54
+ R.string.attribute_hike_short_yes, // 55
+ R.string.attribute_hike_med_yes, // 56
+ R.string.attribute_hike_long_yes, // 57
+ R.string.attribute_fuel_yes, // 58
+ R.string.attribute_food_yes, // 59
+ R.string.attribute_wirelessbeacon_yes, // 60
+ R.string.attribute_partnership_yes, // 61
+ R.string.attribute_seasonal_yes, // 62
+ R.string.attribute_touristok_yes, // 63
+ R.string.attribute_treeclimbing_yes, // 64
+ R.string.attribute_frontyard_yes, // 65
+ R.string.attribute_teamwork_yes, // 66
+ };
+ private static final String YES = "_yes";
+ private static final String NO = "_no";
+ private final Pattern BASENAME_PATTERN = Pattern.compile("^.*attribute_(.*)(_yes|_no)");
+
+ private Boolean active = null; // for yes/no
+ private String baseName; // "food", "parkngrab", ...
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+ // map GPX-Attribute-Id to baseName
+ public void setBaseName(int id) {
+ this.baseName = null;
+ // get String out of array
+ if (CACHE_ATTRIBUTES.length <= id)
+ return;
+ int stringId = CACHE_ATTRIBUTES[id];
+ if (stringId == -1)
+ return; // id not found
+ // get text for string
+ String stringName = null;
+ try {
+ stringName = app.getResources().getResourceName(stringId);
+ } catch (NullPointerException e) {
+ return;
+ }
+ if (stringName == null)
+ return;
+ // cut out baseName
+ Matcher m = BASENAME_PATTERN.matcher(stringName);
+ if (! m.matches())
+ return;
+ this.baseName = m.group(1);
+ }
+ // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes"
+ public String getInternalId() {
+ if (baseName == null || active == null)
+ return null;
+ return baseName + (active ? YES : NO);
+ }
+ }
+
+ protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) {
app = appIn;
listId = listIdIn;
search = searchIn;
@@ -278,7 +396,51 @@ public abstract class GPXParser extends FileParser {
}
});
- // waypoint.cache.difficulty
+ // waypoint.cache.attributes
+ // @see issue #299
+
+ // <groundspeak:attributes>
+ // <groundspeak:attribute id="32" inc="1">Bicycles</groundspeak:attribute>
+ // <groundspeak:attribute id="13" inc="1">Available at all times</groundspeak:attribute>
+ // where inc = 0 => _no, inc = 1 => _yes
+ // IDs see array CACHE_ATTRIBUTES
+ final Element gcAttributes = gcCache.getChild(nsGC, "attributes");
+
+ // waypoint.cache.attribute
+ final Element gcAttribute = gcAttributes.getChild(nsGC, "attribute");
+
+ gcAttribute.setStartElementListener(new StartElementListener() {
+ @Override
+ public void start(Attributes attrs) {
+ cacheAttribute = new CacheAttribute();
+ try {
+ if (attrs.getIndex("id") > -1) {
+ cacheAttribute.setBaseName(Integer.parseInt(attrs.getValue("id")));
+ }
+ if (attrs.getIndex("inc") > -1) {
+ cacheAttribute.setActive(Integer.parseInt(attrs.getValue("inc")) != 0);
+ }
+ } catch (Exception e) {
+ // nothing
+ }
+ }
+ });
+
+ gcAttribute.setEndElementListener(new EndElementListener() {
+ @Override
+ public void end() {
+ if (cacheAttribute != null) {
+ String internalId = cacheAttribute.getInternalId();
+ if (internalId != null) {
+ if (cache.attributes == null)
+ cache.attributes = new ArrayList<String>();
+ cache.attributes.add(internalId);
+ }
+ }
+ }
+ });
+
+ // waypoint.cache.difficulty
gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() {
@Override
@@ -489,16 +651,16 @@ 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() : 0l;
+ return parsed ? search.getCurrentId() : 0L;
}
private long parse(final File file, final Handler handlerIn) {
if (file == null) {
- return 0l;
+ return 0L;
}
FileInputStream fis = null;
- long result = 0l;
+ long result = 0L;
try {
fis = new FileInputStream(file);
result = parse(fis, handlerIn);
@@ -553,12 +715,12 @@ public abstract class GPXParser extends FileParser {
public static Long parseGPX(cgeoapplication app, File file, int listId, Handler handler) {
cgSearch search = new cgSearch();
- long searchId = 0l;
+ long searchId = 0L;
try {
GPXParser parser = new GPX10Parser(app, listId, search);
searchId = parser.parse(file, handler);
- if (searchId == 0l) {
+ if (searchId == 0L) {
parser = new GPX11Parser(app, listId, search);
searchId = parser.parse(file, handler);
}