diff options
Diffstat (limited to 'src/cgeo/geocaching/files')
| -rw-r--r-- | src/cgeo/geocaching/files/FileList.java | 456 | ||||
| -rw-r--r-- | src/cgeo/geocaching/files/FileParser.java | 84 | ||||
| -rw-r--r-- | src/cgeo/geocaching/files/GPX10Parser.java | 17 | ||||
| -rw-r--r-- | src/cgeo/geocaching/files/GPX11Parser.java | 17 | ||||
| -rw-r--r-- | src/cgeo/geocaching/files/GPXParser.java | 1484 | ||||
| -rw-r--r-- | src/cgeo/geocaching/files/LocParser.java | 331 |
6 files changed, 1196 insertions, 1193 deletions
diff --git a/src/cgeo/geocaching/files/FileList.java b/src/cgeo/geocaching/files/FileList.java index 08c8b11..fb0c698 100644 --- a/src/cgeo/geocaching/files/FileList.java +++ b/src/cgeo/geocaching/files/FileList.java @@ -1,8 +1,8 @@ package cgeo.geocaching.files; -import java.io.File; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.R; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.activity.AbstractListActivity; import org.apache.commons.lang3.ArrayUtils; @@ -14,231 +14,233 @@ import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.ArrayAdapter; -import cgeo.geocaching.R; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.activity.AbstractListActivity; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractListActivity { - private List<File> files = new ArrayList<File>(); - private T adapter = null; - private ProgressDialog waitDialog = null; - private loadFiles searchingThread = null; - private boolean endSearching = false; - private int listId = 1; - final private Handler changeWaitDialogHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (msg.obj != null && waitDialog != null) { - waitDialog.setMessage(res.getString(R.string.file_searching_in) + " " + (String) msg.obj); - } - } - }; - final private Handler loadFilesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (files == null || files.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - showToast(res.getString(R.string.file_list_no_files)); - - finish(); - return; - } else { - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgFileList.loadFilesHandler: " + e.toString()); - } - } - }; - private String[] extensions; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.gpx); - setTitle(); - - Bundle extras = getIntent().getExtras(); - if (extras != null) { - listId = extras.getInt("list"); - } - if (listId <= 0) { - listId = 1; - } - - setAdapter(); - - waitDialog = ProgressDialog.show( - this, - res.getString(R.string.file_title_searching), - res.getString(R.string.file_searching), - true, - true, - new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface arg0) { - if (searchingThread != null && searchingThread.isAlive()) { - searchingThread.notifyEnd(); - } - if (files.isEmpty()) { - finish(); - } - } - } - ); - - endSearching = false; - searchingThread = new loadFiles(); - searchingThread.start(); - } - - @Override - public void onResume() { - super.onResume(); - - getSettings().load(); - } - - protected abstract T getAdapter(List<File> files); - - private void setAdapter() { - if (adapter == null) { - adapter = getAdapter(files); - setListAdapter(adapter); - } - } - - /** - * Gets the base folder for file searches - * @return The folder to start the recursive search in - */ - protected abstract String[] getBaseFolders(); - - /** - * Triggers the deriving class to set the title - */ - protected abstract void setTitle(); - - private class loadFiles extends Thread { - public void notifyEnd() { - endSearching = true; - } - - @Override - public void run() { - List<File> list = new ArrayList<File>(); - - try { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - boolean loaded = false; - for(String baseFolder : getBaseFolders()) - { - final File dir = new File(baseFolder); - - if (dir.exists() && dir.isDirectory()) { - listDir(list, dir); - if (list.size() > 0) { - loaded = true; - break; - } - } - } - if (!loaded) { - listDir(list, Environment.getExternalStorageDirectory()); - } - } else { - Log.w(cgSettings.tag, "No external media mounted."); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgFileList.loadFiles.run: " + e.toString()); - } - - final Message msg = new Message(); - msg.obj = "loaded directories"; - changeWaitDialogHandler.sendMessage(msg); - - files.addAll(list); - list.clear(); - - loadFilesHandler.sendMessage(new Message()); - } - } - - private void listDir(List<File> result, File directory) { - if (directory == null || !directory.isDirectory() || !directory.canRead()) { - return; - } - - final File[] files = directory.listFiles(); - - if (ArrayUtils.isNotEmpty(files)) { - for (File file : files) { - if (endSearching) { - return; - } - if (!file.canRead()) { - continue; - } - String name = file.getName(); - if (file.isFile()) { - for (String ext : extensions) { - int extLength = ext.length(); - if (name.length() > extLength && name.substring(name.length() - extLength, name.length()).equalsIgnoreCase(ext)) { - result.add(file); // add file to list - break; - } - } - - } else if (file.isDirectory()) { - if (name.charAt(0) == '.') { - continue; // skip hidden directories - } - if (name.length() > 16) { - name = name.substring(0, 14) + "..."; - } - final Message msg = new Message(); - msg.obj = name; - changeWaitDialogHandler.sendMessage(msg); - - listDir(result, file); // go deeper - } - } - } - - return; - } - - protected FileList(final String extension) { - setExtensions(new String[] {extension}); - } - - protected FileList(final String[] extensions) { - setExtensions(extensions); - } - - private void setExtensions(String[] extensionsIn) { - for (String extension : extensionsIn) { - if (extension.length() == 0 || extension.charAt(0) != '.') { - extension = "." + extension; - } - } - extensions = extensionsIn; - } + private List<File> files = new ArrayList<File>(); + private T adapter = null; + private ProgressDialog waitDialog = null; + private loadFiles searchingThread = null; + private boolean endSearching = false; + private int listId = 1; + final private Handler changeWaitDialogHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (msg.obj != null && waitDialog != null) { + waitDialog.setMessage(res.getString(R.string.file_searching_in) + " " + (String) msg.obj); + } + } + }; + final private Handler loadFilesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (files == null || files.isEmpty()) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + showToast(res.getString(R.string.file_list_no_files)); + + finish(); + return; + } else { + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgFileList.loadFilesHandler: " + e.toString()); + } + } + }; + private String[] extensions; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.gpx); + setTitle(); + + Bundle extras = getIntent().getExtras(); + if (extras != null) { + listId = extras.getInt("list"); + } + if (listId <= 0) { + listId = 1; + } + + setAdapter(); + + waitDialog = ProgressDialog.show( + this, + res.getString(R.string.file_title_searching), + res.getString(R.string.file_searching), + true, + true, + new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface arg0) { + if (searchingThread != null && searchingThread.isAlive()) { + searchingThread.notifyEnd(); + } + if (files.isEmpty()) { + finish(); + } + } + } + ); + + endSearching = false; + searchingThread = new loadFiles(); + searchingThread.start(); + } + + @Override + public void onResume() { + super.onResume(); + + getSettings().load(); + } + + protected abstract T getAdapter(List<File> files); + + private void setAdapter() { + if (adapter == null) { + adapter = getAdapter(files); + setListAdapter(adapter); + } + } + + /** + * Gets the base folder for file searches + * + * @return The folder to start the recursive search in + */ + protected abstract String[] getBaseFolders(); + + /** + * Triggers the deriving class to set the title + */ + protected abstract void setTitle(); + + private class loadFiles extends Thread { + public void notifyEnd() { + endSearching = true; + } + + @Override + public void run() { + List<File> list = new ArrayList<File>(); + + try { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + boolean loaded = false; + for (String baseFolder : getBaseFolders()) + { + final File dir = new File(baseFolder); + + if (dir.exists() && dir.isDirectory()) { + listDir(list, dir); + if (list.size() > 0) { + loaded = true; + break; + } + } + } + if (!loaded) { + listDir(list, Environment.getExternalStorageDirectory()); + } + } else { + Log.w(cgSettings.tag, "No external media mounted."); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgFileList.loadFiles.run: " + e.toString()); + } + + final Message msg = new Message(); + msg.obj = "loaded directories"; + changeWaitDialogHandler.sendMessage(msg); + + files.addAll(list); + list.clear(); + + loadFilesHandler.sendMessage(new Message()); + } + } + + private void listDir(List<File> result, File directory) { + if (directory == null || !directory.isDirectory() || !directory.canRead()) { + return; + } + + final File[] files = directory.listFiles(); + + if (ArrayUtils.isNotEmpty(files)) { + for (File file : files) { + if (endSearching) { + return; + } + if (!file.canRead()) { + continue; + } + String name = file.getName(); + if (file.isFile()) { + for (String ext : extensions) { + int extLength = ext.length(); + if (name.length() > extLength && name.substring(name.length() - extLength, name.length()).equalsIgnoreCase(ext)) { + result.add(file); // add file to list + break; + } + } + + } else if (file.isDirectory()) { + if (name.charAt(0) == '.') { + continue; // skip hidden directories + } + if (name.length() > 16) { + name = name.substring(0, 14) + "..."; + } + final Message msg = new Message(); + msg.obj = name; + changeWaitDialogHandler.sendMessage(msg); + + listDir(result, file); // go deeper + } + } + } + + return; + } + + protected FileList(final String extension) { + setExtensions(new String[] { extension }); + } + + protected FileList(final String[] extensions) { + setExtensions(extensions); + } + + private void setExtensions(String[] extensionsIn) { + for (String extension : extensionsIn) { + if (extension.length() == 0 || extension.charAt(0) != '.') { + extension = "." + extension; + } + } + extensions = extensionsIn; + } } diff --git a/src/cgeo/geocaching/files/FileParser.java b/src/cgeo/geocaching/files/FileParser.java index 2939b59..c7f16c8 100644 --- a/src/cgeo/geocaching/files/FileParser.java +++ b/src/cgeo/geocaching/files/FileParser.java @@ -1,5 +1,12 @@ package cgeo.geocaching.files;
+import cgeo.geocaching.cgBase;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgSearch;
+
+import android.os.Handler;
+import android.os.Message;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -7,49 +14,40 @@ import java.io.FileReader; import java.io.IOException;
import java.util.Date;
-import android.os.Handler;
-import android.os.Message;
-import cgeo.geocaching.cgBase;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgSearch;
-
public abstract class FileParser {
- protected static StringBuilder readFile(File file)
- throws FileNotFoundException, IOException {
- StringBuilder buffer = new StringBuilder();
- BufferedReader input = new BufferedReader(new FileReader(file));
- try {
- String line = null;
- while (( line = input.readLine()) != null){
- buffer.append(line);
- }
- }
- finally {
- input.close();
- }
- return buffer;
- }
-
- static void showFinishedMessage(Handler handler, cgSearch search) {
- if (handler != null) {
- final Message msg = new Message();
- msg.obj = search.getCount();
- handler.sendMessage(msg);
- }
- }
-
- protected static void fixCache(cgCache cache) {
- cache.latitudeString = cgBase.formatLatitude(cache.coords.getLatitude(), true);
- cache.longitudeString = cgBase.formatLongitude(cache.coords.getLongitude(), true);
- if (cache.inventory != null) {
- cache.inventoryItems = cache.inventory.size();
- } else {
- cache.inventoryItems = 0;
- }
- cache.updated = new Date().getTime();
- cache.detailedUpdate = new Date().getTime();
- }
-
-
+ protected static StringBuilder readFile(File file)
+ throws FileNotFoundException, IOException {
+ StringBuilder buffer = new StringBuilder();
+ BufferedReader input = new BufferedReader(new FileReader(file));
+ try {
+ String line = null;
+ while ((line = input.readLine()) != null) {
+ buffer.append(line);
+ }
+ } finally {
+ input.close();
+ }
+ return buffer;
+ }
+
+ static void showFinishedMessage(Handler handler, cgSearch search) {
+ if (handler != null) {
+ final Message msg = new Message();
+ msg.obj = search.getCount();
+ handler.sendMessage(msg);
+ }
+ }
+
+ protected static void fixCache(cgCache cache) {
+ cache.latitudeString = cgBase.formatLatitude(cache.coords.getLatitude(), true);
+ cache.longitudeString = cgBase.formatLongitude(cache.coords.getLongitude(), true);
+ if (cache.inventory != null) {
+ cache.inventoryItems = cache.inventory.size();
+ } else {
+ cache.inventoryItems = 0;
+ }
+ cache.updated = new Date().getTime();
+ cache.detailedUpdate = new Date().getTime();
+ }
}
diff --git a/src/cgeo/geocaching/files/GPX10Parser.java b/src/cgeo/geocaching/files/GPX10Parser.java index 7bb3cb5..be3c857 100644 --- a/src/cgeo/geocaching/files/GPX10Parser.java +++ b/src/cgeo/geocaching/files/GPX10Parser.java @@ -2,18 +2,19 @@ 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(cgeoapplication appIn, int listIdIn,
+ cgSearch searchIn) {
+ super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/0", "1.0");
+ }
- @Override
- protected Element getCacheParent(Element waypoint) {
- return waypoint;
- }
+ @Override
+ protected Element getCacheParent(Element waypoint) {
+ return waypoint;
+ }
}
diff --git a/src/cgeo/geocaching/files/GPX11Parser.java b/src/cgeo/geocaching/files/GPX11Parser.java index d890e6d..9370450 100644 --- a/src/cgeo/geocaching/files/GPX11Parser.java +++ b/src/cgeo/geocaching/files/GPX11Parser.java @@ -2,18 +2,19 @@ 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(cgeoapplication appIn, int listIdIn,
+ cgSearch searchIn) {
+ super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/1", "1.1");
+ }
- @Override
- protected Element getCacheParent(Element waypoint) {
- return waypoint.getChild(namespace, "extensions");
- }
+ @Override
+ protected Element getCacheParent(Element waypoint) {
+ return waypoint.getChild(namespace, "extensions");
+ }
}
diff --git a/src/cgeo/geocaching/files/GPXParser.java b/src/cgeo/geocaching/files/GPXParser.java index a9978c5..1e1458a 100644 --- a/src/cgeo/geocaching/files/GPXParser.java +++ b/src/cgeo/geocaching/files/GPXParser.java @@ -1,17 +1,15 @@ package cgeo.geocaching.files; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import cgeo.geocaching.R; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgLog; +import cgeo.geocaching.cgSearch; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgTrackable; +import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; import org.xml.sax.Attributes; @@ -25,435 +23,437 @@ 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; -import cgeo.geocaching.cgSearch; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgTrackable; -import cgeo.geocaching.cgeoapplication; -import cgeo.geocaching.connector.ConnectorFactory; -import cgeo.geocaching.geopoint.Geopoint; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.UUID; +import java.util.regex.Matcher; +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'Z'"); // 2010-04-20T07:00:00Z - private static final SimpleDateFormat formatTimezone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000'Z"); // 2010-04-20T01:01:03.000-04:00 - - 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); - 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 - }; - - 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; - - private cgCache cache = new cgCache(); - private cgTrackable trackable = new cgTrackable(); - private cgLog log = new cgLog(); - - private String type = null; - private String sym = null; - 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 - - private final class UserDataListener implements EndTextElementListener { - private int index; - - public UserDataListener(int index) { - this.index = index; - } - - @Override - public void end(String user) { - userData[index] = validate(user); - } - } - - private static final class CacheAttributeTranslator { - // 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 static 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 SimpleDateFormat formatSimple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 2010-04-20T07:00:00Z + private static final SimpleDateFormat formatTimezone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000'Z"); // 2010-04-20T01:01:03.000-04:00 + + 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); + 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 + }; + + 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; + + private cgCache cache = new cgCache(); + private cgTrackable trackable = new cgTrackable(); + private cgLog log = new cgLog(); + + private String type = null; + private String sym = null; + 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 + + private final class UserDataListener implements EndTextElementListener { + private int index; + + public UserDataListener(int index) { + this.index = index; + } + + @Override + public void end(String user) { + userData[index] = validate(user); + } + } + + private static final class CacheAttributeTranslator { + // 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 static 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 static final Pattern BASENAME_PATTERN = Pattern.compile("^.*attribute_(.*)(_yes|_no)"); - // map GPX-Attribute-Id to baseName - public static String getBaseName(final int id) { - // get String out of array - if (CACHE_ATTRIBUTES.length <= id) { - return null; - } - final int stringId = CACHE_ATTRIBUTES[id]; - if (stringId == -1) { - return null; // id not found - } - // get text for string - String stringName = null; - try { - stringName = app.getResources().getResourceName(stringId); - } catch (NullPointerException e) { - return null; - } - if (stringName == null) { - return null; - } - // cut out baseName - final Matcher m = BASENAME_PATTERN.matcher(stringName); - if (! m.matches()) { - return null; - } - return m.group(1); - } - - // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes" - public static String getInternalId(final int attributeId, final boolean active) { - final String baseName = CacheAttributeTranslator.getBaseName(attributeId); - if (baseName == 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; - namespace = namespaceIn; - version = versionIn; - } - - private static Date parseDate(String inputUntrimmed) throws ParseException { - final String input = inputUntrimmed.trim(); - if (input.length() >= 3 && input.charAt(input.length() - 3) == ':') { - final String removeColon = input.substring(0, input.length() - 3) + input.substring(input.length() - 2); - return formatTimezone.parse(removeColon); - } - return formatSimple.parse(input); - } - - public UUID parse(final InputStream stream, Handler handlerIn) { - handler = handlerIn; - - final RootElement root = new RootElement(namespace, "gpx"); - final Element waypoint = root.getChild(namespace, "wpt"); - - // waypoint - attributes - waypoint.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - try { - if (attrs.getIndex("lat") > -1 && attrs.getIndex("lon") > -1) { - cache.coords = new Geopoint(new Double(attrs.getValue("lat")), - new Double(attrs.getValue("lon"))); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse waypoint's latitude and/or longitude."); - } - } - }); - - // waypoint - waypoint.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isBlank(cache.geocode)) { - // try to find geocode somewhere else - findGeoCode(name); - findGeoCode(desc); - findGeoCode(cmt); - } - - if (StringUtils.isNotBlank(cache.geocode) - && cache.coords != null - && ((type == null && sym == null) - || (type != null && type.indexOf("geocache") > -1) - || (sym != null && sym.indexOf("geocache") > -1))) { - fixCache(cache); - 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; - } - } - - app.addCacheToSearch(search, cache); - } - - showFinishedMessage(handler, search); - - resetCache(); - } - }); - - // waypoint.time - waypoint.getChild(namespace, "time").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.hidden = parseDate(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse cache date: " + e.toString()); - } - } - }); - - // waypoint.name - waypoint.getChild(namespace, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - name = body; - - final String content = body.trim(); - cache.name = content; - - findGeoCode(cache.name); - findGeoCode(cache.description); - } - }); - - // waypoint.desc - waypoint.getChild(namespace, "desc").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - desc = body; - - cache.shortdesc = validate(body); - } - }); - - // waypoint.cmt - waypoint.getChild(namespace, "cmt").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - cmt = body; - - cache.description = validate(body); - } - }); - - // waypoint.type - waypoint.getChild(namespace, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - final String[] content = body.split("\\|"); - if (content.length > 0) { - type = content[0].toLowerCase().trim(); - } - } - }); - - // waypoint.sym - waypoint.getChild(namespace, "sym").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - body = body.toLowerCase(); - sym = body; - if (body.indexOf("geocache") != -1 && body.indexOf("found") != -1) { - cache.found = true; - } - } - }); - - // waypoint.url - waypoint.getChild(namespace, "url").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String url) { - final Matcher matcher = patternGuid.matcher(url); - if (matcher.matches()) { - String guid = matcher.group(1); - if (StringUtils.isNotBlank(guid)) { - cache.guid = guid; - } - } - } - }); - - // for GPX 1.0, cache info comes from waypoint node (so called private children, - // for GPX 1.1 from extensions node - final Element cacheParent = getCacheParent(waypoint); - - - // GSAK extensions - final Element gsak = cacheParent.getChild(GSAK_NS, "wptExtension"); - gsak.getChild(GSAK_NS, "Watch").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String watchList) { - cache.onWatchlist = Boolean.valueOf(watchList.trim()); - } - }); - - gsak.getChild(GSAK_NS, "UserData").setEndTextElementListener(new UserDataListener(1)); - - for (int i = 2; i <= 4; i++) { - gsak.getChild(GSAK_NS, "User" + i).setEndTextElementListener(new UserDataListener(i)); - } - - // 3 different versions of the GC schema - for (String nsGC : nsGCList) { - // waypoints.cache - final Element gcCache = cacheParent.getChild(nsGC, "cache"); - - gcCache.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - try { - if (attrs.getIndex("id") > -1) { - cache.cacheId = attrs.getValue("id"); - } - if (attrs.getIndex("archived") > -1) { - cache.archived = attrs.getValue("archived").equalsIgnoreCase("true"); - } - if (attrs.getIndex("available") > -1) { - cache.disabled = !attrs.getValue("available").equalsIgnoreCase("true"); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse cache attributes."); - } - } - }); - - // waypoint.cache.name - gcCache.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String cacheName) { - cache.name = validate(cacheName); - } - }); - - // waypoint.cache.owner - gcCache.getChild(nsGC, "owner").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String cacheOwner) { - cache.owner = validate(cacheOwner); - } - }); - - // waypoint.cache.type - gcCache.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - setType(validate(body.toLowerCase())); - } - }); - - // waypoint.cache.container - gcCache.getChild(nsGC, "container").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - cache.size = validate(body.toLowerCase()); - } - }); - - // waypoint.cache.attributes - // @see issue #299 + // map GPX-Attribute-Id to baseName + public static String getBaseName(final int id) { + // get String out of array + if (CACHE_ATTRIBUTES.length <= id) { + return null; + } + final int stringId = CACHE_ATTRIBUTES[id]; + if (stringId == -1) { + return null; // id not found + } + // get text for string + String stringName = null; + try { + stringName = app.getResources().getResourceName(stringId); + } catch (NullPointerException e) { + return null; + } + if (stringName == null) { + return null; + } + // cut out baseName + final Matcher m = BASENAME_PATTERN.matcher(stringName); + if (!m.matches()) { + return null; + } + return m.group(1); + } + + // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes" + public static String getInternalId(final int attributeId, final boolean active) { + final String baseName = CacheAttributeTranslator.getBaseName(attributeId); + if (baseName == 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; + namespace = namespaceIn; + version = versionIn; + } + + private static Date parseDate(String inputUntrimmed) throws ParseException { + final String input = inputUntrimmed.trim(); + if (input.length() >= 3 && input.charAt(input.length() - 3) == ':') { + final String removeColon = input.substring(0, input.length() - 3) + input.substring(input.length() - 2); + return formatTimezone.parse(removeColon); + } + return formatSimple.parse(input); + } + + public UUID parse(final InputStream stream, Handler handlerIn) { + handler = handlerIn; + + final RootElement root = new RootElement(namespace, "gpx"); + final Element waypoint = root.getChild(namespace, "wpt"); + + // waypoint - attributes + waypoint.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + try { + if (attrs.getIndex("lat") > -1 && attrs.getIndex("lon") > -1) { + cache.coords = new Geopoint(new Double(attrs.getValue("lat")), + new Double(attrs.getValue("lon"))); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse waypoint's latitude and/or longitude."); + } + } + }); + + // waypoint + waypoint.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isBlank(cache.geocode)) { + // try to find geocode somewhere else + findGeoCode(name); + findGeoCode(desc); + findGeoCode(cmt); + } + + if (StringUtils.isNotBlank(cache.geocode) + && cache.coords != null + && ((type == null && sym == null) + || (type != null && type.indexOf("geocache") > -1) + || (sym != null && sym.indexOf("geocache") > -1))) { + fixCache(cache); + 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; + } + } + + app.addCacheToSearch(search, cache); + } + + showFinishedMessage(handler, search); + + resetCache(); + } + }); + + // waypoint.time + waypoint.getChild(namespace, "time").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.hidden = parseDate(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse cache date: " + e.toString()); + } + } + }); + + // waypoint.name + waypoint.getChild(namespace, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + name = body; + + final String content = body.trim(); + cache.name = content; + + findGeoCode(cache.name); + findGeoCode(cache.description); + } + }); + + // waypoint.desc + waypoint.getChild(namespace, "desc").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + desc = body; + + cache.shortdesc = validate(body); + } + }); + + // waypoint.cmt + waypoint.getChild(namespace, "cmt").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + cmt = body; + + cache.description = validate(body); + } + }); + + // waypoint.type + waypoint.getChild(namespace, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + final String[] content = body.split("\\|"); + if (content.length > 0) { + type = content[0].toLowerCase().trim(); + } + } + }); + + // waypoint.sym + waypoint.getChild(namespace, "sym").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + body = body.toLowerCase(); + sym = body; + if (body.indexOf("geocache") != -1 && body.indexOf("found") != -1) { + cache.found = true; + } + } + }); + + // waypoint.url + waypoint.getChild(namespace, "url").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String url) { + final Matcher matcher = patternGuid.matcher(url); + if (matcher.matches()) { + String guid = matcher.group(1); + if (StringUtils.isNotBlank(guid)) { + cache.guid = guid; + } + } + } + }); + + // for GPX 1.0, cache info comes from waypoint node (so called private children, + // for GPX 1.1 from extensions node + final Element cacheParent = getCacheParent(waypoint); + + // GSAK extensions + final Element gsak = cacheParent.getChild(GSAK_NS, "wptExtension"); + gsak.getChild(GSAK_NS, "Watch").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String watchList) { + cache.onWatchlist = Boolean.valueOf(watchList.trim()); + } + }); + + gsak.getChild(GSAK_NS, "UserData").setEndTextElementListener(new UserDataListener(1)); + + for (int i = 2; i <= 4; i++) { + gsak.getChild(GSAK_NS, "User" + i).setEndTextElementListener(new UserDataListener(i)); + } + + // 3 different versions of the GC schema + for (String nsGC : nsGCList) { + // waypoints.cache + final Element gcCache = cacheParent.getChild(nsGC, "cache"); + + gcCache.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + try { + if (attrs.getIndex("id") > -1) { + cache.cacheId = attrs.getValue("id"); + } + if (attrs.getIndex("archived") > -1) { + cache.archived = attrs.getValue("archived").equalsIgnoreCase("true"); + } + if (attrs.getIndex("available") > -1) { + cache.disabled = !attrs.getValue("available").equalsIgnoreCase("true"); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse cache attributes."); + } + } + }); + + // waypoint.cache.name + gcCache.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String cacheName) { + cache.name = validate(cacheName); + } + }); + + // waypoint.cache.owner + gcCache.getChild(nsGC, "owner").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String cacheOwner) { + cache.owner = validate(cacheOwner); + } + }); + + // waypoint.cache.type + gcCache.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + setType(validate(body.toLowerCase())); + } + }); + + // waypoint.cache.container + gcCache.getChild(nsGC, "container").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + cache.size = validate(body.toLowerCase()); + } + }); + + // waypoint.cache.attributes + // @see issue #299 // <groundspeak:attributes> // <groundspeak:attribute id="32" inc="1">Bicycles</groundspeak:attribute> @@ -474,10 +474,10 @@ public abstract class GPXParser extends FileParser { boolean attributeActive = Integer.parseInt(attrs.getValue("inc")) != 0; String internalId = CacheAttributeTranslator.getInternalId(attributeId, attributeActive); if (internalId != null) { - if (cache.attributes == null) { - cache.attributes = new ArrayList<String>(); - } - cache.attributes.add(internalId); + if (cache.attributes == null) { + cache.attributes = new ArrayList<String>(); + } + cache.attributes.add(internalId); } } } catch (NumberFormatException e) { @@ -487,308 +487,308 @@ public abstract class GPXParser extends FileParser { }); // waypoint.cache.difficulty - gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.difficulty = new Float(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse difficulty: " + e.toString()); - } - } - }); - - // waypoint.cache.terrain - gcCache.getChild(nsGC, "terrain").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.terrain = new Float(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse terrain: " + e.toString()); - } - } - }); - - // waypoint.cache.country - gcCache.getChild(nsGC, "country").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String country) { - if (StringUtils.isBlank(cache.location)) { - cache.location = validate(country); - } else { - cache.location = cache.location + ", " + country.trim(); - } - } - }); - - // waypoint.cache.state - gcCache.getChild(nsGC, "state").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String state) { - if (StringUtils.isBlank(cache.location)) { - cache.location = validate(state); - } else { - cache.location = state.trim() + ", " + cache.location; - } - } - }); - - // waypoint.cache.encoded_hints - gcCache.getChild(nsGC, "encoded_hints").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String encoded) { - cache.hint = validate(encoded); - } - }); - - gcCache.getChild(nsGC, "short_description").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String shortDesc) { - cache.shortdesc = validate(shortDesc); - } - }); - - gcCache.getChild(nsGC, "long_description").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String desc) { - cache.description = validate(desc); - } - }); - - // waypoint.cache.travelbugs - final Element gcTBs = gcCache.getChild(nsGC, "travelbugs"); - - // waypoint.cache.travelbugs.travelbug - gcTBs.getChild(nsGC, "travelbug").setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - trackable = new cgTrackable(); - - try { - if (attrs.getIndex("ref") > -1) { - trackable.geocode = attrs.getValue("ref").toUpperCase(); - } - } catch (Exception e) { - // nothing - } - } - }); - - // waypoint.cache.travelbug - final Element gcTB = gcTBs.getChild(nsGC, "travelbug"); - - gcTB.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isNotBlank(trackable.geocode) && StringUtils.isNotBlank(trackable.name)) { - if (cache.inventory == null) { - cache.inventory = new ArrayList<cgTrackable>(); - } - cache.inventory.add(trackable); - } - } - }); - - // waypoint.cache.travelbugs.travelbug.name - gcTB.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String tbName) { - trackable.name = validate(tbName); - } - }); - - // waypoint.cache.logs - final Element gcLogs = gcCache.getChild(nsGC, "logs"); - - // waypoint.cache.log - final Element gcLog = gcLogs.getChild(nsGC, "log"); - - gcLog.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - log = new cgLog(); - - try { - if (attrs.getIndex("id") > -1) { - log.id = Integer.parseInt(attrs.getValue("id")); - } - } catch (Exception e) { - // nothing - } - } - }); - - gcLog.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isNotBlank(log.log)) { - if (cache.logs == null) { - cache.logs = new ArrayList<cgLog>(); - } - cache.logs.add(log); - } - } - }); - - // waypoint.cache.logs.log.date - gcLog.getChild(nsGC, "date").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - log.date = parseDate(body).getTime(); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse log date: " + e.toString()); - } - } - }); - - // waypoint.cache.logs.log.type - gcLog.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - final String logType = validate(body).toLowerCase(); - if (cgBase.logTypes0.containsKey(logType)) { - log.type = cgBase.logTypes0.get(logType); - } else { - log.type = cgBase.LOG_NOTE; - } - } - }); - - // waypoint.cache.logs.log.finder - gcLog.getChild(nsGC, "finder").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String finderName) { - log.author = validate(finderName); - } - }); - - // waypoint.cache.logs.log.text - gcLog.getChild(nsGC, "text").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String logText) { - log.log = validate(logText); - } - }); - } - boolean parsed = false; - try { - Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler()); - parsed = true; - } catch (IOException e) { - Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not read file!"); - } 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; - } - - private UUID parse(final File file, final Handler handlerIn) { - if (file == null) { - return null; - } - - FileInputStream fis = null; - UUID result = null; - try { - fis = new FileInputStream(file); - result = parse(fis, handlerIn); - } catch (FileNotFoundException e) { - Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!"); - } - try { - if (fis != null) { - fis.close(); - } - } catch (IOException e) { - Log.e(cgSettings.tag, "Error after parsing .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not close file!"); - } - return result; - } - - protected abstract Element getCacheParent(Element waypoint); - - protected static String validate(String input) { - if ("nil".equalsIgnoreCase(input)) { - return ""; - } - return input.trim(); - } - - private void setType(String parsedString) { - final String knownType = cgBase.cacheTypes.get(parsedString); - if (knownType != null) { - cache.type = knownType; - } - else { - if (StringUtils.isBlank(cache.type)) { - cache.type = "mystery"; // default for not recognized types - } - } - } - - private void findGeoCode(final String input) { - if (input == null || StringUtils.isNotBlank(cache.geocode)) { - return; - } - 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; - } - } - } - } - - private void resetCache() { - type = null; - sym = null; - name = null; - desc = null; - cmt = null; - - cache = new cgCache(); - for (int i = 0; i < userData.length; i++) { - userData[i] = null; - } - } - - public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) { - final cgSearch search = new cgSearch(); - UUID searchId = null; - - 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); - } - } 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(); - } + gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.difficulty = new Float(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse difficulty: " + e.toString()); + } + } + }); + + // waypoint.cache.terrain + gcCache.getChild(nsGC, "terrain").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.terrain = new Float(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse terrain: " + e.toString()); + } + } + }); + + // waypoint.cache.country + gcCache.getChild(nsGC, "country").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String country) { + if (StringUtils.isBlank(cache.location)) { + cache.location = validate(country); + } else { + cache.location = cache.location + ", " + country.trim(); + } + } + }); + + // waypoint.cache.state + gcCache.getChild(nsGC, "state").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String state) { + if (StringUtils.isBlank(cache.location)) { + cache.location = validate(state); + } else { + cache.location = state.trim() + ", " + cache.location; + } + } + }); + + // waypoint.cache.encoded_hints + gcCache.getChild(nsGC, "encoded_hints").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String encoded) { + cache.hint = validate(encoded); + } + }); + + gcCache.getChild(nsGC, "short_description").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String shortDesc) { + cache.shortdesc = validate(shortDesc); + } + }); + + gcCache.getChild(nsGC, "long_description").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String desc) { + cache.description = validate(desc); + } + }); + + // waypoint.cache.travelbugs + final Element gcTBs = gcCache.getChild(nsGC, "travelbugs"); + + // waypoint.cache.travelbugs.travelbug + gcTBs.getChild(nsGC, "travelbug").setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + trackable = new cgTrackable(); + + try { + if (attrs.getIndex("ref") > -1) { + trackable.geocode = attrs.getValue("ref").toUpperCase(); + } + } catch (Exception e) { + // nothing + } + } + }); + + // waypoint.cache.travelbug + final Element gcTB = gcTBs.getChild(nsGC, "travelbug"); + + gcTB.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isNotBlank(trackable.geocode) && StringUtils.isNotBlank(trackable.name)) { + if (cache.inventory == null) { + cache.inventory = new ArrayList<cgTrackable>(); + } + cache.inventory.add(trackable); + } + } + }); + + // waypoint.cache.travelbugs.travelbug.name + gcTB.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String tbName) { + trackable.name = validate(tbName); + } + }); + + // waypoint.cache.logs + final Element gcLogs = gcCache.getChild(nsGC, "logs"); + + // waypoint.cache.log + final Element gcLog = gcLogs.getChild(nsGC, "log"); + + gcLog.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + log = new cgLog(); + + try { + if (attrs.getIndex("id") > -1) { + log.id = Integer.parseInt(attrs.getValue("id")); + } + } catch (Exception e) { + // nothing + } + } + }); + + gcLog.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isNotBlank(log.log)) { + if (cache.logs == null) { + cache.logs = new ArrayList<cgLog>(); + } + cache.logs.add(log); + } + } + }); + + // waypoint.cache.logs.log.date + gcLog.getChild(nsGC, "date").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + log.date = parseDate(body).getTime(); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse log date: " + e.toString()); + } + } + }); + + // waypoint.cache.logs.log.type + gcLog.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + final String logType = validate(body).toLowerCase(); + if (cgBase.logTypes0.containsKey(logType)) { + log.type = cgBase.logTypes0.get(logType); + } else { + log.type = cgBase.LOG_NOTE; + } + } + }); + + // waypoint.cache.logs.log.finder + gcLog.getChild(nsGC, "finder").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String finderName) { + log.author = validate(finderName); + } + }); + + // waypoint.cache.logs.log.text + gcLog.getChild(nsGC, "text").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String logText) { + log.log = validate(logText); + } + }); + } + boolean parsed = false; + try { + Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler()); + parsed = true; + } catch (IOException e) { + Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not read file!"); + } 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; + } + + private UUID parse(final File file, final Handler handlerIn) { + if (file == null) { + return null; + } + + FileInputStream fis = null; + UUID result = null; + try { + fis = new FileInputStream(file); + result = parse(fis, handlerIn); + } catch (FileNotFoundException e) { + Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!"); + } + try { + if (fis != null) { + fis.close(); + } + } catch (IOException e) { + Log.e(cgSettings.tag, "Error after parsing .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not close file!"); + } + return result; + } + + protected abstract Element getCacheParent(Element waypoint); + + protected static String validate(String input) { + if ("nil".equalsIgnoreCase(input)) { + return ""; + } + return input.trim(); + } + + private void setType(String parsedString) { + final String knownType = cgBase.cacheTypes.get(parsedString); + if (knownType != null) { + cache.type = knownType; + } + else { + if (StringUtils.isBlank(cache.type)) { + cache.type = "mystery"; // default for not recognized types + } + } + } + + private void findGeoCode(final String input) { + if (input == null || StringUtils.isNotBlank(cache.geocode)) { + return; + } + 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; + } + } + } + } + + private void resetCache() { + type = null; + sym = null; + name = null; + desc = null; + cmt = null; + + cache = new cgCache(); + for (int i = 0; i < userData.length; i++) { + userData[i] = null; + } + } + + public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) { + final cgSearch search = new cgSearch(); + UUID searchId = null; + + 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); + } + } 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(); + } } diff --git a/src/cgeo/geocaching/files/LocParser.java b/src/cgeo/geocaching/files/LocParser.java index 076005d..f631e10 100644 --- a/src/cgeo/geocaching/files/LocParser.java +++ b/src/cgeo/geocaching/files/LocParser.java @@ -1,17 +1,5 @@ package cgeo.geocaching.files;
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-
-import android.os.Handler;
-import android.util.Log;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgCacheWrap;
@@ -21,158 +9,171 @@ import cgeo.geocaching.cgSettings; import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
+import org.apache.commons.lang3.StringUtils;
+
+import android.os.Handler;
+import android.util.Log;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public final class LocParser extends FileParser {
- private static final Pattern patternGeocode = Pattern
- .compile("name id=\"([^\"]+)\"");
- private static final Pattern patternLat = Pattern
- .compile("lat=\"([^\"]+)\"");
- private static final Pattern patternLon = Pattern
- .compile("lon=\"([^\"]+)\"");
- // premium only >>
- private static final Pattern patternDifficulty = Pattern
- .compile("<difficulty>([^<]+)</difficulty>");
- private static final Pattern patternTerrain = Pattern
- .compile("<terrain>([^<]+)</terrain>");
- private static final Pattern patternContainer = Pattern
- .compile("<container>([^<]+)</container>");
- private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
-
- public static void parseLoc(final cgCacheWrap caches,
- final String fileContent) {
- final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
-
- // save found cache coordinates
- for (cgCache cache : caches.cacheList) {
- if (cidCoords.containsKey(cache.geocode)) {
- cgCoord coord = cidCoords.get(cache.geocode);
-
- copyCoordToCache(coord, cache);
- }
- }
- }
-
- private static void copyCoordToCache(final cgCoord coord, final cgCache cache) {
- cache.coords = coord.coords;
- cache.difficulty = coord.difficulty;
- cache.terrain = coord.terrain;
- cache.size = coord.size;
- cache.geocode = coord.geocode.toUpperCase();
- if (StringUtils.isBlank(cache.name)) {
- cache.name = coord.name;
- }
- }
-
- private static Map<String, cgCoord> parseCoordinates(
- final String fileContent) {
- final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
- if (StringUtils.isBlank(fileContent)) {
- return coords;
- }
- // >> premium only
-
- final String[] points = fileContent.split("<waypoint>");
-
- // parse coordinates
- for (String pointString : points) {
- final cgCoord pointCoord = new cgCoord();
-
- final Matcher matcherGeocode = patternGeocode.matcher(pointString);
- if (matcherGeocode.find()) {
- String geocode = matcherGeocode.group(1).trim().toUpperCase();
- pointCoord.name = geocode;
- pointCoord.geocode = geocode;
- }
- final Matcher matcherName = patternName.matcher(pointString);
- if (matcherName.find()) {
- String name = matcherName.group(1).trim();
- int pos = name.indexOf(" by ");
- if (pos > 0) {
- name = name.substring(0, pos).trim();
- }
- pointCoord.name = name;
- }
- final Matcher matcherLat = patternLat.matcher(pointString);
- final Matcher matcherLon = patternLon.matcher(pointString);
- if (matcherLat.find() && matcherLon.find()) {
- final Map<String, Object>tmpLat = cgBase.parseCoordinate(matcherLat.group(1).trim(), "lat");
- final Map<String, Object> tmpLon = cgBase.parseCoordinate(matcherLon.group(1).trim(), "lon");
- pointCoord.coords = new Geopoint((Double) tmpLat.get("coordinate"),
- (Double) tmpLon.get("coordinate"));
- }
- final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
- if (matcherDifficulty.find()) {
- pointCoord.difficulty = new Float(matcherDifficulty.group(1)
- .trim());
- }
- final Matcher matcherTerrain = patternTerrain.matcher(pointString);
- if (matcherTerrain.find()) {
- pointCoord.terrain = new Float(matcherTerrain.group(1).trim());
- }
- final Matcher matcherContainer = patternContainer.matcher(pointString);
- if (matcherContainer.find()) {
- final int size = Integer.parseInt(matcherContainer.group(1)
- .trim());
-
- if (size == 1) {
- pointCoord.size = "not chosen";
- } else if (size == 2) {
- pointCoord.size = "micro";
- } else if (size == 3) {
- pointCoord.size = "regular";
- } else if (size == 4) {
- pointCoord.size = "large";
- } else if (size == 5) {
- pointCoord.size = "virtual";
- } else if (size == 6) {
- pointCoord.size = "other";
- } else if (size == 8) {
- pointCoord.size = "small";
- } else {
- pointCoord.size = "unknown";
- }
- }
-
- if (StringUtils.isNotBlank(pointCoord.geocode)) {
- coords.put(pointCoord.geocode, pointCoord);
- }
- }
-
- Log.i(cgSettings.tag,
- "Coordinates found in .loc file: " + coords.size());
- return coords;
- }
-
- public static UUID parseLoc(cgeoapplication app, File file, int listId,
- Handler handler) {
- cgSearch search = new cgSearch();
- UUID searchId = null;
-
- try {
- 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.geocode) || StringUtils.isBlank(coord.name)) {
- continue;
- }
- cgCache cache = new cgCache();
- copyCoordToCache(coord, cache);
- caches.cacheList.add(cache);
-
- fixCache(cache);
- cache.reason = listId;
- cache.detailed = false;
-
- app.addCacheToSearch(search, cache);
- }
- caches.totalCnt = caches.cacheList.size();
- showFinishedMessage(handler, search);
- } 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();
- }
+ private static final Pattern patternGeocode = Pattern
+ .compile("name id=\"([^\"]+)\"");
+ private static final Pattern patternLat = Pattern
+ .compile("lat=\"([^\"]+)\"");
+ private static final Pattern patternLon = Pattern
+ .compile("lon=\"([^\"]+)\"");
+ // premium only >>
+ private static final Pattern patternDifficulty = Pattern
+ .compile("<difficulty>([^<]+)</difficulty>");
+ private static final Pattern patternTerrain = Pattern
+ .compile("<terrain>([^<]+)</terrain>");
+ private static final Pattern patternContainer = Pattern
+ .compile("<container>([^<]+)</container>");
+ private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
+
+ public static void parseLoc(final cgCacheWrap caches,
+ final String fileContent) {
+ final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
+
+ // save found cache coordinates
+ for (cgCache cache : caches.cacheList) {
+ if (cidCoords.containsKey(cache.geocode)) {
+ cgCoord coord = cidCoords.get(cache.geocode);
+
+ copyCoordToCache(coord, cache);
+ }
+ }
+ }
+
+ private static void copyCoordToCache(final cgCoord coord, final cgCache cache) {
+ cache.coords = coord.coords;
+ cache.difficulty = coord.difficulty;
+ cache.terrain = coord.terrain;
+ cache.size = coord.size;
+ cache.geocode = coord.geocode.toUpperCase();
+ if (StringUtils.isBlank(cache.name)) {
+ cache.name = coord.name;
+ }
+ }
+
+ private static Map<String, cgCoord> parseCoordinates(
+ final String fileContent) {
+ final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
+ if (StringUtils.isBlank(fileContent)) {
+ return coords;
+ }
+ // >> premium only
+
+ final String[] points = fileContent.split("<waypoint>");
+
+ // parse coordinates
+ for (String pointString : points) {
+ final cgCoord pointCoord = new cgCoord();
+
+ final Matcher matcherGeocode = patternGeocode.matcher(pointString);
+ if (matcherGeocode.find()) {
+ String geocode = matcherGeocode.group(1).trim().toUpperCase();
+ pointCoord.name = geocode;
+ pointCoord.geocode = geocode;
+ }
+ final Matcher matcherName = patternName.matcher(pointString);
+ if (matcherName.find()) {
+ String name = matcherName.group(1).trim();
+ int pos = name.indexOf(" by ");
+ if (pos > 0) {
+ name = name.substring(0, pos).trim();
+ }
+ pointCoord.name = name;
+ }
+ final Matcher matcherLat = patternLat.matcher(pointString);
+ final Matcher matcherLon = patternLon.matcher(pointString);
+ if (matcherLat.find() && matcherLon.find()) {
+ final Map<String, Object> tmpLat = cgBase.parseCoordinate(matcherLat.group(1).trim(), "lat");
+ final Map<String, Object> tmpLon = cgBase.parseCoordinate(matcherLon.group(1).trim(), "lon");
+ pointCoord.coords = new Geopoint((Double) tmpLat.get("coordinate"),
+ (Double) tmpLon.get("coordinate"));
+ }
+ final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
+ if (matcherDifficulty.find()) {
+ pointCoord.difficulty = new Float(matcherDifficulty.group(1)
+ .trim());
+ }
+ final Matcher matcherTerrain = patternTerrain.matcher(pointString);
+ if (matcherTerrain.find()) {
+ pointCoord.terrain = new Float(matcherTerrain.group(1).trim());
+ }
+ final Matcher matcherContainer = patternContainer.matcher(pointString);
+ if (matcherContainer.find()) {
+ final int size = Integer.parseInt(matcherContainer.group(1)
+ .trim());
+
+ if (size == 1) {
+ pointCoord.size = "not chosen";
+ } else if (size == 2) {
+ pointCoord.size = "micro";
+ } else if (size == 3) {
+ pointCoord.size = "regular";
+ } else if (size == 4) {
+ pointCoord.size = "large";
+ } else if (size == 5) {
+ pointCoord.size = "virtual";
+ } else if (size == 6) {
+ pointCoord.size = "other";
+ } else if (size == 8) {
+ pointCoord.size = "small";
+ } else {
+ pointCoord.size = "unknown";
+ }
+ }
+
+ if (StringUtils.isNotBlank(pointCoord.geocode)) {
+ coords.put(pointCoord.geocode, pointCoord);
+ }
+ }
+
+ Log.i(cgSettings.tag,
+ "Coordinates found in .loc file: " + coords.size());
+ return coords;
+ }
+
+ public static UUID parseLoc(cgeoapplication app, File file, int listId,
+ Handler handler) {
+ cgSearch search = new cgSearch();
+ UUID searchId = null;
+
+ try {
+ 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.geocode) || StringUtils.isBlank(coord.name)) {
+ continue;
+ }
+ cgCache cache = new cgCache();
+ copyCoordToCache(coord, cache);
+ caches.cacheList.add(cache);
+
+ fixCache(cache);
+ cache.reason = listId;
+ cache.detailed = false;
+
+ app.addCacheToSearch(search, cache);
+ }
+ caches.totalCnt = caches.cacheList.size();
+ showFinishedMessage(handler, search);
+ } 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();
+ }
}
|
